Pydantic Professional Development
Comprehensive guidance for building production-ready applications with Pydantic v2.12, the most widely used data validation library for Python.
Quick Reference
Installation: See references/install.md for setup instructions and optional dependencies
Core Philosophy: See references/why.md for Pydantic's design principles and when to use it
Migration from v1: See references/migration.md for upgrading from Pydantic v1.x
Core Concepts
Pydantic uses Python type hints to define data schemas and performs validation/coercion automatically. The fundamental building blocks are:
Models
Primary documentation: references/concepts/models.md
Define data structures by inheriting from BaseModel :
from pydantic import BaseModel, Field
class User(BaseModel): id: int name: str = Field(min_length=1, max_length=100) email: str age: int | None = None
Key concepts:
-
Basic model usage and instantiation
-
Data conversion and coercion
-
Nested models and relationships
-
Model methods: model_validate() , model_dump() , model_dump_json()
-
Generic models and dynamic creation
-
Immutability with frozen=True
API reference: references/api/base_model/BaseModel.md
- Complete BaseModel class documentation
Fields
Primary documentation: references/concepts/fields.md
Customize field behavior with constraints, defaults, and metadata:
from pydantic import BaseModel, Field from typing import Annotated
class Product(BaseModel): name: str = Field(description="Product name") price: Annotated[float, Field(gt=0, description="Price in USD")] quantity: int = Field(default=0, ge=0)
Key concepts:
-
Field constraints (gt, ge, lt, le, min_length, max_length, pattern)
-
Default values and factories
-
Aliases and validation aliases
-
Required vs optional fields
-
Computed fields with @computed_field
API reference: references/api/fields/
- Field, FieldInfo, and computed field APIs
Validators
Primary documentation: references/concepts/validators.md
Implement custom validation logic with field and model validators:
from pydantic import BaseModel, field_validator, model_validator
class Account(BaseModel): username: str password: str password_confirm: str
@field_validator('username')
@classmethod
def username_alphanumeric(cls, v):
assert v.isalnum(), 'must be alphanumeric'
return v
@model_validator(mode='after')
def check_passwords_match(self):
if self.password != self.password_confirm:
raise ValueError('passwords do not match')
return self
Validator types:
-
After validators: Run after Pydantic validation (type-safe, recommended)
-
Before validators: Run before validation (for data preprocessing)
-
Wrap validators: Full control over validation process
-
Plain validators: Replace default validation entirely
API reference: references/api/functional_validators/
- All validator APIs and decorators
Types
Primary documentation: references/concepts/types.md
Pydantic supports all Python types plus specialized validation types:
Standard types: int , float , str , bool , list , dict , set , tuple , datetime , date , time , UUID , etc.
Pydantic types: See references/api/types/ for specialized types:
-
Constrained types: conint() , constr() , confloat() , etc.
-
Network types: EmailStr , AnyUrl , IPvAnyAddress
-
Datetime types: AwareDatetime , NaiveDatetime , FutureDate , PastDate
-
Special types: Json , SecretStr , PaymentCardNumber , FilePath , DirectoryPath
Type documentation: references/concepts/types.md covers all supported types and patterns
Configuration
Primary documentation: references/concepts/config.md
Control model behavior with ConfigDict :
from pydantic import BaseModel, ConfigDict
class User(BaseModel): model_config = ConfigDict( str_strip_whitespace=True, validate_assignment=True, frozen=False, extra='forbid' )
Common settings:
-
extra : 'forbid' | 'allow' | 'ignore' - Handle extra fields
-
validate_assignment : Validate on attribute assignment
-
frozen : Make instances immutable
-
str_strip_whitespace : Strip whitespace from strings
-
from_attributes : Enable ORM mode for SQLAlchemy, etc.
-
populate_by_name : Allow population by field name and alias
API reference: references/api/config/ConfigDict.md
Common Workflows
Validation Workflows
Parse untrusted data:
user = User.model_validate(data) # Raises ValidationError if invalid
Parse JSON:
user = User.model_validate_json(json_string)
Create without validation:
user = User.model_construct(**trusted_data) # Skip validation for performance
Handle validation errors: See references/errors/validation_errors.md
Serialization Workflows
Primary documentation: references/concepts/serialization.md
Export to dict:
user_dict = user.model_dump() user_dict = user.model_dump(exclude={'password'}) user_dict = user.model_dump(by_alias=True)
Export to JSON:
json_str = user.model_dump_json() json_str = user.model_dump_json(indent=2, exclude_none=True)
Custom serializers: See references/api/functional_serializers/
JSON Schema Generation
Primary documentation: references/concepts/json_schema.md
Generate schema:
schema = User.model_json_schema() schema = User.model_json_schema(by_alias=True, mode='serialization')
Customize schema generation: See references/api/json_schema/GenerateJsonSchema.md
Settings Management
Primary documentation: references/concepts/pydantic_settings.md
For application configuration from environment variables:
from pydantic_settings import BaseSettings
class Settings(BaseSettings): database_url: str api_key: str debug: bool = False
model_config = ConfigDict(env_file='.env')
settings = Settings()
API reference: references/api/pydantic_settings/
Working with ORMs
Primary documentation: references/examples/orms.md
Pydantic integrates with SQLAlchemy, Django, and other ORMs:
from pydantic import BaseModel, ConfigDict
class UserModel(BaseModel): model_config = ConfigDict(from_attributes=True)
id: int
name: str
Convert ORM instance to Pydantic model
user = UserModel.model_validate(sql_user)
Advanced Features
Dataclasses
Primary documentation: references/concepts/dataclasses.md
Use Pydantic with Python dataclasses:
from pydantic.dataclasses import dataclass
@dataclass class User: id: int name: str
API reference: references/api/dataclasses/
Type Adapter
Primary documentation: references/concepts/type_adapter.md
Validate data against any type, not just models:
from pydantic import TypeAdapter
ListOfInts = TypeAdapter(list[int]) validated = ListOfInts.validate_python(['1', '2', '3'])
API reference: references/api/type_adapter/TypeAdapter.md
Unions and Discriminated Unions
Primary documentation: references/concepts/unions.md
Handle multiple possible types:
from typing import Literal, Union from pydantic import BaseModel, Field
class Cat(BaseModel): pet_type: Literal['cat'] meows: int
class Dog(BaseModel): pet_type: Literal['dog'] barks: float
class Owner(BaseModel): pet: Union[Cat, Dog] = Field(discriminator='pet_type')
Aliases
Primary documentation: references/concepts/alias.md
Map field names for validation and serialization:
from pydantic import BaseModel, Field
class User(BaseModel): username: str = Field(alias='userName')
API reference: references/api/aliases/
Strict Mode
Primary documentation: references/concepts/strict_mode.md
Enforce strict type validation without coercion:
from pydantic import BaseModel, ConfigDict
class StrictModel(BaseModel): model_config = ConfigDict(strict=True)
count: int # Won't accept '123', only 123
Performance Optimization
Primary documentation: references/concepts/performance.md
Guidelines for optimizing Pydantic performance in production
Error Handling
Validation Errors
Complete reference: references/errors/validation_errors.md
Understand and handle validation errors:
from pydantic import ValidationError
try: user = User(**data) except ValidationError as e: print(e.errors()) # List of error dictionaries print(e.json()) # JSON formatted errors
Error types reference: references/errors/errors.md
- All validation error codes
Usage Errors
Reference: references/errors/usage_errors.md
Common mistakes and how to fix them
API Reference
Complete API documentation organized by module:
-
references/api/base_model/
-
BaseModel class and create_model()
-
references/api/fields/
-
Field(), FieldInfo, computed fields, private attributes
-
references/api/config/
-
ConfigDict and configuration options
-
references/api/types/
-
All Pydantic types (constrained types, network types, etc.)
-
references/api/functional_validators/
-
Validator decorators and classes
-
references/api/functional_serializers/
-
Serializer decorators and classes
-
references/api/json_schema/
-
JSON schema generation APIs
-
references/api/dataclasses/
-
Pydantic dataclass support
-
references/api/type_adapter/
-
TypeAdapter for validating any type
-
references/api/errors/
-
Error classes
-
references/api/networks/
-
Network validation types (URLs, emails, IPs)
-
references/api/aliases/
-
Alias configuration classes
-
references/api/validate_call/
-
Function validation decorator
-
references/api/version/
-
Version information
Examples
Practical examples for common use cases:
-
references/examples/custom_validators.md
-
Building custom validators
-
references/examples/orms.md
-
Integration with SQLAlchemy and Django
-
references/examples/files.md
-
Validating file data (JSON, CSV, etc.)
-
references/examples/requests.md
-
Validating API requests and responses
-
references/examples/queues.md
-
Using Pydantic with message queues
-
references/examples/dynamic_models.md
-
Creating models at runtime
Development Guidelines
Code Quality
Linting integration: references/integrations/linting.md
- Configure ruff, mypy, and other linters
Best practices:
-
Always type annotate fields explicitly
-
Use Field() for constraints and metadata
-
Prefer after validators over before validators
-
Use discriminated unions for type safety
-
Enable validate_assignment for mutable models
-
Use frozen=True for immutable data
-
Configure extra='forbid' to catch typos
Production Readiness
Required considerations:
-
Error handling: Always catch and handle ValidationError
-
Performance: Use model_construct() for trusted data
-
Security: Validate all external inputs
-
Serialization: Test model_dump() output matches expectations
-
Schema validation: Generate and validate JSON schemas for APIs
-
Migration: Follow references/migration.md when upgrading
Testing
Validate your models:
def test_user_validation(): # Test valid data user = User(id=1, name="Test", email="test@example.com") assert user.id == 1
# Test invalid data
with pytest.raises(ValidationError):
User(id="invalid", name="Test")
Getting Help
-
Overview: references/index.md
-
Introduction to Pydantic
-
Help resources: references/help_with_pydantic.md
-
Community support
-
Version policy: references/version-policy.md
-
Versioning and deprecation
-
Contributing: references/contributing.md
-
How to contribute to Pydantic
Version Information
This skill covers Pydantic v2.12.5 (December 2025). For migration from v1.x, see references/migration.md .