In FastAPI, I am using SQLAlchemy and Pydantic to return data.
@router.get("/1", response_model=User)
def read_user(db: Session = Depends(get_db)):
db_user = user_module.get_user(db, user_id="1")
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
This approach helps me standardize the returned model, but I want to unify the response format for all APIs to {"code": 0, "msg": "success", "data": {...}}
, so that the User model from the original return model is placed within the "data" field, making it easier for frontend management.
I attempted to use FastAPI middleware for implementation, but it doesn't recognize the User return model in Swagger and other documentation. If I redefine a generic Pydantic return model with nested models, I cannot manipulate the SQLAlchemy returned data model into the desired User model.
Is there any way to solve my requirement or are there any better solutions?
To unify the response format in FastAPI to {"code": 0, "msg": "success", "data": {...}}
, while preserving Pydantic data models and ensuring proper recognition in Swagger and other documentation.
from pydantic import BaseModel, Field
from typing import Generic, TypeVar, Type, Optional
from fastapi import Depends, HTTPException, APIRouter
from sqlalchemy.orm import Session
T = TypeVar('T')
class GenericResponse(BaseModel, Generic[T]):
code: int = Field(default=0, example=0)
msg: str = Field(default="success", example="success")
data: Optional[T]
router = APIRouter()
@router.get("/1", response_model=GenericResponse[User])
def read_user(db: Session = Depends(get_db)):
db_user = user_module.get_user(db, user_id="1")
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return GenericResponse(data=db_user)
declaring a generic response might be able to help you fix the structure and standardize the response in your required type.