Sling Academy
Home/FastAPI/FastAPI: How to Change the Response Status Code

FastAPI: How to Change the Response Status Code

Last updated: September 02, 2023

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!

Next Article: FastAPI: How to Upload and Validate Files

Previous Article: 3 Ways to Get User’s IP Address in FastAPI

Series: FastAPI Request & Response Tutorials

FastAPI

You May Also Like

  • Popular useful built-in Jinja filters you should know
  • How to remove consecutive whitespace in rendered Jinja pages
  • How to format large numbers with thousand separators in Jinja template
  • How to format date time in Jinja templates
  • FastAPI + Jinja: How to create custom filters
  • How to pass variables from Python (FastAPI) to Jinja
  • How to decode Jinja response to string
  • How to create and use macros in Jinja
  • How to use namespace in Jinja
  • How to use if/ else in Jinja
  • How to use loops in Jinja
  • FastAPI + SQLAlchemy: Using cursor-based pagination
  • FastAPI: How to use macros in Jinja templates
  • Fixing Common Swagger UI Errors in FastAPI
  • FastAPI Error: 307 Temporary Redirect – Causes and Solutions
  • FastAPI Error: Expected UploadFile, received ‘str’
  • Resolving FastAPI ImportError: No Known Parent Package
  • FastAPI Error: No module named ‘pydantic_core._pydantic_core’
  • Resolving FastAPI 422 Error: Value is not a valid dict