πUnit 12: Request Body - List Fields and Nested Models
Introduction
In FastAPI, you can define request bodies with complex structures using Pydantic models. These can include fields and nested models. In the following sections, this unit will show how to implement list fields and nested models.
List fields
Let's take a look at the following program:
# Note: This program is implemented in Python 3.12
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: list[str] = []
@app.post("/update-item/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item, "message": "Item updated successfully"}
return resultsTo evaluate the program, you can compose a request in Postman as shown in Fig. 1. The request body can be as follows:
{
"name": "Green Apple",
"description": "A type of fruit",
"price": 50000,
"tax": 2500,
"tags": ["fruit", "apple"]
}
Nested models
In the following program, we define two classes, i.e., Image and Item, and they have a HAS-A relationship. In Image class, the metadata is declared as a list of dictionary (key-value pairs).
# Note: This program is implemented in Python 3.12
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
metadata: list[dict[str, str]]
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
tags: list[str] = []
image: Image = None
@app.post("/update-item/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item, "message": "Item updated successfully"}
return resultsThe request body to evaluate the above program is as follows. You should note how we compose the metadata values. Fig. 2 shows the results when evaluating the program in Postman.
{
"name": "Green Apple",
"description": "A type of fruit",
"price": 50000,
"tax": 2500,
"tags": [
"fruit",
"apple"
],
"image": {
"url": "example.com",
"metadata": [
{
"File type": "JPEG",
"MIME type": "image/jpeg"
}
]
}
}
Example program
In this example:
We define a Pydantic model
Itemwith fieldsname,description,price, andtax.We then define another Pydantic model
Orderthat contains a list ofItemobjects along withcustomer_nameandshipping_address.In the route
/order/, we accept POST requests with a request body of typeOrder.When a request is made to
/order/, FastAPI automatically validates the request body against theOrdermodel and gives you an instance ofOrderin the route functioncreate_order.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
class Order(BaseModel):
items: list[Item]
customer_name: str
shipping_address: str
@app.post("/order/")
async def create_order(order: Order):
return {"order_details": order}Summary
In this unit, we have introduced how to enhance request body in FastAPI to allow the server program to capture more complex inputs using list fields and nested models in combination with Pydantic model.
Last updated