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_OK
, HTTP_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!