Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a separate response_model for HTTP 400 errors?

Tags:

fastapi

I'm forced to set all values in a response_model as Optional.

class ConnectOut(BaseModel):
    product_id: Optional[str]
    expires_at: Optional[datetime]
    detail: Optional[ErrorType]

If I don't do that the HTTP400 path below throws validation errors, because product_id and expires_at won't be provided in case of a 400 error.

@router_connect.post("/", status_code=200, response_model=ConnectOut)
async def connect(
    body: ConnectIn,
    response: Response,
):
    if account.is_banned:
        response.status_code = status.HTTP_400_BAD_REQUEST
        return {"detail": ErrorType.USER_IS_BANNED}

Is there a way to define a response_model for success and response_model for 400 Error messages?

Many Thanks,

like image 743
Houman Avatar asked Apr 22 '26 19:04

Houman


1 Answers

You can simply raise an HTTPException instead of returning a non-fitting response for the given response model, e.g.:

from fastapi import HTTPException
...
raise HTTPException(status_code=400, detail="Example bad request.")

EDIT:

For documentation purposes, you can do the following to have it properly display:

@example_router.post(
    "/example",
    response_model=schemas.Example,
    status_code=201,
    responses={200: {"model": schemas.Example}, 400: {"model": schemas.HTTPError}},
)
def create_example(...) -> models.Example:
    ...
    raise HTTPException(status_code=400, detail="Example bad request.")

Where the HTTPError schema looks like this:

from pydantic import BaseModel

class HTTPError(BaseModel):
    """
    HTTP error schema to be used when an `HTTPException` is thrown.
    """

    detail: str
like image 168
Jason Rebelo Neves Avatar answered May 07 '26 06:05

Jason Rebelo Neves