Python > Web Development with Python > Asynchronous Web Frameworks (e.g., FastAPI, AsyncIO) > Request and Response in FastAPI

FastAPI Request Body and Response Model Example

This example demonstrates how to define request bodies and response models in FastAPI using Pydantic. We define a simple item model with required fields and use it for both request input and response output. The example showcases automatic data validation, serialization, and documentation generated by FastAPI.

Setting up the FastAPI Application and Data Model

This section sets up the basic FastAPI application. We import `FastAPI` and `BaseModel` from their respective libraries. `BaseModel` from `pydantic` allows us to define data models with type hints, which are crucial for request and response validation and serialization. The `Item` class defines the structure of our data, including fields like `name` (string), `description` (optional string), `price` (float), and `tax` (optional float). The `Union` type hint allows a field to be either of the specified types (e.g., string or None).

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None

Defining a POST Endpoint with Request Body

This defines a POST endpoint at `/items/`. The `create_item` function takes an argument `item` of type `Item`. FastAPI automatically understands that this `item` should be populated from the request body, and it deserializes the incoming JSON data into an `Item` object. FastAPI will also automatically validate the request body against the `Item` model. If the request body is invalid, FastAPI will return an HTTP 422 error with details about the validation errors.

@app.post("/items/")
async def create_item(item: Item):
    return item

Defining a GET Endpoint with Path Parameters and Query Parameters

This defines a GET endpoint at `/items/{item_id}`. The `item_id` is a path parameter, meaning it's part of the URL itself. The `q` is an optional query parameter. FastAPI automatically handles parsing these parameters from the URL. The function returns a dictionary containing the `item_id` and the value of the `q` parameter.

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

Running the FastAPI Application

This section provides instructions on how to run the FastAPI application using Uvicorn. The `uvicorn main:app --reload` command starts the server and automatically reloads the application whenever changes are made to the code. The example POST request shows the expected JSON format for creating a new item.

# To run this example, save it as main.py and execute:
# uvicorn main:app --reload

# Then you can send a POST request to /items/ with a JSON body like:
# {
#     "name": "Foo",
#     "description": "An optional description",
#     "price": 50.2,
#     "tax": 2.3
# }

Concepts behind the snippet

  • Pydantic Models: Pydantic models provide data validation and serialization/deserialization.
  • Path Parameters: Path parameters are part of the URL path, defined with curly braces {}.
  • Query Parameters: Query parameters are appended to the URL after a question mark (?), separated by ampersands (&).
  • Request Body: The request body is the data sent in the body of a POST, PUT, or PATCH request. FastAPI automatically parses and validates the request body based on the defined Pydantic model.

Real-Life Use Case Section

Consider an e-commerce API. The `Item` model could represent a product. A POST endpoint like `/products` would allow administrators to add new products to the catalog. A GET endpoint like `/products/{product_id}` would allow customers to retrieve details about a specific product. The request body validation ensures that only valid product data is added to the database.

Best Practices

  • Use descriptive variable names.
  • Provide clear and informative error messages. Pydantic's validation errors are very helpful in this regard.
  • Document your API endpoints using OpenAPI. FastAPI automatically generates OpenAPI documentation based on your code.
  • Consider using dependency injection for reusable logic.

Interview Tip

Be prepared to discuss the benefits of using FastAPI for building APIs, including its speed, automatic data validation, and generation of API documentation (Swagger UI). Also, be ready to explain how Pydantic models facilitate data serialization and deserialization.

When to use them

Use FastAPI when you need to build high-performance APIs quickly and efficiently, especially when you require data validation and automatic API documentation. It's particularly well-suited for microservices and applications that handle a large number of requests.

Memory footprint

FastAPI's memory footprint is relatively small due to its asynchronous nature and efficient data handling. The use of Pydantic also helps in optimizing memory usage by validating and serializing data efficiently.

Alternatives

Alternatives to FastAPI include Flask, Django REST framework, and Tornado. Flask is a microframework that offers more flexibility but requires more manual configuration. Django REST framework is a powerful but more heavyweight framework. Tornado is another asynchronous framework, but it doesn't provide the same level of data validation and automatic documentation as FastAPI.

Pros

  • Fast performance: Asynchronous support and efficient data handling.
  • Automatic data validation: Pydantic integration ensures data integrity.
  • Automatic API documentation: Generates Swagger UI and ReDoc documentation.
  • Easy to learn and use: Simple and intuitive API.

Cons

  • Relatively new: The ecosystem is still evolving compared to more established frameworks.
  • Steeper learning curve for asynchronous programming: Requires understanding of async/await syntax.

FAQ

  • What is Pydantic and why is it used in FastAPI?

    Pydantic is a data validation and settings management library for Python. It's used in FastAPI to define data models, validate request and response data, and automatically serialize and deserialize JSON. It provides strong type checking and helps prevent errors related to data format.
  • How does FastAPI handle data validation?

    FastAPI leverages Pydantic models to automatically validate incoming request data. When a request is received, FastAPI deserializes the data into a Pydantic model. If the data doesn't conform to the model's defined types and constraints, FastAPI raises a validation error, preventing invalid data from reaching your application logic.
  • How do I handle different HTTP methods (GET, POST, PUT, DELETE) in FastAPI?

    You use the corresponding decorator for each HTTP method: `@app.get()`, `@app.post()`, `@app.put()`, `@app.delete()`, etc. Each decorator is associated with a function that handles requests for that specific method and path.