@@ -821,7 +821,7 @@ uv run alembic upgrade head
821821
822822> 📖 ** [ See CRUD operations guide in our docs] ( https://benavlabs.github.io/FastAPI-boilerplate/user-guide/database/crud/ ) **
823823
824- Inside ` app/crud ` , create a new ` crud_entities .py` inheriting from ` FastCRUD ` for each new entity:
824+ Inside ` app/crud ` , create a new ` crud_entity .py` inheriting from ` FastCRUD ` for each new entity:
825825
826826``` python
827827from fastcrud import FastCRUD
@@ -1028,42 +1028,56 @@ crud_user.get(db=db, username="myusername", schema_to_select=UserRead)
10281028
10291029> 📖 ** [ See API endpoints guide in our docs] ( https://benavlabs.github.io/FastAPI-boilerplate/user-guide/api/endpoints/ ) **
10301030
1031- Inside ` app/api/v1 ` , create a new ` entities.py ` file and create the desired routes
1031+ Inside ` app/api/v1 ` , create a new ` entities.py ` file and create the desired routes with proper dependency injection:
10321032
10331033``` python
1034- from typing import Annotated
1035-
1036- from fastapi import Depends
1034+ from typing import Annotated, List
1035+ from fastapi import Depends, Request, APIRouter
1036+ from sqlalchemy.ext.asyncio import AsyncSession
10371037
10381038from app.schemas.entity import EntityRead
10391039from app.core.db.database import async_get_db
1040+ from app.crud.crud_entity import crud_entity
10401041
1041- ...
1042+ router = APIRouter( tags = [ " entities " ])
10421043
1043- router = fastapi.APIRouter(tags = [" entities" ])
1044-
1045-
1046- @router.get (" /entities/{id} " , response_model = List[EntityRead])
1047- async def read_entities (request : Request, id : int , db : Annotated[AsyncSession, Depends(async_get_db)]):
1048- entity = await crud_entities.get(db = db, id = id )
10491044
1045+ @router.get (" /entities/{id} " , response_model = EntityRead)
1046+ async def read_entity (
1047+ request : Request,
1048+ id : int ,
1049+ db : Annotated[AsyncSession, Depends(async_get_db)]
1050+ ):
1051+ entity = await crud_entity.get(db = db, id = id )
1052+
1053+ if entity is None : # Explicit None check
1054+ raise NotFoundException(" Entity not found" )
1055+
10501056 return entity
10511057
10521058
1053- ...
1059+ @router.get (" /entities" , response_model = List[EntityRead])
1060+ async def read_entities (
1061+ request : Request,
1062+ db : Annotated[AsyncSession, Depends(async_get_db)]
1063+ ):
1064+ entities = await crud_entity.get_multi(db = db, is_deleted = False )
1065+ return entities
10541066```
10551067
1056- Then in ` app/api/v1/__init__.py ` add the router such as :
1068+ Then in ` app/api/v1/__init__.py ` add the router:
10571069
10581070``` python
10591071from fastapi import APIRouter
1060- from app.api.v1.entity import router as entity_router
1072+ from app.api.v1.entities import router as entity_router
1073+ from app.api.v1.users import router as user_router
1074+ from app.api.v1.posts import router as post_router
10611075
1062- ...
1076+ router = APIRouter( prefix = " /v1 " )
10631077
1064- router = APIRouter( prefix = " /v1 " ) # this should be there already
1065- ...
1066- router.include_router(entity_router)
1078+ router.include_router(user_router)
1079+ router.include_router(post_router)
1080+ router.include_router(entity_router) # Add your new router
10671081```
10681082
10691083#### 5.7.1 Paginated Responses
@@ -1100,6 +1114,9 @@ With the `get_multi` method we get a python `dict` with full suport for paginati
11001114And in the endpoint, we can import from ` fastcrud.paginated ` the following functions and Pydantic Schema:
11011115
11021116``` python
1117+ from typing import Annotated
1118+ from fastapi import Depends, Request
1119+ from sqlalchemy.ext.asyncio import AsyncSession
11031120from fastcrud.paginated import (
11041121 PaginatedListResponse, # What you'll use as a response_model to validate
11051122 paginated_response, # Creates a paginated response based on the parameters
@@ -1119,13 +1136,16 @@ from app.schemas.entity import EntityRead
11191136
11201137@router.get (" /entities" , response_model = PaginatedListResponse[EntityRead])
11211138async def read_entities (
1122- request : Request, db : Annotated[AsyncSession, Depends(async_get_db)], page : int = 1 , items_per_page : int = 10
1139+ request : Request,
1140+ db : Annotated[AsyncSession, Depends(async_get_db)],
1141+ page : int = 1 ,
1142+ items_per_page : int = 10
11231143):
11241144 entities_data = await crud_entity.get_multi(
11251145 db = db,
11261146 offset = compute_offset(page, items_per_page),
11271147 limit = items_per_page,
1128- schema_to_select = UserRead ,
1148+ schema_to_select = EntityRead ,
11291149 is_deleted = False ,
11301150 )
11311151
@@ -1139,15 +1159,48 @@ async def read_entities(
11391159To add exceptions you may just import from ` app/core/exceptions/http_exceptions ` and optionally add a detail:
11401160
11411161``` python
1142- from app.core.exceptions.http_exceptions import NotFoundException
1162+ from app.core.exceptions.http_exceptions import (
1163+ NotFoundException,
1164+ ForbiddenException,
1165+ DuplicateValueException
1166+ )
1167+
1168+ @router.post (" /entities" , response_model = EntityRead, status_code = 201 )
1169+ async def create_entity (
1170+ request : Request,
1171+ entity_data : EntityCreate,
1172+ db : Annotated[AsyncSession, Depends(async_get_db)],
1173+ current_user : Annotated[UserRead, Depends(get_current_user)]
1174+ ):
1175+ # Check if entity already exists
1176+ if await crud_entity.exists(db = db, name = entity_data.name) is True :
1177+ raise DuplicateValueException(" Entity with this name already exists" )
1178+
1179+ # Check user permissions
1180+ if current_user.is_active is False : # Explicit boolean check
1181+ raise ForbiddenException(" User account is disabled" )
1182+
1183+ # Create the entity
1184+ entity = await crud_entity.create(db = db, object = entity_data)
1185+
1186+ if entity is None : # Explicit None check
1187+ raise CustomException(" Failed to create entity" )
1188+
1189+ return entity
11431190
1144- # If you want to specify the detail, just add the message
1145- if not user:
1146- raise NotFoundException(" User not found" )
11471191
1148- # Or you may just use the default message
1149- if not post:
1150- raise NotFoundException()
1192+ @router.get (" /entities/{id} " , response_model = EntityRead)
1193+ async def read_entity (
1194+ request : Request,
1195+ id : int ,
1196+ db : Annotated[AsyncSession, Depends(async_get_db)]
1197+ ):
1198+ entity = await crud_entity.get(db = db, id = id )
1199+
1200+ if entity is None : # Explicit None check
1201+ raise NotFoundException(" Entity not found" )
1202+
1203+ return entity
11511204```
11521205
11531206** The predefined possibilities in http_exceptions are the following:**
0 commit comments