pydantic

Pydantic v2 Framework Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "pydantic" with this command: npx skills add slanycukr/riot-api-project/slanycukr-riot-api-project-pydantic

Pydantic v2 Framework Skill

Pydantic is a data validation library that uses Python type annotations to define data schemas, offering fast and extensible validation with automatic type coercion.

Quick Start

Basic Model Definition

from pydantic import BaseModel from datetime import datetime from typing import Optional

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

Automatic type coercion

user = User( id='123', # String → int name='John Doe', email='john@example.com', signup_ts='2017-06-01 12:22' # String → datetime )

Validation from Data Sources

From dict

user = User.model_validate({'id': 1, 'name': 'Alice', 'email': 'alice@test.com'})

From JSON

user = User.model_validate_json('{"id": 1, "name": "Alice", "email": "alice@test.com"}')

Serialization

print(user.model_dump()) # Python dict print(user.model_dump_json()) # JSON string

Common Patterns

Field Configuration

from pydantic import BaseModel, Field, EmailStr, HttpUrl from typing import Annotated

class Product(BaseModel): product_id: int = Field(alias='id', ge=1, description='Unique product identifier') name: str = Field(min_length=1, max_length=200) price: float = Field(gt=0, le=1000000) email: EmailStr website: HttpUrl tags: list[str] = Field(default_factory=list, max_length=10) internal_code: str = Field(exclude=True, default='N/A')

class User(BaseModel): username: Annotated[str, Field(min_length=3, pattern=r'^[a-zA-Z0-9_]+$')] age: int = Field(ge=0, le=150)

Model Configuration

from pydantic import BaseModel, ConfigDict

class StrictModel(BaseModel): model_config = ConfigDict( strict=True, # No type coercion frozen=True, # Immutable instances validate_assignment=True, # Validate on attribute assignment extra='forbid', # Reject extra fields str_strip_whitespace=True, populate_by_name=True, # Accept both alias and field name use_enum_values=True, # Serialize enums as values )

id: int
name: str

Custom Validation

from pydantic import BaseModel, model_validator, field_validator, ValidationError from typing import Any

class DateRange(BaseModel): start_date: str end_date: str

@field_validator('start_date', 'end_date')
@classmethod
def validate_date_format(cls, v: str) -> str:
    # Custom validation logic
    if not v:
        raise ValueError('Date cannot be empty')
    return v

@model_validator(mode='after')
def check_dates_order(self) -> 'DateRange':
    # Cross-field validation
    if self.start_date > self.end_date:
        raise ValueError('start_date must be before end_date')
    return self

Using the model

try: date_range = DateRange(start_date='2024-01-01', end_date='2024-01-31') except ValidationError as e: for error in e.errors(): print(f"{error['loc']}: {error['msg']}")

Serialization Control

from pydantic import BaseModel, Field, SecretStr from datetime import datetime

class User(BaseModel): id: int username: str password: SecretStr created_at: datetime internal_data: dict = Field(exclude=True, default_factory=dict)

Serialization options

user = User( id=1, username='john', password='secret', created_at=datetime.now() )

Basic serialization

print(user.model_dump()) # Python dict print(user.model_dump_json()) # JSON string

Excluding fields

print(user.model_dump(exclude={'password'})) print(user.model_dump(exclude={'username', 'created_at'}))

Include only specific fields

print(user.model_dump(include={'id', 'username'}))

JSON-compatible serialization

print(user.model_dump(mode='json')) # datetime → string print(user.model_dump(by_alias=True)) # Use field aliases

Custom Serialization

from typing import Annotated, Any from pydantic import BaseModel, field_serializer, PlainSerializer

class Model(BaseModel): number: int created_at: datetime

@field_serializer('number')
def serialize_number(self, value: int) -> str:
    return f"{value:,}"  # Format with commas

# Using Annotated with PlainSerializer
custom_field: Annotated[
    float,
    PlainSerializer(lambda x: round(x, 2), return_type=float)
]

Nested Models and Relationships

from pydantic import BaseModel from typing import Optional, List

class Address(BaseModel): street: str city: str country: str = 'USA' zip_code: str

class User(BaseModel): id: int name: str addresses: List[Address] primary_address: Optional[Address] = None

Usage

user = User( id=1, name='John Doe', addresses=[ {'street': '123 Main St', 'city': 'New York', 'zip_code': '10001'}, {'street': '456 Oak Ave', 'city': 'Boston', 'zip_code': '02101'} ], primary_address={'street': '123 Main St', 'city': 'New York', 'zip_code': '10001'} )

Enum Integration

from enum import Enum, IntEnum from pydantic import BaseModel

class Status(str, Enum): PENDING = 'pending' ACTIVE = 'active' COMPLETED = 'completed'

class Priority(IntEnum): LOW = 1 MEDIUM = 2 HIGH = 3

class Task(BaseModel): title: str status: Status = Status.PENDING priority: Priority = Priority.MEDIUM

model_config = ConfigDict(use_enum_values=True)

Can use enum values or names

task1 = Task(title='Task 1', status='active', priority=3) task2 = Task(title='Task 2', status=Status.ACTIVE, priority=Priority.HIGH)

TypeAdapter for Standalone Validation

from pydantic import TypeAdapter from typing import List, Optional

Validate individual types without full models

int_adapter = TypeAdapter(int) print(int_adapter.validate_python('123')) # 123

list_adapter = TypeAdapter(List[int]) print(list_adapter.validate_python(['1', '2', '3'])) # [1, 2, 3]

Generate JSON schemas

print(int_adapter.json_schema()) print(list_adapter.json_schema())

Data Validation Patterns

from pydantic import BaseModel, ValidationError from typing import Union

class EmailValidator(BaseModel): email: str

@field_validator('email')
@classmethod
def validate_email(cls, v: str) -> str:
    if '@' not in v:
        raise ValueError('Invalid email format')
    return v.lower()

Validation error handling

try: user = User(id='invalid', name='', email='test') except ValidationError as e: print(f"Errors: {e.error_count()}") for error in e.errors(): print(f" {error['loc']}: {error['msg']} ({error['type']})")

Requirements

  • Python 3.8+

  • Pydantic v2.x: pip install pydantic

  • Optional dependencies for enhanced types:

  • pip install pydantic[email] for EmailStr

  • pip install pydantic[url] for HttpUrl

  • pip install pydantic[typing-extensions] for extended type support

Best Practices

  • Use specific types: Prefer conint(gt=0) over int for positive numbers

  • Configure models: Use ConfigDict to set global model behavior

  • Handle validation errors: Always wrap model creation in try/catch blocks

  • Use field validators: Implement custom validation logic with @field_validator

  • Control serialization: Use model_dump() parameters to control output format

  • Leverage type coercion: Pydantic automatically converts compatible types

  • Use nested models: Break complex data into smaller, reusable models

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

axios

No summary provided by upstream source.

Repository SourceNeeds Review
General

radix-ui

No summary provided by upstream source.

Repository SourceNeeds Review
General

httpx

No summary provided by upstream source.

Repository SourceNeeds Review
General

structlog

No summary provided by upstream source.

Repository SourceNeeds Review