Page cover image

🍊Unit 8: Request Body

Introduction

In FastAPI, the request body is typically used to send data from a client to your API. It is often used for creating or updating resources. FastAPI automatically parses the request body based on the type hints you provide in your function parameters.

FastAPI uses Pydantic models to validate incoming data, ensuring that the request body matches the expected structure and data types. If the validation fails, FastAPI automatically returns a 422 Unprocessable Entity response detailing the validation errors. This greatly simplifies error handling and ensures that your function only processes valid data.


Request Body

Demo 1

Let's implement a simple example of how to define an endpoint that expects a request body in FastAPI:

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float
    is_offer: bool = None

app = FastAPI()

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

We first declare a data model as a class Item that inherits from BaseModel. You should note that the is_offer is an optional attribute which has a default value is None. The function create_item receive a JSON object from a client and then represented as a dict object in your program.

Since we used Python Type Hints and Pydantic models in the program, we already have data validation. If the data is invalid, the program will return a clear and informative error, indicating exactly where and what the incorrect data is.

To evaluate the program, we use Postman software and create a new POST request to the API endpoint at http://127.0.0.1:8000/items/, as shown in Fig. 1.

Demo 2

In this second demonstration program, we will modify the data received from a client and subsequently return the modified data to the client.

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float
    tax: float = 0.0  # Default value for tax

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    item_dict = item.model_dump()
    if item.tax:
        final_price = item.price + item.tax
        item_dict.update({"final_price": final_price})
    return item_dict

The method item.dict() in class BaseModel is deprecated, use item.model_dump() instead.

We also use Postman software to evaluate the program, as shown in Fig. 2.

We can further analyze the program's error scenarios, including cases where the tax is entered as a textual value or when required attributes are missing.

{
    "name": "beer",
    "price": 50000,
    "tax": "five thousand"
}

With the above request body, you will get the following error:

{
    "detail": [
        {
            "type": "float_parsing",
            "loc": [
                "body",
                "tax"
            ],
            "msg": "Input should be a valid number, unable to parse string as a number",
            "input": "five thousand",
            "url": "https://errors.pydantic.dev/2.6/v/float_parsing"
        }
    ]
}

However, you should note that the below request body is correct (tax value is represented as a string) :

{
    "name": "beer",
    "price": 50000,
    "tax": "5000"
}

Demo 3: A complex parameter

In this third demo, we combine all three request body, path parameter and query parameter.

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float
    tax: float = 0.0  # Default value for tax

app = FastAPI()

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, query: str = None):
    output = {"item_id": item_id, **item.model_dump()}
    if query:
        output.update({"query": query})
    return output

The method item.dict() in class BaseModel is deprecated, use item.model_dump() instead.

To evaluate the program, you should note that:

  • The update_item function now accepts a PUT method, instead of the POST method as in the previous two programs.

  • The item_id is a path parameter.

  • The query is a query parameter.

  • The name, tax, and price are attributes of a request body.

  • The URL to evaluate this API endpoint is http://127.0.0.1:8000/items/1001?query=update-item-price

Fig. 3 and Fig. 4 shows a demonstration of this API endpoint in Postman software.


Summary

FastAPI provides a powerful and intuitive way to handle request bodies through its seamless integration with Pydantic models. This combination not only ensures that your API endpoints can efficiently parse and validate incoming data but also significantly enhances the developer experience by reducing boilerplate code and automating documentation. By leveraging type hints and Pydantic models, developers can define clear, concise, and self-documenting APIs that enforce data integrity and provide meaningful error messages when data validation fails.

Last updated