FastAPIInteractive

Lesson 1 of 6 ยท Build a Blog API with Authentication

Data Models Deep Dive

Master Pydantic models for data validation and serialization. Create complex nested schemas for users, blog posts, and API responses.

Open this lesson in the editor โ†’

What you'll learn

  • Understand Pydantic BaseModel fundamentals
  • Create nested data models with relationships
  • Implement custom validators and field constraints
  • Design request/response schemas for a blog API

Data Models Deep Dive

Welcome to the Blog API tutorial! In this lesson, you'll master Pydantic models - the foundation of data validation and serialization in FastAPI.

๐ŸŽฏ What We're Building

You're creating the data backbone for a Blog API with Authentication that includes:

  • ๐Ÿ‘ค User management with roles and permissions
  • ๐Ÿ“ Blog posts with rich metadata
  • ๐Ÿ” Authentication schemas for secure access
  • ๐Ÿ“Š Nested responses with related data

๐Ÿ› ๏ธ Pydantic Fundamentals

Pydantic is Python's most powerful data validation library that provides:

  • Automatic validation based on Python type hints
  • JSON serialization/deserialization
  • Custom validators for complex business rules
  • Clear error messages when validation fails
  • IDE support with autocomplete and type checking

๐Ÿ—๏ธ Basic Model Structure

1. Simple Model

from pydantic import BaseModel

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

2. Optional Fields and Defaults

from typing import Optional

class User(BaseModel):
    name: str
    email: str
    age: Optional[int] = None
    is_active: bool = True

3. Field Constraints

from pydantic import BaseModel, Field

class User(BaseModel):
    username: str = Field(..., min_length=3, max_length=20)
    email: str = Field(..., pattern=r'^[^@]+@[^@]+\.[^@]+$')
    age: int = Field(..., ge=0, le=120)  # ge = greater equal, le = less equal

๐Ÿ”ง Advanced Validation

Custom Validators

from pydantic import BaseModel, validator
import re

class User(BaseModel):
    username: str
    password: str
    
    @validator('password')
    def validate_password(cls, v):
        if len(v) < 8:
            raise ValueError('Password must be at least 8 characters')
        if not re.search(r'\d', v):
            raise ValueError('Password must contain a number')
        return v

Enums for Controlled Values

from enum import Enum
from pydantic import BaseModel

class UserRole(str, Enum):
    ADMIN = "admin"
    AUTHOR = "author"
    READER = "reader"

class User(BaseModel):
    role: UserRole = UserRole.READER

๐Ÿ”— Nested Models and Relationships

Creating Nested Structures

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

class BlogPost(BaseModel):
    title: str
    content: str
    author: Author  # Nested model

Inheritance for Similar Models

class UserBase(BaseModel):
    username: str
    email: str

class UserCreate(UserBase):
    password: str

class UserResponse(UserBase):
    id: int
    created_at: datetime

๐Ÿ“ Your Task Breakdown

1. UserRole Enum

Create roles for your blog platform:

  • ADMIN: Full system access
  • AUTHOR: Can create/edit posts
  • READER: Read-only access

2. User Model

Design a comprehensive user model with:

  • Validation: Username format, email validation
  • Roles: Default to READER
  • Timestamps: Track creation time
  • Status: Active/inactive users

3. BlogPost Model

Create a rich blog post model with:

  • Content validation: Minimum content length
  • Tags system: Limited number and size
  • Publishing status: Draft vs published
  • Relationships: Link to author

4. Request/Response Schemas

Design specialized schemas for:

  • UserCreate: Registration data with password
  • BlogPostResponse: Post data with nested author info

๐Ÿ’ก Pro Tips

Field Documentation

class User(BaseModel):
    username: str = Field(..., description="Unique username for the user")
    
    class Config:
        schema_extra = {
            "example": {
                "username": "john_doe",
                "email": "john@example.com"
            }
        }

Date Handling

from datetime import datetime
from pydantic import BaseModel

class Post(BaseModel):
    created_at: datetime
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }

Validation Order

Pydantic validates fields in this order:

  1. Type validation (str, int, etc.)
  2. Field constraints (min_length, etc.)
  3. Custom validators (@validator decorated methods)

๐ŸŽ What You Get

When you complete this lesson, you'll have:

  • โœ… Type-safe models with automatic validation
  • โœ… Clear API documentation (auto-generated from models)
  • โœ… Robust error handling with detailed messages
  • โœ… IDE support with autocomplete and type hints
  • โœ… JSON serialization that "just works"

๐Ÿš€ Next Steps

After mastering these data models, you'll use them to:

  • Connect to databases with SQLAlchemy
  • Handle authentication with JWT tokens
  • Create API endpoints with automatic validation
  • Upload files with proper validation

Ready to build bulletproof data models? Let's code! ๐Ÿ”ง

Hint

Start with the UserRole enum using string values. For User model, use Field() for validation constraints. Remember that Pydantic validators use @validator decorator and class methods.

Now write it

The editor runs a real FastAPI server and grades your code against this lesson's own endpoints.

Start Data Models Deep Dive