Utilities
Additional metadata in the resulting response schema
If you need to add fields to the response schema that are not supported by AbstractResponseSchema.from_api_route
, you can use the respond
function.
# schemas.py file
from typing import TypeVar, Generic
from fastapi_responseschema import AbstractResponseSchema
T = TypeVar("T")
class ResponseSchema(AbstractResponseSchema[T], Generic[T]):
data: T
error: bool
code: str # From a `result_code` field, not natively supported by constructors
@classmethod
def from_exception(cls, reason: T, status_code: int, result_code: str = "Error", **others):
return cls(
data=reason,
error=status_code >= 400,
code=result_code
)
@classmethod
def from_api_route(
cls, content: T, status_code: int, result_code: Optional[str] = None, **others
):
return cls(
data=content,
error=status_code >= 400,
code=result_code
)
...
# api.py file
from fastapi import APIRouter
from fastapi_responseschema import respond
from .schemas import StandardAPIRoute # the SchemaAPIRoute you defined
router = APIRouter(route_class=StandardAPIRoute)
class ParrotMessage(BaseModel):
message: str
@router.post("/parrot")
def repeat(body: ParrotMessage):
return respond({"parrot_says": body.message}, result_code="OK_PARROT_HEALTHY")
In a similar way, for fields that are not supported in AbstractResponseSchema.from_exception
you can raise an exception with metadata:
from fastapi_responseschema.exceptions import GenericHTTPException
...
@router.get("/faulty")
def repeat():
raise GenericHTTPException(status_code=405, detail="This is a faulty service", result_code="KO_NOT_SUPPORTED")
Exceptions
When developing a backend service usually we keep raising the same few excpetions with the same status code.
You can use the exceptions
module to reduce a little bit the boilerplate code.
from fastapi_responseschema.exceptions import MethodNotAllowed, Gone, NotFound
...
@router.get("/faulty")
def repeat():
raise MethodNotAllowed(detail="This is a faulty service", result_code="KO_NOT_SUPPORTED")
@router.get("/ghost")
def ghost():
raise Gone(detail="This resource is gone, forever.", result_code="KO_CREEPY_GONE")
@router.get("/nope")
def ghost():
raise NotFound(detail="Nope man, can't help you", result_code="KO_NOT_FOUND")