Skip to content

FastAPI

Basic Types

FastAPI supports basic Python types such as int, float, str, bool, and None. These types can be used to define API endpoints with simple data types.

  • int type for integer values
  • float type for floating-point values
  • str type for string values
  • bool type for boolean values
  • None type for null values
stock_id: int = 1027
stock_name: str = "HDFCBANK"
stock_price: float = 1645.45
stock_is_active: bool = True
stock_description: str | None = None


print(stock_id)  # 1027
print(stock_name)  # HDFCBANK
print(stock_price)  # 1645.45
print(stock_is_active)  # True
print(stock_description)  # None

Complex Types

FastAPI also supports complex Python types such as list, tuple, dict, and set. These types can be used to define API endpoints with complex data structures.

  • list type for collections of values
  • tuple type for immutable collections of values
  • dict type for key-value pairs
  • set type for unordered collections of unique values
item_list: list[str] = ['HINDMOTORS', 'HFCL', 'HDFCBANK']

item_dict: dict[str, int] = {'HINDMOTORS': 1, 'HFCL': 2, 'HDFCBANK': 3}

item_set: set[str] = {'HINDMOTORS', 'HFCL', 'HDFCBANK'}

item_tuple: tuple[str, int, float] = ('HDFCBANK', 1, 1645.45)


print(item_list[0])  # HINDMOTORS
print(item_dict['HFCL'])  # 2
print(item_tuple[0])  # HDFCBANK
print(item_list.pop())  # HDFCBANK

Type Conversion

FastAPI can automatically convert input data to the expected type. If the input data cannot be converted, an error is raised.

  • Convert input data to expected type
  • Raise error if input data cannot be converted
from pydantic import BaseModel

# Define a Pydantic model with type conversion
class Stock(BaseModel):
    id: int
    name: str
    price: float


def create_item(id: str, name: str, price: str):
    # Attempt to convert the input types to the expected types
    stock_id = int(id)
    stock_price = float(price)

    # Create an instance of the Stock model with the converted types
    stock = Stock(id=stock_id, name=name, price=stock_price)

    print(stock)  # Output: id=1027 name='HDFCBANK' price=1645.45


create_item(id='1027', name='HDFCBANK', price='1645.45')


def create_item_auto(stock: Stock):
    # Pydantic will automatically convert the input types to the expected types
    return stock


stock = {'id': '1027', 'name': 'HDFCBANK', 'price': '1645.45'}
create_item_auto(stock)  # Output: Stock id=1027 name='HDFCBANK' price=1645.45

Type Validation

FastAPI can validate the types of input data for API endpoints. If the input data does not conform to the expected type, an error is raised.

  • Validate types of input data for API endpoints
  • Raise error if input data does not conform to expected type

Define a Pydantic model with type validation

from fastapi import HTTPException
from pydantic import BaseModel, field_validator

class Stock(BaseModel):
    id: int
    name: str
    price: float

    @field_validator("id")
    def id_must_be_positive(cls, v):
        if v <= 0:
            raise ValueError("ID must be a positive integer")
        return v

    @field_validator("name")
    def name_must_be_at_least_3_chars(cls, v):
        if len(v) < 3:
            raise ValueError("Name must be at least 3 characters")
        return v

    @field_validator("price")
    def price_must_be_non_negative(cls, v):
        if v < 0:
            raise ValueError("Price must be a non-negative number")
        return v

Define an function with type validation

def create_item(item: Stock):
    return item


pydantic_validation = create_item(Stock(id=1027, name="HD", price=1645.45))
print(pydantic_validation)  # Value error, Name must be at least 3 characters

Define an function with manual type validation

def create_item_manual(id: int, name: str, price: float):
    if id <= 0:
        raise HTTPException(
            status_code=400, detail="ID must be a positive integer")
    if len(name) < 3:
        raise HTTPException(
            status_code=400, detail="Name must be at least 3 characters")
    if price < 0:
        raise HTTPException(
            status_code=400, detail="Price must be a non-negative number")
    return {"id": id, "name": name, "price": price}


manual_validation = create_item_manual(1027, "HD", 1645.45)
print(manual_validation)  # Value error, Name must be at least 3 characters

Pydantic Models

FastAPI supports the use of Pydantic models to define the structure of input data. Pydantic models provide automatic validation and conversion of input data.

  • Define structure of input data using Pydantic models
  • Automatic validation and conversion of input data
from pydantic import BaseModel, Field
from datetime import datetime
from typing import List, Optional

Define a simple Pydantic model

class User(BaseModel):
    id: int
    name: str
    email: str

Define a Pydantic model with optional fields

class Product(BaseModel):
    id: int
    name: str
    description: Optional[str] = None
    price: float

Define a Pydantic model with a list of items

class Order(BaseModel):
    id: int
    user_id: int
    products: List[Product]

Define a Pydantic model with a nested model

class Address(BaseModel):
    street: str
    city: str
    state: str
    zip: str

class Customer(BaseModel):
    id: int
    name: str
    email: str
    address: Address

Define a Pydantic model with validation

class Item(BaseModel):
    id: int
    name: str
    price: float

    class Config:
        min_anystr_length = 1
        max_anystr_length = 100

Define a Pydantic model with validation

class Item(BaseModel):
    id: int
    name: str
    price: float

    class Config:
        min_anystr_length = 1
        max_anystr_length = 100

Define a Pydantic model with custom field validation

class Password(BaseModel):
    password: str

    @Field(..., min_length=8, max_length=128)
    def password_validation(self, value: str):
        if not any(char.isdigit() for char in value):
            raise ValueError("Password must contain at least one digit")
        return value

Define a Pydantic model with datetime field

class Event(BaseModel):
    id: int
    name: str
    start_date: datetime
    end_date: datetime

Example usage:

user = User(id=1, name="John Doe", email="john@example.com")
print(user)

product = Product(id=1, name="Product A", price=10.99)
print(product)

order = Order(id=1, user_id=1, products=[product])
print(order)

customer = Customer(id=1, name="John Doe", email="john@example.com",
                    address=Address(street="123 Main St", city="Anytown", state="CA", zip="12345"))
print(customer)

item = Item(id=1, name="Item A", price=10.99)
print(item)

password = Password(password="mysecretpassword123")
print(password)

event = Event(id=1, name="Event A", start_date=datetime(
    2024, 9, 16), end_date=datetime(2024, 9, 17))
print(event)

Benefits of Using Python Types in FastAPI

Using Python types in FastAPI provides several benefits, including improved code readability and maintainability, automatic validation and conversion of input data, and reduced risk of errors and bugs.

  • Improved code readability and maintainability
  • Automatic validation and conversion of input data
  • Reduced risk of errors and bugs

Conclusion

  • Summary: FastAPI supports basic and complex Python types, as well as Pydantic models for defining the structure of input data.

In conclusion, FastAPI provides robust support for Python types, making it an ideal choice for building robust and maintainable APIs.