From 70825830c4898c17e12c13e2df0c6a417fbfee99 Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Sun, 9 Feb 2025 11:29:05 -0300 Subject: [PATCH] misc: Set prefix and tags to API routers Improve OpenAPI documentation by setting tags to each API router. Also, set a prefix to each router to group the endpoints by their functionality. --- backend/endpoints/auth.py | 4 +++- backend/endpoints/collections.py | 15 +++++++++------ backend/endpoints/configs.py | 23 +++++++++++------------ backend/endpoints/feeds.py | 4 +++- backend/endpoints/firmware.py | 17 ++++++++++------- backend/endpoints/heartbeat.py | 4 +++- backend/endpoints/platform.py | 17 ++++++++++------- backend/endpoints/raw.py | 9 ++++++--- backend/endpoints/rom.py | 21 ++++++++++++--------- backend/endpoints/saves.py | 15 +++++++++------ backend/endpoints/screenshots.py | 7 +++++-- backend/endpoints/search.py | 9 ++++++--- backend/endpoints/states.py | 15 +++++++++------ backend/endpoints/stats.py | 7 +++++-- backend/endpoints/tasks.py | 9 ++++++--- backend/endpoints/user.py | 17 ++++++++++------- 16 files changed, 117 insertions(+), 76 deletions(-) diff --git a/backend/endpoints/auth.py b/backend/endpoints/auth.py index 42306f35e..fca8b07de 100644 --- a/backend/endpoints/auth.py +++ b/backend/endpoints/auth.py @@ -23,7 +23,9 @@ from utils.router import APIRouter ACCESS_TOKEN_EXPIRE_MINUTES: Final = 30 REFRESH_TOKEN_EXPIRE_DAYS: Final = 7 -router = APIRouter() +router = APIRouter( + tags=["auth"], +) # Session authentication endpoints diff --git a/backend/endpoints/collections.py b/backend/endpoints/collections.py index 849361844..dbb616d10 100644 --- a/backend/endpoints/collections.py +++ b/backend/endpoints/collections.py @@ -23,10 +23,13 @@ from PIL import Image from sqlalchemy.inspection import inspect from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/collections", + tags=["collections"], +) -@protected_route(router.post, "/collections", [Scope.COLLECTIONS_WRITE]) +@protected_route(router.post, "/", [Scope.COLLECTIONS_WRITE]) async def add_collection( request: Request, artwork: UploadFile | None = None, @@ -95,7 +98,7 @@ async def add_collection( return CollectionSchema.model_validate(created_collection) -@protected_route(router.get, "/collections", [Scope.COLLECTIONS_READ]) +@protected_route(router.get, "/", [Scope.COLLECTIONS_READ]) def get_collections(request: Request) -> list[CollectionSchema]: """Get collections endpoint @@ -111,7 +114,7 @@ def get_collections(request: Request) -> list[CollectionSchema]: return CollectionSchema.for_user(request.user.id, [c for c in collections]) -@protected_route(router.get, "/collections/{id}", [Scope.COLLECTIONS_READ]) +@protected_route(router.get, "/{id}", [Scope.COLLECTIONS_READ]) def get_collection(request: Request, id: int) -> CollectionSchema: """Get collections endpoint @@ -131,7 +134,7 @@ def get_collection(request: Request, id: int) -> CollectionSchema: return CollectionSchema.model_validate(collection) -@protected_route(router.put, "/collections/{id}", [Scope.COLLECTIONS_WRITE]) +@protected_route(router.put, "/{id}", [Scope.COLLECTIONS_WRITE]) async def update_collection( request: Request, id: int, @@ -221,7 +224,7 @@ async def update_collection( return CollectionSchema.model_validate(updated_collection) -@protected_route(router.delete, "/collections/{id}", [Scope.COLLECTIONS_WRITE]) +@protected_route(router.delete, "/{id}", [Scope.COLLECTIONS_WRITE]) async def delete_collections(request: Request, id: int) -> MessageResponse: """Delete collections endpoint diff --git a/backend/endpoints/configs.py b/backend/endpoints/configs.py index b1821ea5c..0cbb4926a 100644 --- a/backend/endpoints/configs.py +++ b/backend/endpoints/configs.py @@ -11,10 +11,13 @@ from handler.auth.constants import Scope from logger.logger import log from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/config", + tags=["config"], +) -@router.get("/config") +@router.get("/") def get_config() -> ConfigResponse: """Get config endpoint @@ -41,7 +44,7 @@ def get_config() -> ConfigResponse: ) from exc -@protected_route(router.post, "/config/system/platforms", [Scope.PLATFORMS_WRITE]) +@protected_route(router.post, "/system/platforms", [Scope.PLATFORMS_WRITE]) async def add_platform_binding(request: Request) -> MessageResponse: """Add platform binding to the configuration""" @@ -60,9 +63,7 @@ async def add_platform_binding(request: Request) -> MessageResponse: return {"msg": f"{fs_slug} binded to: {slug} successfully!"} -@protected_route( - router.delete, "/config/system/platforms/{fs_slug}", [Scope.PLATFORMS_WRITE] -) +@protected_route(router.delete, "/system/platforms/{fs_slug}", [Scope.PLATFORMS_WRITE]) async def delete_platform_binding(request: Request, fs_slug: str) -> MessageResponse: """Delete platform binding from the configuration""" @@ -77,7 +78,7 @@ async def delete_platform_binding(request: Request, fs_slug: str) -> MessageResp return {"msg": f"{fs_slug} bind removed successfully!"} -@protected_route(router.post, "/config/system/versions", [Scope.PLATFORMS_WRITE]) +@protected_route(router.post, "/system/versions", [Scope.PLATFORMS_WRITE]) async def add_platform_version(request: Request) -> MessageResponse: """Add platform version to the configuration""" @@ -96,9 +97,7 @@ async def add_platform_version(request: Request) -> MessageResponse: return {"msg": f"Added {fs_slug} as version of: {slug} successfully!"} -@protected_route( - router.delete, "/config/system/versions/{fs_slug}", [Scope.PLATFORMS_WRITE] -) +@protected_route(router.delete, "/system/versions/{fs_slug}", [Scope.PLATFORMS_WRITE]) async def delete_platform_version(request: Request, fs_slug: str) -> MessageResponse: """Delete platform version from the configuration""" @@ -113,7 +112,7 @@ async def delete_platform_version(request: Request, fs_slug: str) -> MessageResp return {"msg": f"{fs_slug} version removed successfully!"} -@protected_route(router.post, "/config/exclude", [Scope.PLATFORMS_WRITE]) +@protected_route(router.post, "/exclude", [Scope.PLATFORMS_WRITE]) async def add_exclusion(request: Request) -> MessageResponse: """Add platform exclusion to the configuration""" @@ -135,7 +134,7 @@ async def add_exclusion(request: Request) -> MessageResponse: @protected_route( router.delete, - "/config/exclude/{exclusion_type}/{exclusion_value}", + "/exclude/{exclusion_type}/{exclusion_value}", [Scope.PLATFORMS_WRITE], ) async def delete_exclusion( diff --git a/backend/endpoints/feeds.py b/backend/endpoints/feeds.py index de7a8013e..19dd1e67a 100644 --- a/backend/endpoints/feeds.py +++ b/backend/endpoints/feeds.py @@ -22,7 +22,9 @@ from models.rom import Rom from starlette.datastructures import URLPath from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + tags=["feeds"], +) @protected_route( diff --git a/backend/endpoints/firmware.py b/backend/endpoints/firmware.py index eab413407..318f1fc37 100644 --- a/backend/endpoints/firmware.py +++ b/backend/endpoints/firmware.py @@ -11,10 +11,13 @@ from handler.scan_handler import scan_firmware from logger.logger import log from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/firmware", + tags=["firmware"], +) -@protected_route(router.post, "/firmware", [Scope.FIRMWARE_WRITE]) +@protected_route(router.post, "/", [Scope.FIRMWARE_WRITE]) def add_firmware( request: Request, platform_id: int, @@ -81,7 +84,7 @@ def add_firmware( } -@protected_route(router.get, "/firmware", [Scope.FIRMWARE_READ]) +@protected_route(router.get, "/", [Scope.FIRMWARE_READ]) def get_platform_firmware( request: Request, platform_id: int | None = None, @@ -102,7 +105,7 @@ def get_platform_firmware( @protected_route( router.get, - "/firmware/{id}", + "/{id}", [] if DISABLE_DOWNLOAD_ENDPOINT_AUTH else [Scope.FIRMWARE_READ], ) def get_firmware(request: Request, id: int) -> FirmwareSchema: @@ -126,7 +129,7 @@ def get_firmware(request: Request, id: int) -> FirmwareSchema: @protected_route( router.head, - "/firmware/{id}/content/{file_name}", + "/{id}/content/{file_name}", [] if DISABLE_DOWNLOAD_ENDPOINT_AUTH else [Scope.FIRMWARE_READ], ) def head_firmware_content(request: Request, id: int, file_name: str): @@ -160,7 +163,7 @@ def head_firmware_content(request: Request, id: int, file_name: str): @protected_route( router.get, - "/firmware/{id}/content/{file_name}", + "/{id}/content/{file_name}", [] if DISABLE_DOWNLOAD_ENDPOINT_AUTH else [Scope.FIRMWARE_READ], ) def get_firmware_content( @@ -190,7 +193,7 @@ def get_firmware_content( return FileResponse(path=firmware_path, filename=firmware.file_name) -@protected_route(router.post, "/firmware/delete", [Scope.FIRMWARE_WRITE]) +@protected_route(router.post, "/delete", [Scope.FIRMWARE_WRITE]) async def delete_firmware( request: Request, ) -> MessageResponse: diff --git a/backend/endpoints/heartbeat.py b/backend/endpoints/heartbeat.py index 44b7221e4..b22cb2796 100644 --- a/backend/endpoints/heartbeat.py +++ b/backend/endpoints/heartbeat.py @@ -21,7 +21,9 @@ from handler.metadata.sgdb_handler import STEAMGRIDDB_API_ENABLED from utils import get_version from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + tags=["system"], +) @router.get("/heartbeat") diff --git a/backend/endpoints/platform.py b/backend/endpoints/platform.py index 1ca0ff4d2..e58cbecb0 100644 --- a/backend/endpoints/platform.py +++ b/backend/endpoints/platform.py @@ -14,10 +14,13 @@ from handler.scan_handler import scan_platform from logger.logger import log from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/platforms", + tags=["platforms"], +) -@protected_route(router.post, "/platforms", [Scope.PLATFORMS_WRITE]) +@protected_route(router.post, "/", [Scope.PLATFORMS_WRITE]) async def add_platforms(request: Request) -> PlatformSchema: """Create platform endpoint @@ -40,7 +43,7 @@ async def add_platforms(request: Request) -> PlatformSchema: ) -@protected_route(router.get, "/platforms", [Scope.PLATFORMS_READ]) +@protected_route(router.get, "/", [Scope.PLATFORMS_READ]) def get_platforms(request: Request) -> list[PlatformSchema]: """Get platforms endpoint @@ -57,7 +60,7 @@ def get_platforms(request: Request) -> list[PlatformSchema]: ] -@protected_route(router.get, "/platforms/supported", [Scope.PLATFORMS_READ]) +@protected_route(router.get, "/supported", [Scope.PLATFORMS_READ]) def get_supported_platforms(request: Request) -> list[PlatformSchema]: """Get list of supported platforms endpoint @@ -94,7 +97,7 @@ def get_supported_platforms(request: Request) -> list[PlatformSchema]: return supported_platforms -@protected_route(router.get, "/platforms/{id}", [Scope.PLATFORMS_READ]) +@protected_route(router.get, "/{id}", [Scope.PLATFORMS_READ]) def get_platform(request: Request, id: int) -> PlatformSchema: """Get platforms endpoint @@ -114,7 +117,7 @@ def get_platform(request: Request, id: int) -> PlatformSchema: return PlatformSchema.model_validate(platform) -@protected_route(router.put, "/platforms/{id}", [Scope.PLATFORMS_WRITE]) +@protected_route(router.put, "/{id}", [Scope.PLATFORMS_WRITE]) async def update_platform(request: Request, id: int) -> PlatformSchema: """Update platform endpoint @@ -138,7 +141,7 @@ async def update_platform(request: Request, id: int) -> PlatformSchema: return PlatformSchema.model_validate(platform_db) -@protected_route(router.delete, "/platforms/{id}", [Scope.PLATFORMS_WRITE]) +@protected_route(router.delete, "/{id}", [Scope.PLATFORMS_WRITE]) async def delete_platforms(request: Request, id: int) -> MessageResponse: """Delete platforms endpoint diff --git a/backend/endpoints/raw.py b/backend/endpoints/raw.py index 921bc46ff..355676041 100644 --- a/backend/endpoints/raw.py +++ b/backend/endpoints/raw.py @@ -5,16 +5,19 @@ from fastapi.responses import FileResponse from handler.auth.constants import Scope from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/raw", + tags=["raw"], +) -@protected_route(router.head, "/raw/assets/{path:path}", [Scope.ASSETS_READ]) +@protected_route(router.head, "/assets/{path:path}", [Scope.ASSETS_READ]) def head_raw_asset(request: Request, path: str): asset_path = f"{ASSETS_BASE_PATH}/{path}" return FileResponse(path=asset_path, filename=path.split("/")[-1]) -@protected_route(router.get, "/raw/assets/{path:path}", [Scope.ASSETS_READ]) +@protected_route(router.get, "/assets/{path:path}", [Scope.ASSETS_READ]) def get_raw_asset(request: Request, path: str): """Download a single asset file diff --git a/backend/endpoints/rom.py b/backend/endpoints/rom.py index f47abb3f5..b6e1876a1 100644 --- a/backend/endpoints/rom.py +++ b/backend/endpoints/rom.py @@ -42,10 +42,13 @@ from utils.hashing import crc32_to_hex from utils.nginx import FileRedirectResponse, ZipContentLine, ZipResponse from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/roms", + tags=["roms"], +) -@protected_route(router.post, "/roms", [Scope.ROMS_WRITE]) +@protected_route(router.post, "/", [Scope.ROMS_WRITE]) async def add_rom(request: Request): """Upload single rom endpoint @@ -107,7 +110,7 @@ async def add_rom(request: Request): return Response(status_code=status.HTTP_201_CREATED) -@protected_route(router.get, "/roms", [Scope.ROMS_READ]) +@protected_route(router.get, "/", [Scope.ROMS_READ]) def get_roms( request: Request, platform_id: int | None = None, @@ -170,7 +173,7 @@ def get_roms( @protected_route( router.get, - "/roms/{id}", + "/{id}", [] if DISABLE_DOWNLOAD_ENDPOINT_AUTH else [Scope.ROMS_READ], ) def get_rom(request: Request, id: int) -> DetailedRomSchema: @@ -194,7 +197,7 @@ def get_rom(request: Request, id: int) -> DetailedRomSchema: @protected_route( router.head, - "/roms/{id}/content/{file_name}", + "/{id}/content/{file_name}", [] if DISABLE_DOWNLOAD_ENDPOINT_AUTH else [Scope.ROMS_READ], ) async def head_rom_content( @@ -280,7 +283,7 @@ async def head_rom_content( @protected_route( router.get, - "/roms/{id}/content/{file_name}", + "/{id}/content/{file_name}", [] if DISABLE_DOWNLOAD_ENDPOINT_AUTH else [Scope.ROMS_READ], ) async def get_rom_content( @@ -396,7 +399,7 @@ async def get_rom_content( ) -@protected_route(router.put, "/roms/{id}", [Scope.ROMS_WRITE]) +@protected_route(router.put, "/{id}", [Scope.ROMS_WRITE]) async def update_rom( request: Request, id: int, @@ -572,7 +575,7 @@ async def update_rom( return DetailedRomSchema.from_orm_with_request(rom, request) -@protected_route(router.post, "/roms/delete", [Scope.ROMS_WRITE]) +@protected_route(router.post, "/delete", [Scope.ROMS_WRITE]) async def delete_roms( request: Request, ) -> MessageResponse: @@ -631,7 +634,7 @@ async def delete_roms( return {"msg": f"{len(roms_ids)} roms deleted successfully!"} -@protected_route(router.put, "/roms/{id}/props", [Scope.ROMS_USER_WRITE]) +@protected_route(router.put, "/{id}/props", [Scope.ROMS_USER_WRITE]) async def update_rom_user(request: Request, id: int) -> RomUserSchema: data = await request.json() rom_user_data = data.get("data", {}) diff --git a/backend/endpoints/saves.py b/backend/endpoints/saves.py index b3876c768..829ab2463 100644 --- a/backend/endpoints/saves.py +++ b/backend/endpoints/saves.py @@ -12,10 +12,13 @@ from handler.scan_handler import scan_save from logger.logger import log from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/saves", + tags=["saves"], +) -@protected_route(router.post, "/saves", [Scope.ASSETS_WRITE]) +@protected_route(router.post, "/", [Scope.ASSETS_WRITE]) def add_saves( request: Request, rom_id: int, @@ -84,17 +87,17 @@ def add_saves( } -# @protected_route(router.get, "/saves", [Scope.ASSETS_READ]) +# @protected_route(router.get, "/", [Scope.ASSETS_READ]) # def get_saves(request: Request) -> MessageResponse: # pass -# @protected_route(router.get, "/saves/{id}", [Scope.ASSETS_READ]) +# @protected_route(router.get, "/{id}", [Scope.ASSETS_READ]) # def get_save(request: Request, id: int) -> MessageResponse: # pass -@protected_route(router.put, "/saves/{id}", [Scope.ASSETS_WRITE]) +@protected_route(router.put, "/{id}", [Scope.ASSETS_WRITE]) async def update_save(request: Request, id: int) -> SaveSchema: data = await request.form() @@ -128,7 +131,7 @@ async def update_save(request: Request, id: int) -> SaveSchema: return SaveSchema.model_validate(db_save) -@protected_route(router.post, "/saves/delete", [Scope.ASSETS_WRITE]) +@protected_route(router.post, "/delete", [Scope.ASSETS_WRITE]) async def delete_saves(request: Request) -> MessageResponse: data: dict = await request.json() save_ids: list = data["saves"] diff --git a/backend/endpoints/screenshots.py b/backend/endpoints/screenshots.py index 81f92eb44..946ab650d 100644 --- a/backend/endpoints/screenshots.py +++ b/backend/endpoints/screenshots.py @@ -9,10 +9,13 @@ from handler.scan_handler import scan_screenshot from logger.logger import log from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/screenshots", + tags=["screenshots"], +) -@protected_route(router.post, "/screenshots", [Scope.ASSETS_WRITE]) +@protected_route(router.post, "/", [Scope.ASSETS_WRITE]) def add_screenshots( request: Request, rom_id: int, diff --git a/backend/endpoints/search.py b/backend/endpoints/search.py index fd6c1389f..2a804e34b 100644 --- a/backend/endpoints/search.py +++ b/backend/endpoints/search.py @@ -12,10 +12,13 @@ from handler.scan_handler import _get_main_platform_igdb_id from logger.logger import log from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/search", + tags=["search"], +) -@protected_route(router.get, "/search/roms", [Scope.ROMS_READ]) +@protected_route(router.get, "/roms", [Scope.ROMS_READ]) async def search_rom( request: Request, rom_id: int, @@ -117,7 +120,7 @@ async def search_rom( return matched_roms -@protected_route(router.get, "/search/cover", [Scope.ROMS_READ]) +@protected_route(router.get, "/cover", [Scope.ROMS_READ]) async def search_cover( request: Request, search_term: str = "", diff --git a/backend/endpoints/states.py b/backend/endpoints/states.py index 5ed07e616..d9eedaa5d 100644 --- a/backend/endpoints/states.py +++ b/backend/endpoints/states.py @@ -12,10 +12,13 @@ from handler.scan_handler import scan_state from logger.logger import log from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/states", + tags=["states"], +) -@protected_route(router.post, "/states", [Scope.ASSETS_WRITE]) +@protected_route(router.post, "/", [Scope.ASSETS_WRITE]) def add_states( request: Request, rom_id: int, @@ -83,17 +86,17 @@ def add_states( } -# @protected_route(router.get, "/states", [Scope.ASSETS_READ]) +# @protected_route(router.get, "/", [Scope.ASSETS_READ]) # def get_states(request: Request) -> MessageResponse: # pass -# @protected_route(router.get, "/states/{id}", [Scope.ASSETS_READ]) +# @protected_route(router.get, "/{id}", [Scope.ASSETS_READ]) # def get_state(request: Request, id: int) -> MessageResponse: # pass -@protected_route(router.put, "/states/{id}", [Scope.ASSETS_WRITE]) +@protected_route(router.put, "/{id}", [Scope.ASSETS_WRITE]) async def update_state(request: Request, id: int) -> StateSchema: data = await request.form() @@ -126,7 +129,7 @@ async def update_state(request: Request, id: int) -> StateSchema: return StateSchema.model_validate(db_state) -@protected_route(router.post, "/states/delete", [Scope.ASSETS_WRITE]) +@protected_route(router.post, "/delete", [Scope.ASSETS_WRITE]) async def delete_states(request: Request) -> MessageResponse: data: dict = await request.json() state_ids: list = data["states"] diff --git a/backend/endpoints/stats.py b/backend/endpoints/stats.py index c6af7a6fb..081dc98bd 100644 --- a/backend/endpoints/stats.py +++ b/backend/endpoints/stats.py @@ -2,10 +2,13 @@ from endpoints.responses.stats import StatsReturn from handler.database import db_stats_handler from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/stats", + tags=["stats"], +) -@router.get("/stats") +@router.get("/") def stats() -> StatsReturn: """Endpoint to return the current RomM stats diff --git a/backend/endpoints/tasks.py b/backend/endpoints/tasks.py index 12f301a22..3d9373033 100644 --- a/backend/endpoints/tasks.py +++ b/backend/endpoints/tasks.py @@ -5,10 +5,13 @@ from handler.auth.constants import Scope from tasks.update_switch_titledb import update_switch_titledb_task from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/tasks", + tags=["tasks"], +) -@protected_route(router.post, "/tasks/run", [Scope.TASKS_RUN]) +@protected_route(router.post, "/run", [Scope.TASKS_RUN]) async def run_tasks(request: Request) -> MessageResponse: """Run all tasks endpoint @@ -22,7 +25,7 @@ async def run_tasks(request: Request) -> MessageResponse: return {"msg": "All tasks ran successfully!"} -@protected_route(router.post, "/tasks/{task}/run", [Scope.TASKS_RUN]) +@protected_route(router.post, "/{task}/run", [Scope.TASKS_RUN]) async def run_task(request: Request, task: str) -> MessageResponse: """Run all tasks endpoint diff --git a/backend/endpoints/user.py b/backend/endpoints/user.py index 5d0988c68..687afcd83 100644 --- a/backend/endpoints/user.py +++ b/backend/endpoints/user.py @@ -16,12 +16,15 @@ from logger.logger import log from models.user import Role, User from utils.router import APIRouter -router = APIRouter() +router = APIRouter( + prefix="/users", + tags=["users"], +) @protected_route( router.post, - "/users", + "/", [], status_code=status.HTTP_201_CREATED, ) @@ -77,7 +80,7 @@ def add_user( return UserSchema.model_validate(db_user_handler.add_user(user)) -@protected_route(router.get, "/users", [Scope.USERS_READ]) +@protected_route(router.get, "/", [Scope.USERS_READ]) def get_users(request: Request) -> list[UserSchema]: """Get all users endpoint @@ -91,7 +94,7 @@ def get_users(request: Request) -> list[UserSchema]: return [UserSchema.model_validate(u) for u in db_user_handler.get_users()] -@protected_route(router.get, "/users/me", [Scope.ME_READ]) +@protected_route(router.get, "/me", [Scope.ME_READ]) def get_current_user(request: Request) -> UserSchema | None: """Get current user endpoint @@ -105,7 +108,7 @@ def get_current_user(request: Request) -> UserSchema | None: return request.user -@protected_route(router.get, "/users/{id}", [Scope.USERS_READ]) +@protected_route(router.get, "/{id}", [Scope.USERS_READ]) def get_user(request: Request, id: int) -> UserSchema: """Get user endpoint @@ -123,7 +126,7 @@ def get_user(request: Request, id: int) -> UserSchema: return UserSchema.model_validate(user) -@protected_route(router.put, "/users/{id}", [Scope.ME_WRITE]) +@protected_route(router.put, "/{id}", [Scope.ME_WRITE]) async def update_user( request: Request, id: int, form_data: Annotated[UserForm, Depends()] ) -> UserSchema: @@ -220,7 +223,7 @@ async def update_user( return UserSchema.model_validate(db_user) -@protected_route(router.delete, "/users/{id}", [Scope.USERS_WRITE]) +@protected_route(router.delete, "/{id}", [Scope.USERS_WRITE]) def delete_user(request: Request, id: int) -> MessageResponse: """Delete user endpoint