Pydantic Models: The Engine of FastAPI

Pydantic Models: The Engine of FastAPI

Master the core of data validation. Learn how Pydantic models enforce types, provide defaults, and handle complex data structures with ease.

Pydantic Models: The Engine of FastAPI

In the previous module, we touched on request bodies. Now, we dive deep into the library that makes it all work: Pydantic.

Pydantic is data validation and settings management using Python type annotations. It is not a FastAPI feature—it is a standalone library that FastAPI uses as its data engine.


1. What is a Pydantic Model?

A Pydantic model is a class that inherits from BaseModel. Its job is to define the "Shape" and "Type" of your data.

from pydantic import BaseModel

class User(BaseModel):
    id: int
    username: str
    is_premium: bool = False

What happens when you create an instance?

# This works
user = User(id=1, username="shshell")

# This crashes with a ValidationError!
user = User(id="not-an-int", username="shshell")

2. Advanced Field Validation

Pydantic isn't just for types. You can use the Field function to add complex constraints.

from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(..., example="Wireless Mouse")
    price: float = Field(..., gt=0, description="The price must be greater than zero")
    sku: str = Field(..., pattern="^[A-Z]{3}-\d{3}$")  # Regex for ABC-123
  • ...: This means the field is required.
  • gt=0: Greater Than 0.
  • pattern: Regex validation.

3. Data Conversion (Coercion)

Pydantic is "strict but helpful." It will try to convert data to the right type if it can.

InputTarget TypeResult
"1"int1 (Success)
"true"boolTrue (Success)
1.5int1 (Success, truncated)
"abc"intValidationError

4. Why Pydantic v2?

FastAPI now supports Pydantic v2, which was rewritten in Rust. This makes data validation up to 20x faster than v1. For high-traffic APIs, this move to Rust significantly lowers CPU usage and latency.


Visualizing Validation

graph TD
    A["Raw Data (JSON/Dict)"] --> B["Pydantic Model"]
    B --> C{Validation Loop}
    C -- "Type mismatch?" --> D["Coerce/Convert"]
    D -- "Success" --> E["Check Constraints (gt, min_length)"]
    D -- "Failure" --> F["Raise ValidationError"]
    E -- "Success" --> G["Return Python Object"]
    E -- "Failure" --> F

Summary

  • BaseModel is the foundation of your API data structures.
  • Field allows for fine-grained validation (Regex, numeric bounds).
  • Coercion handles the messy nature of web data automatically.
  • Performance: Pydantic v2 (Rust-powered) makes FastAPI incredibly efficient.

In the next lesson, we focus on Input Validation and how to write custom check logic for your models.


Exercise: The Constraint Ninja

Design a model for a BankAccount.

  1. It must have an account_number that is exactly 10 characters long.
  2. It must have a balance that can never be less than -500 (overdraft limit).
  3. It must have a currency code that is exactly 3 uppercase letters (e.g., "USD").

Subscribe to our newsletter

Get the latest posts delivered right to your inbox.

Subscribe on LinkedIn