CS504070 - FastAPI Tutorials
  • 🧩CS504070 - FastAPI Tutorials
  • 🔎Unit 1: Python Type Hint
  • ⚙️Unit 2: Pydantic
  • 🔃Unit 3: Concurrency
  • 💾Unit 4: Install FastAPI
  • 🍉Unit 5: Hello World!
  • 🍌Unit 6: Path Parameters
  • 🍋Unit 7: Query Parameters
  • 🍊Unit 8: Request Body
  • 🍐Unit 9: Query Parameters and Validations
  • 🍎Unit 10: Path Parameters and Validations
  • 🍏Unit 11: Multiple Parameters
  • 🍇Unit 12: Request Body - List Fields and Nested Models
  • 🍓Unit 13: Data Types
  • 🍪Unit 14: Cookie Parameters
  • 🫐Unit 15: Header Parameters
  • 🍈Unit 16: Response Model - Return Type
  • 🍒Unit 17: Additional Models
  • 🥑Unit 18: Implementing JWT Authentication with FastAPI
  • ⚙️Appendix A
  • 🍭Appendix B
Powered by GitBook
On this page
  • Introduction
  • List fields
  • Nested models
  • Example program
  • Summary

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 results

You should note that the above program is implemented in Python 3.12. If you are using Python before version 3.9, the List declaration is as follows:

from typing import List

my_list: List[str]

To 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"]
}

In Python, a list allows duplicate elements and maintains their order, while a set ensures element uniqueness without any guaranteed order.

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 results

The 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 Item with fields name, description, price, and tax.

  • We then define another Pydantic model Order that contains a list of Item objects along with customer_name and shipping_address.

  • In the route /order/, we accept POST requests with a request body of type Order.

  • When a request is made to /order/, FastAPI automatically validates the request body against the Order model and gives you an instance of Order in the route function create_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.

PreviousUnit 11: Multiple ParametersNextUnit 13: Data Types

Last updated 1 year ago

🍇
Page cover image
Fig. 1. Example of a quest in Postman
Fig. 2. Example of a quest in Postman