Pydantic v2 Guide — Data Validation, Models, and Settings Management

Master Pydantic v2 for data validation, settings management with BaseSettings, custom validators, and model configuration.

Overview

Master Pydantic v2 for data validation, settings management with BaseSettings, custom validators, and model configuration. This guide covers the essential concepts, practical examples, and production-ready patterns you need to get started.

Getting Started

Before diving in, make sure you have the necessary prerequisites installed. This guide assumes basic familiarity with the underlying technology stack.

Core Concepts

Understanding the fundamentals is essential before applying advanced patterns. The following sections break down the key ideas with working code examples.

Best Practices

  • Start simple and add complexity only when needed
  • Write tests alongside your implementation
  • Document decisions that aren't obvious from the code
  • Monitor in production with appropriate logging and metrics

Common Pitfalls

Developers commonly run into a few specific issues when first implementing these patterns. Understanding them upfront saves significant debugging time later.

Production Checklist

  • Error handling and graceful degradation
  • Logging and observability
  • Performance testing under realistic load
  • Security review

What is Pydantic?

Pydantic is a Python library for data validation and settings management using Python type annotations. It's widely used in FastAPI, data pipelines, and anywhere you need reliable data structures.

Basic Models

from pydantic import BaseModel, EmailStr, Field
from datetime import datetime

class User(BaseModel):
    id: int
    name: str = Field(..., min_length=1, max_length=100)
    email: EmailStr
    created_at: datetime = Field(default_factory=datetime.utcnow)
    is_active: bool = True

# Create instance with validation
user = User(id=1, name="John", email="[email protected]")
print(user.dict())  # Convert to dict

Validators

from pydantic import validator, field_validator

class Product(BaseModel):
    name: str
    price: float
    discount: float = 0
    
    @field_validator('price')
    @classmethod
    def price_must_be_positive(cls, v):
        if v <= 0:
            raise ValueError('Price must be positive')
        return v
    
    @field_validator('discount')
    @classmethod
    def discount_must_be_valid(cls, v):
        if not 0 <= v <= 100:
            raise ValueError('Discount must be 0-100')
        return v

Settings Management

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    app_name: str = "MyApp"
    database_url: str
    secret_key: str
    debug: bool = False
    
    class Config:
        env_file = ".env"

settings = Settings()

Pydantic V2 Changes

# V2 uses field_validator instead of validator
from pydantic import field_validator, model_validator

class Order(BaseModel):
    items: list[str]
    total: float
    
    @model_validator(mode='after')
    def check_total(self):
        if self.total < 0:
            raise ValueError('Total cannot be negative')
        return self

Best Practices

  • Use Field for constraints: min_length, max_length, gt, lt, pattern
  • Leverage model_config: Configure validation behavior centrally
  • Use model_validator for cross-field validation: Validate multiple fields together
  • Generate schemas: Use model_json_schema() for API docs
→ Explore DevKits Free Developer Tools
aiforeverthing.com — Python tools, JSON validators, and more

Frequently Asked Questions

What's the difference between Pydantic V1 and V2?

V2 is faster (Rust core), uses field_validator instead of validator, and has improved error handling.

How do I handle nested models?

Just use Pydantic models as field types. Pydantic automatically validates nested structures.

Can I use Pydantic with dataclasses?

Yes! Use @pydantic.dataclasses.dataclass for type-safe dataclasses with validation.

→ Explore DevKits Free Developer Tools
aiforeverthing.com — No signup, runs in your browser