FastAPI: How to Change the Response Status Code

Updated: September 2, 2023 By: Khue Post a comment

FastAPI, as its name implies, is a fast, modern, and high-performance web framework for building backend APIs with Python. The response status code is a three-digit number that indicates the result of a request. For example, 200 means OK, 404 means Not Found, and 500 means Internal Server Error. By default, FastAPI will return a 200 status code for successful requests and a 422 status code for validation errors. However, sometimes you may want to change the status code to indicate a different outcome. For example, you may want to return a 201 status code for a successful POST request that creates a new resource, or a 404 status code for a GET request that cannot find the requested resource.

In this concise, exampled-base article, I will show you 2 different ways to change the response status code in FastAPI.

Using the status_code parameter of route decorators

To change the response status code in FastAPI, you can use the status_code parameter in the @app.get@app.post, or other route decorators. The status_code parameter accepts an integer value or a constant from the starlette.status module. For example, to return a 201 status code for a POST request that creates a new user, you can do as shown below:

from fastapi import FastAPI
from starlette.status import HTTP_201_CREATED

# create the FastAPI instance
app = FastAPI()

# set the status code to 201
@app.post("/users", status_code=HTTP_201_CREATED)
def create_user(name: str):
    # some logic to create a new user
    return {"name": name}

In the code snippet above,  I imported the constant HTTP_201_CREATED from the starlette.status module. The starlette.status module is a part of the starlette framework, which is a dependency of FastAPI. The starlette.status module provides constants for common HTTP status codes, such as HTTP_200_OKHTTP_404_NOT_FOUND, and so on. Using these constants can make the code more readable and avoid typos or errors. For example, instead of writing status_code=201, I can write status_code=HTTP_201_CREATED, which is more descriptive and clear.

Boot your API up by running:

uvicorn main:app --reload

Then go to http://localhost:8000/docs to give it a shot:

Using the Response object

In this approach, we use the Response object from the fastapi module to set the status code dynamically in the function body. The Response object has a status_code attribute that you can assign an integer value or a constant from the starlette.status module.

The following example returns a 404 status code for a GET request that cannot find the requested user:

from fastapi import FastAPI, Response
from starlette.status import HTTP_404_NOT_FOUND, HTTP_200_OK

app = FastAPI()


@app.get("/users/{user_id}")
def get_user(user_id: int, response: Response):
    # some logic to get the user by id
    user = None

    if user is None:
        # set the status code
        response.status_code = HTTP_404_NOT_FOUND
        return {"detail": "User not found"}
    else:
        # set the status code
        response.status_code = HTTP_200_OK
        return user

You can test it by using the built-in Swagger UI at http://localhost:8000/docs:

Advanced Example

This is a complete code example that shows how to change the response status code in FastAPI for different scenarios:

# SlingAcademy.com
# main.py

from fastapi import FastAPI, Response
from starlette.status import HTTP_201_CREATED, HTTP_404_NOT_FOUND

app = FastAPI()

# A mock database of users
users = [
    {"id": 1, "name": "Sling Academy"},
    {"id": 2, "name": "Ranni the Witch"},
    {"id": 3, "name": "Khue"},
]


# A helper function to get a user by id
def get_user_by_id(user_id: int):
    for user in users:
        if user["id"] == user_id:
            return user
    return None


# A POST route to create a new user and return a 201 status code
@app.post("/users", status_code=HTTP_201_CREATED)
def create_user(name: str):
    # some logic to create a new user and add it to the database
    new_user = {"id": len(users) + 1, "name": name}
    users.append(new_user)
    return new_user


# A GET route to get a user by id and return either a 200 or a 404 status code
@app.get("/users/{user_id}")
def get_user(user_id: int, response: Response):
    # some logic to get the user by id from the database
    user = get_user_by_id(user_id)
    if user is None:
        response.status_code = HTTP_404_NOT_FOUND
        return {"detail": "User not found"}
    else:
        return user

Conclusion

In this article, I have explained how to change the response status code in FastAPI using two methods: the status_code parameter in the route decorators and the Response object in the function body. You can use either method depending on your needs and preferences. Changing the response status code can help you communicate more clearly with your clients and follow the best practices of RESTful API design. This tutorial ends here. Happy coding & enjoy your day!