Decorate response model of a FastAPI route with another model

Question:

I have a common response pattern for most of the routes, like having specific fields in it (e.g. ‘date’ with default value, ‘info’, where decorated data should live in and so on).

For example, having this endpoint:

@route.get(...,response_model=Entry) endpoint returns serialized Entry object.

Would it be possible to declare a pydantic model, like CommonResponse, that automatically contains predefined fields and put Entry model in its field(‘info’), and use like this:

@route.get(...,response_model=CommonResponse[Entry]) or @route.get(...,response_model=CommonResponse[List[Entry]])

Asked By: Maxim Kolodnikov

||

Answers:

According to pydantic doc- Generic Models

Pydantic supports the creation of generic models to make it easier to reuse a common model structure.

  1. define generic model
DataT = TypeVar('DataT')


class GenericResponseModel(GenericModel, Generic[DataT]):
    success: bool = Field(True)
    error_msg: Optional[str] = Field(None, alias='errorMsg')
    data: Optional[DataT] = Field(None)
    total: Optional[int] = Field(None)

    class Config:
        allow_population_by_field_name = True
  1. Use in your response_model
@router.get('/',
         response_model=schemas.GenericResponseModel[List[schemas.ShopModel]])
# ...

@router.get('/{shop_id}',
            response_model=schemas.GenericResponseModel[schemas.ShopModel])
async def get():
    # ...
    shop = get_shop()
    return schemas.GenericResponseModel(data=shop)
  1. The openapi doc will cantains List[schemas.ShopModel] or schemas.ShopModel and have example value for these
Answered By: dilless
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.