fix: various bugs + improve api readability

This commit is contained in:
swve 2023-11-29 21:59:35 +01:00
parent 7daf6df5a0
commit 2bf80030d7
21 changed files with 98 additions and 75 deletions

View file

@ -53,7 +53,6 @@ class ActivityCreate(ActivityBase):
class ActivityUpdate(ActivityBase):
activity_id: int
name: Optional[str]
activity_type: Optional[ActivityTypeEnum]
activity_sub_type: Optional[ActivitySubTypeEnum]

View file

@ -21,6 +21,7 @@ class Chapter(ChapterBase, table=True):
update_date: str = ""
class ChapterCreate(ChapterBase):
# referenced order here will be ignored and just used for validation
# used order will be the next available.
@ -28,7 +29,6 @@ class ChapterCreate(ChapterBase):
class ChapterUpdate(ChapterBase):
chapter_id: int
name: Optional[str]
description: Optional[str]
thumbnail_image: Optional[str]

View file

@ -22,13 +22,13 @@ class Course(CourseBase, table=True):
update_date: str = ""
class CourseCreate(CourseBase):
org_id: int = Field(default=None, foreign_key="organization.id")
pass
class CourseUpdate(CourseBase):
course_id: int
name: str
description: Optional[str]
about: Optional[str]

View file

@ -17,7 +17,7 @@ class Organization(OrganizationBase, table=True):
update_date: str = ""
class OrganizationUpdate(OrganizationBase):
org_id: int
pass
class OrganizationCreate(OrganizationBase):
pass

View file

@ -4,7 +4,6 @@ from sqlmodel import Field, SQLModel
from src.db.trail_runs import TrailRunRead
class TrailBase(SQLModel):
org_id: int = Field(default=None, foreign_key="organization.id")
user_id: int = Field(default=None, foreign_key="user.id")
@ -30,3 +29,6 @@ class TrailRead(BaseModel):
creation_date: str
update_date: str
runs: list[TrailRunRead]
class Config:
orm_mode = True

View file

@ -25,7 +25,6 @@ class UserUpdate(UserBase):
class UserUpdatePassword(SQLModel):
user_id: int
old_password: str
new_password: str

View file

