Pydantic does the validation and generates OpenAPI docs on its own.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | # ====================================================================== # Q: Write a FastAPI endpoint with validation, a dependency for the DB session # and correct status codes. # # Pydantic does the validation and generates OpenAPI docs on its own. # response_model filters the fields so internal fields do not leak. The # tenant_id check is inside the query (404, not 403). Depends corresponds to # DRF's authentication/permission classes. # ====================================================================== from fastapi import FastAPI, Depends, HTTPException, status from pydantic import BaseModel, Field, ConfigDict app = FastAPI() class AssetIn(BaseModel): hostname: str = Field(min_length=1, max_length=255) ip: str criticality: int = Field(ge=1, le=5) class AssetOut(AssetIn): model_config = ConfigDict(from_attributes=True) # from an ORM object id: int @app.post('/v1/assets', response_model=AssetOut, status_code=status.HTTP_201_CREATED) def create_asset(data: AssetIn, session: Session = Depends(get_session), user: User = Depends(require_permission('assets:write'))): asset = Asset(**data.model_dump(), tenant_id=user.tenant_id) session.add(asset) session.flush() # so it gets an id before the commit return asset @app.get('/v1/assets/{asset_id}', response_model=AssetOut) def get_asset(asset_id: int, session: Session = Depends(get_session), user: User = Depends(current_user)): asset = session.scalar(select(Asset).where( Asset.id == asset_id, Asset.tenant_id == user.tenant_id)) if asset is None: raise HTTPException(status.HTTP_404_NOT_FOUND) return asset |