Defining and using request and response models
In the world of API development, data handling is a critical aspect that determines the robustness and reliability of your application. FastAPI simplifies this process through its seamless integration with Pydantic, a data validation and settings management library using Python type annotations. The recipe will show you how to define and use request and response models in FastAPI, ensuring your data is well structured, validated, and clearly defined.
Pydantic models are a powerful feature for data validation and conversion. They allow you to define the structure, type, and constraints of the data your application handles, both for incoming requests and outgoing responses.
In this recipe, we will see how to use Pydantic to ensure that your data conforms to the specified schema, providing an automatic layer of safety and clarity.
Getting ready
This recipe requires you to know how to set up a basic endpoint in FastAPI.
How to do it...
We will break the process into the following steps:
- Creating the model
- Defining the request body
- Validating request data
- Managing response formats
Creating the model
Let’s create a Pydantic BaseModel
class for our bookstore application in a new file called models.py
.
Suppose we want to have a model for a book that includes the title, author, and publication year:
from pydantic import BaseModel class Book(BaseModel): title: str author: str year: int
Here, Book
is a Pydantic BaseModel
class with three fields: title
, author
, and year
. Each field is typed, ensuring that any data conforming to this model will have these attributes with the specified data types.
Defining the request body
In FastAPI, Pydantic models are not just for validation. They also serve as the request body. Let’s add an endpoint to our application where users can add new books:
from models import Book @app.post("/book") async def create_book(book: Book): return book
In this endpoint, when a user sends a POST
request to the /book
endpoint with JSON data, FastAPI automatically parses and validates it against the Book
model. If the data is invalid, the user gets an automatic error response.
Validating request data
Pydantic offers advanced validation features. For instance, you can add regex validations, default values, and more:
from pydantic import BaseModel, Field class Book(BaseModel): title: str = Field(..., min_length=1, max_length=100) author: str = Field(..., min_length=1, max_length=50) year: int = Field(..., gt=1900, lt=2100)
For an exhaustive list of validation features, have a look at Pydantic’s official documentation: https://docs.pydantic.dev/latest/concepts/fields/.
Next, you can proceed to manage the response format.
Managing response formats
FastAPI allows you to define response models explicitly, ensuring that the data returned by your API matches a specific schema. This can be particularly useful for filtering out sensitive data or restructuring the response.
For example, let’s say you want the /allbooks
GET
endpoint to return a list of books, but only with their titles and authors, omitting the publication year. In main.py
, add the following accordingly:
from pydantic import BaseModel class BookResponse(BaseModel): title: str author: str @app.get("/allbooks") async def read_all_books() -> list[BookResponse]: return [ { "id": 1, "title": "1984", "author": "George Orwell"}, { "id": 1, "title": "The Great Gatsby", "author": "F. Scott Fitzgerald", }, ]
Here, the -> list[BookResponse]
function type hint tells FastAPI to use the BookResponse
model for responses, ensuring that only the title and author fields are included in the response JSON. Alternatively, you can specify the response type in the endpoint decorator’s arguments as follows:
@app.get("/allbooks", response_model= list[BookResponse]) async def read_all_books() -> Any: # rest of the endpoint content
The response_model
argument takes priority and can be used instead of the type hint to resolve type checker issues that may occur.
Check the documentation at http://127.0.0.1:8000/docs
. Unroll the /allbooks
endpoint details, and you will notice the example value response based on the schema as follows:
[ { "title": "string", "author": "string" } ]
By mastering Pydantic models in FastAPI, you are now capable of handling complex data structures with ease and precision. You’ve learned to define request bodies and manage response formats, ensuring data consistency and integrity throughout your application.
See also
Pydantic is a standalone project largely used for data validation in Python with many more features than what the recipe has shown. Feel free to have a look at the official documentation at the following link:
- Pydantic: https://docs.pydantic.dev/latest/
You can see more on response model usage at the FastAPI official documentation link:
- Response Model - Return Type: https://fastapi.tiangolo.com/tutorial/response-model/