@ -49,30 +49,33 @@ async def api_get_activity(
)
@router.get("/coursechapter/{coursechapter_id}")
async def api_get_activities(
@router.get("/chapter/{chapter_id}")
async def api_get_chapter_activities(
request: Request,
coursechapter_id: str,
chapter_id: int,
current_user: PublicUser = Depends(get_current_user),
db_session=Depends(get_db_session),
) -> List[ActivityRead]:
"""
Get CourseChapter activities
Get Activities for a chapter
"""
return await get_activities(request, coursechapter_id, current_user, db_session)
return await get_activities(request, chapter_id, current_user, db_session)
@router.put("/")
@router.put("/{activity_id}")
async def api_update_activity(
request: Request,
activity_object: ActivityUpdate,
activity_id: int,
current_user: PublicUser = Depends(get_current_user),
db_session=Depends(get_db_session),
) -> ActivityRead:
"""
Update activity by activity_id
"""
return await update_activity(request, activity_object, current_user, db_session)
return await update_activity(
request, activity_object, activity_id, current_user, db_session
)
@router.delete("/{activity_id}")

View file

@ -50,7 +50,7 @@ async def api_get_coursechapter(
return await get_chapter(request, chapter_id, current_user, db_session)
@router.get("/meta/{course_id}")
@router.get("/course/{course_id}/meta")
async def api_get_chapter_meta(
request: Request,
course_id: int,
@ -65,7 +65,7 @@ async def api_get_chapter_meta(
)
@router.put("/order/{course_id}")
@router.put("/course/{course_id}/order")
async def api_update_chapter_meta(
request: Request,
course_id: int,
@ -81,7 +81,7 @@ async def api_update_chapter_meta(
)
@router.get("/{course_id}/page/{page}/limit/{limit}")
@router.get("/course/{course_id}/page/{page}/limit/{limit}")
async def api_get_chapter_by(
request: Request,
course_id: int,
@ -98,24 +98,26 @@ async def api_get_chapter_by(
)
@router.put("/{coursechapter_id}")
@router.put("/{chapter_id}")
async def api_update_coursechapter(
request: Request,
coursechapter_object: ChapterUpdate,
coursechapter_id: str,
chapter_id: int,
current_user: PublicUser = Depends(get_current_user),
db_session=Depends(get_db_session),
) -> ChapterRead:
"""
Update CourseChapters by course_id
"""
return await update_chapter(request, coursechapter_object, current_user, db_session)
return await update_chapter(
request, coursechapter_object, chapter_id, current_user, db_session
)
@router.delete("/{coursechapter_id}")
@router.delete("/{chapter_id}")
async def api_delete_coursechapter(
request: Request,
coursechapter_id: str,
chapter_id: int,
current_user: PublicUser = Depends(get_current_user),
db_session=Depends(get_db_session),
):
@ -123,4 +125,4 @@ async def api_delete_coursechapter(
Delete CourseChapters by ID
"""
return await delete_chapter(request, coursechapter_id, current_user, db_session)
return await delete_chapter(request, chapter_id, current_user, db_session)

View file

@ -42,7 +42,7 @@ async def api_get_collection(
return await get_collection(request, collection_id, current_user, db_session)
@router.get("/org_id/{org_id}/page/{page}/limit/{limit}")
@router.get("/org/{org_id}/page/{page}/limit/{limit}")
async def api_get_collections_by(
request: Request,
page: int,

View file

@ -3,7 +3,12 @@ from fastapi import APIRouter, Depends, UploadFile, Form, Request
from sqlmodel import Session
from src.core.events.database import get_db_session
from src.db.users import PublicUser
from src.db.courses import CourseCreate, CourseRead, CourseUpdate, FullCourseReadWithTrail
from src.db.courses import (
CourseCreate,
CourseRead,
CourseUpdate,
FullCourseReadWithTrail,
)
from src.security.auth import get_current_user
from src.services.courses.courses import (
create_course,
@ -49,7 +54,7 @@ async def api_create_course(
return await create_course(request, course, current_user, db_session, thumbnail)
@router.put("/thumbnail/{course_id}")
@router.put("/{course_id}/thumbnail")
async def api_create_course_thumbnail(
request: Request,
course_id: str,
@ -80,7 +85,7 @@ async def api_get_course(
)
@router.get("/meta/{course_id}")
@router.get("/{course_id}/meta")
async def api_get_course_meta(
request: Request,
course_id: int,
@ -112,17 +117,20 @@ async def api_get_course_by_orgslug(
)
@router.put("/")
@router.put("/{course_id}")
async def api_update_course(
request: Request,
course_object: CourseUpdate,
course_id: int,
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
) -> CourseRead:
"""
Update Course by course_id
"""
return await update_course(request, course_object, current_user, db_session)
return await update_course(
request, course_object, course_id, current_user, db_session
)
@router.delete("/{course_id}")

View file

@ -92,24 +92,25 @@ async def api_user_orgs(
db_session: Session = Depends(get_db_session),
) -> List[Organization]:
"""
Get orgs by page and limit by user
Get orgs by page and limit by current user
"""
return await get_orgs_by_user(
request, db_session, str(current_user.id), page, limit
)
@router.put("/")
@router.put("/{org_id}")
async def api_update_org(
request: Request,
org_object: OrganizationUpdate,
org_id: int,
current_user: PublicUser = Depends(get_current_user),
db_session: Session = Depends(get_db_session),
) -> OrganizationRead:
"""
Update Org by ID
"""
return await update_org(request, org_object, current_user, db_session)
return await update_org(request, org_object,org_id, current_user, db_session)
@router.delete("/{org_id}")

View file

@ -41,7 +41,7 @@ async def api_get_user_trail(
return await get_user_trails(request, user=user, db_session=db_session)
@router.get("/org_slug/{org_id}/trail")
@router.get("/org/{org_id}/trail")
async def api_get_trail_by_org_id(
request: Request,
org_id: int,
@ -69,7 +69,7 @@ async def api_add_course_to_trail(
return await add_course_to_trail(request, user, course_id, db_session)
@router.post("/remove_course/{course_id}")
@router.delete("/remove_course/{course_id}")
async def api_remove_course_to_trail(
request: Request,
course_id: str,
@ -82,11 +82,10 @@ async def api_remove_course_to_trail(
return await remove_course_from_trail(request, user, course_id, db_session)
@router.post("/add_activity/course_id/{course_id}/activity_id/{activity_id}")
@router.post("/add_activity/{activity_id}")
async def api_add_activity_to_trail(
request: Request,
activity_id: int,
course_id: int,
user=Depends(get_current_user),
db_session=Depends(get_db_session),
) -> TrailRead:
@ -94,5 +93,5 @@ async def api_add_activity_to_trail(
Add Course to trail
"""
return await add_activity_to_trail(
request, user, course_id, activity_id, db_session
request, user, activity_id, db_session
)

View file

@ -33,7 +33,7 @@ async def api_get_current_user(current_user: User = Depends(get_current_user)):
return current_user.dict()
@router.post("/org_id/{org_id}", response_model=UserRead, tags=["users"])
@router.post("/{org_id}", response_model=UserRead, tags=["users"])
async def api_create_user_with_orgid(
*,
request: Request,
@ -62,7 +62,7 @@ async def api_create_user_without_org(
return await create_user_without_org(request, db_session, current_user, user_object)
@router.get("/user_id/{user_id}", response_model=UserRead, tags=["users"])
@router.get("/id/{user_id}", response_model=UserRead, tags=["users"])
async def api_get_user_by_id(
*,
request: Request,
@ -76,7 +76,7 @@ async def api_get_user_by_id(
return await read_user_by_id(request, db_session, current_user, user_id)
@router.get("/user_uuid/{user_uuid}", response_model=UserRead, tags=["users"])
@router.get("/uuid/{user_uuid}", response_model=UserRead, tags=["users"])
async def api_get_user_by_uuid(
*,
request: Request,
@ -90,32 +90,34 @@ async def api_get_user_by_uuid(
return await read_user_by_uuid(request, db_session, current_user, user_uuid)
@router.put("/", response_model=UserRead, tags=["users"])
@router.put("/{user_id}", response_model=UserRead, tags=["users"])
async def api_update_user(
*,
request: Request,
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
user_id: int,
user_object: UserUpdate,
) -> UserRead:
"""
Update User
"""
return await update_user(request, db_session, current_user, user_object)
return await update_user(request, db_session, user_id, current_user, user_object)
@router.put("/change_password/", response_model=UserRead, tags=["users"])
@router.put("/change_password/{user_id}", response_model=UserRead, tags=["users"])
async def api_update_user_password(
*,
request: Request,
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
user_id: int,
form: UserUpdatePassword,
) -> UserRead:
"""
Update User Password
"""
return await update_user_password(request, db_session, current_user, form)
return await update_user_password(request, db_session, current_user, user_id, form)
@router.delete("/user_id/{user_id}", tags=["users"])
@ -125,7 +127,7 @@ async def api_delete_user(
db_session: Session = Depends(get_db_session),
current_user: PublicUser = Depends(get_current_user),
user_id: int,
) :
):
"""
Delete User
"""

View file

@ -5,6 +5,7 @@ async def check_element_type(element_id):
"""
Check if the element is a course, a user, a house or a collection, by checking its prefix
"""
print("element_id", element_id)
if element_id.startswith("course_"):
return "courses"
elif element_id.startswith("user_"):
@ -13,12 +14,14 @@ async def check_element_type(element_id):
return "houses"
elif element_id.startswith("org_"):
return "organizations"
elif element_id.startswith("coursechapter_"):
elif element_id.startswith("chapter_"):
return "coursechapters"
elif element_id.startswith("collection_"):
return "collections"
elif element_id.startswith("activity_"):
return "activities"
elif element_id.startswith("role_"):
return "roles"
else:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,

View file

@ -104,10 +104,11 @@ async def get_activity(
async def update_activity(
request: Request,
activity_object: ActivityUpdate,
activity_id: int,
current_user: PublicUser | AnonymousUser,
db_session: Session,
):
statement = select(Activity).where(Activity.id == activity_object.activity_id)
statement = select(Activity).where(Activity.id == activity_id)
activity = db_session.exec(statement).first()
if not activity:
@ -121,8 +122,6 @@ async def update_activity(
request, activity.activity_uuid, current_user, "update", db_session
)
del activity_object.activity_id
# Update only the fields that were passed in
for var, value in vars(activity_object).items():
if value is not None:
@ -183,7 +182,7 @@ async def delete_activity(
async def get_activities(
request: Request,
coursechapter_id: str,
coursechapter_id: int,
current_user: PublicUser | AnonymousUser,
db_session: Session,
) -> list[ActivityRead]:

View file

@ -130,10 +130,11 @@ async def get_chapter(
async def update_chapter(
request: Request,
chapter_object: ChapterUpdate,
chapter_id: int,
current_user: PublicUser | AnonymousUser,
db_session: Session,
) -> ChapterRead:
statement = select(Chapter).where(Chapter.id == chapter_object.chapter_id)
statement = select(Chapter).where(Chapter.id == chapter_id)
chapter = db_session.exec(statement).first()
if not chapter:
@ -161,7 +162,7 @@ async def update_chapter(
async def delete_chapter(
request: Request,
chapter_id: str,
chapter_id: int,
current_user: PublicUser | AnonymousUser,
db_session: Session,
):
@ -190,7 +191,6 @@ async def delete_chapter(
return {"detail": "chapter deleted"}
async def get_course_chapters(
request: Request,
course_id: int,

View file

@ -65,6 +65,8 @@ async def get_course_meta(
detail="Course not found",
)
print('cd',course.course_uuid)
# RBAC check
await rbac_check(request, course.course_uuid, current_user, "read", db_session)
@ -189,10 +191,11 @@ async def update_course_thumbnail(
async def update_course(
request: Request,
course_object: CourseUpdate,
course_id: int,
current_user: PublicUser | AnonymousUser,
db_session: Session,
):
statement = select(Course).where(Course.id == course_object.course_id)
statement = select(Course).where(Course.id == course_id)
course = db_session.exec(statement).first()
if not course:
@ -204,8 +207,6 @@ async def update_course(
# RBAC check
await rbac_check(request, course.course_uuid, current_user, "update", db_session)
del course_object.course_id
# Update only the fields that were passed in
for var, value in vars(course_object).items():
if value is not None:

View file

@ -118,10 +118,11 @@ async def create_org(
async def update_org(
request: Request,
org_object: OrganizationUpdate,
org_id: int,
current_user: PublicUser | AnonymousUser,
db_session: Session,
):
statement = select(Organization).where(Organization.id == org_object.org_id)
statement = select(Organization).where(Organization.id == org_id)
result = db_session.exec(statement)
org = result.first()
@ -149,9 +150,6 @@ async def update_org(
detail="Organization slug already exists",
)
# Remove the org_id from the org_object
del org_object.org_id
# Update only the fields that were passed in
for var, value in vars(org_object).items():
if value is not None:
@ -203,7 +201,6 @@ async def update_org_logo(
db_session.commit()
db_session.refresh(org)
return {"detail": "Logo updated"}

View file

@ -2,6 +2,7 @@ from datetime import datetime
from uuid import uuid4
from fastapi import HTTPException, Request, status
from sqlmodel import Session, select
from src.db.activities import Activity
from src.db.courses import Course
from src.db.trail_runs import TrailRun, TrailRunRead
from src.db.trail_steps import TrailStep
@ -120,13 +121,20 @@ async def get_user_trail_with_orgid(
async def add_activity_to_trail(
request: Request,
user: PublicUser,
course_id: int,
activity_id: int,
db_session: Session,
) -> TrailRead:
# Look for the activity
statement = select(Activity).where(Activity.id == activity_id)
activity = db_session.exec(statement).first()
if not activity:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Activity not found"
)
# check if run already exists
statement = select(TrailRun).where(TrailRun.course_id == course_id)
statement = select(TrailRun).where(TrailRun.course_id == activity.course_id)
trailrun = db_session.exec(statement).first()
if trailrun:
@ -134,7 +142,7 @@ async def add_activity_to_trail(
status_code=status.HTTP_400_BAD_REQUEST, detail="TrailRun already exists"
)
statement = select(Course).where(Course.id == course_id)
statement = select(Course).where(Course.id == activity.course_id)
course = db_session.exec(statement).first()
if not course:
@ -160,7 +168,7 @@ async def add_activity_to_trail(
if not trailrun:
trailrun = TrailRun(
trail_id=trail.id if trail.id is not None else 0,
course_id=course.id if course.id is not None else 0 ,
course_id=course.id if course.id is not None else 0,
org_id=course.org_id,
user_id=user.id,
creation_date=str(datetime.now()),
@ -177,7 +185,7 @@ async def add_activity_to_trail(
if not trailstep:
trailstep = TrailStep(
trailrun_id=trailrun.id if trailrun.id is not None else 0 ,
trailrun_id=trailrun.id if trailrun.id is not None else 0,
activity_id=activity_id,
course_id=course.id if course.id is not None else 0,
org_id=course.org_id,
@ -225,7 +233,6 @@ async def add_course_to_trail(
course_id: str,
db_session: Session,
) -> TrailRead:
# check if run already exists
statement = select(TrailRun).where(TrailRun.course_id == course_id)
trailrun = db_session.exec(statement).first()

View file

@ -158,11 +158,12 @@ async def create_user_without_org(
async def update_user(
request: Request,
db_session: Session,
user_id: int,
current_user: PublicUser | AnonymousUser,
user_object: UserUpdate,
):
# Get user
statement = select(User).where(User.username == user_object.username)
statement = select(User).where(User.id == user_id)
user = db_session.exec(statement).first()
if not user:
@ -195,10 +196,11 @@ async def update_user_password(
request: Request,
db_session: Session,
current_user: PublicUser | AnonymousUser,
user_id: int,
form: UserUpdatePassword,
):
# Get user
statement = select(User).where(User.username == form.user_id)
statement = select(User).where(User.id == user_id)
user = db_session.exec(statement).first()
if not user:
@ -340,7 +342,6 @@ async def rbac_check(
request, current_user.id, "create", "user_x", db_session
)
else:
await authorization_verify_if_user_is_anon(current_user.id)