Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return Pydantic object with a specific http response code in FastAPI?

I have an endpoint which returns a Pydantic object. However, I would like a response code other than 200 in some cases (for example if my service in not healthy). How can I achieve that with FastAPI?

class ServiceHealth(BaseModel):
    http_ok: bool = True
    database_ok: bool = False

    def is_everything_ok(self) -> bool:
        return self.http_ok and self.database_ok

@router.get("/health")
def health() -> ServiceHealth:
    return ServiceHealth()
like image 495
poiuytrez Avatar asked Feb 01 '26 06:02

poiuytrez


2 Answers

You can return a Response Directly.

For example, you can use JSONResponse and set the status manually:

@router.get("/health")
async def health() -> ServiceHealth:
    response = ServiceHealth()
    
    if response.is_everything_ok():
        return JSONResponse(content=response.dict(), status_code=200)
    return JSONResponse(content=response.dict(), status_code=500)

Also, there is a handy status.py which you can import from fastapi that contains all the available status codes:

from fastapi import status

@router.get("/health")
async def health() -> ServiceHealth:
    response = ServiceHealth()
    
    if response.is_everything_ok():
        return JSONResponse(content=response.dict(), status_code=status.HTTP_200_OK)
    return JSONResponse(content=response.dict(), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
like image 70
John Moutafis Avatar answered Feb 03 '26 18:02

John Moutafis


Just specify the status_code keyword-argument, when initializing your APIRoute. It is passed along by all route decorators as far as I know, including APIRouter.get.

from fastapi import FastAPI
from pydantic import BaseModel


class ServiceHealth(BaseModel):
    http_ok: bool = True
    database_ok: bool = False


api = FastAPI()


@api.get("/health", status_code=299)
def health() -> ServiceHealth:
    return ServiceHealth()

Performing a GET on that route still returns the expected JSON {"http_ok":true,"database_ok":false} with the HTTP status code 299 (just to demonstrate, not a "real" status code).

There are a few restrictions that FastAPI places on that argument. Notably, you cannot return a body, if you define a 304 status code or any informational (1xx) status code.

like image 32
Daniil Fajnberg Avatar answered Feb 03 '26 20:02

Daniil Fajnberg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!