pydantic-v2
Pydantic v2 patterns for production Python: validators (`@field_validator`, `@model_validator`), computed fields, strict types, discriminated unions, settings management, `model_validate` / `model_dump`, `condecimal` and `Annotated[Decimal, ...]` for money, performance tips, and a v1 to v2 migration checklist. Also covers FastAPI integration (response_model serialization, request validation, error envelope customization). TRIGGER WHEN: writing or refactoring Pydantic models in Python 3.10+; migrating a codebase from Pydantic v1 to v2; choosing between `Annotated[Decimal, ...]` vs `condecimal`; hitting v2 performance or serialization surprises; designing FastAPI request/response schemas or error envelopes with Pydantic. DO NOT TRIGGER WHEN: the task is Python testing (use python-tdd), generic typing unrelated to Pydantic (use mypy / typing docs), or non-Python schema work (use typescript-development for Zod / io-ts).
What this skill does
# Pydantic v2
Pydantic v2 (released 2023-06, current stable **2.13** as of 2026-04-19, paired with Python 3.10-3.14 including 3.14 free-threaded builds) is a near-complete rewrite on `pydantic-core` (Rust). API is similar but not identical to v1 -- several v1 patterns silently break or behave differently. This skill documents the v2 idioms, the v1 migration gotchas, and the FastAPI integration surface.
Notable recent releases:
- **2.11** (2025): 2x schema build-time improvements, 2-5x memory reduction for nested models, PEP 695/696 generic syntax, experimental free-threaded Python 3.13, `validate_by_alias` / `validate_by_name` / `serialize_by_alias` config (`populate_by_name` pending v3 deprecation), `Path` and `deque` no longer accept constraints ([2.11 release](https://pydantic.dev/articles/pydantic-v2-11-release)).
- **2.12**: Python 3.14 support (PEP 649/749 annotations), experimental `MISSING` sentinel, `exclude_if` on fields, `ensure_ascii` on JSON output, `serialize_as_any` unified behavior, `@model_validator(mode="after")` classmethod deprecated -- write as instance method ([2.12 release](https://pydantic.dev/articles/pydantic-v2-12-release)).
- **2.13** (April 2026): **Polymorphic serialization** (`model_dump(polymorphic_serialization=True)`), `exclude_if` extended to computed fields, `ascii_only` in `StringConstraints`, `model_fields_set` tracks post-instantiation extras ([2.13 release](https://pydantic.dev/articles/pydantic-v2-13-release)).
## When to load which section
- Writing a new model from scratch -> "Core model patterns" + "Validators"
- Migrating from v1 -> "v1 -> v2 migration checklist"
- Working with money / decimals -> "Monetary precision (CWE-681 defense)"
- FastAPI request/response models -> "FastAPI integration"
- Performance-sensitive hot path -> "Performance notes"
- Secret handling / redaction -> "Security and secrets"
- Validation observability or LLM agents -> "PydanticAI and Logfire"
## Core model patterns
```python
from datetime import datetime
from decimal import Decimal
from typing import Annotated, Literal
from pydantic import (
BaseModel,
ConfigDict,
Field,
StringConstraints,
computed_field,
field_validator,
model_validator,
)
# Type aliases with constraints -- preferred in v2 over `constr()` / `conint()`
NonEmptyStr = Annotated[str, StringConstraints(min_length=1, strip_whitespace=True)]
USDAmount = Annotated[Decimal, Field(max_digits=14, decimal_places=2, ge=0)]
class LineItem(BaseModel):
# model_config replaces inner `Config` class
model_config = ConfigDict(
strict=True, # refuse string "1" for int field
frozen=True, # hashable + immutable
populate_by_name=True, # accept alias AND field name
str_strip_whitespace=True, # strip on all str fields
extra="forbid", # reject unknown keys
)
sku: NonEmptyStr
quantity: int = Field(ge=1)
unit_price: USDAmount
currency: Literal["USD", "EUR", "GBP"] = "USD"
@computed_field
@property
def total(self) -> USDAmount:
return self.unit_price * self.quantity
@field_validator("sku")
@classmethod
def sku_format(cls, v: str) -> str:
if not v.isalnum():
raise ValueError("sku must be alphanumeric")
return v.upper()
@model_validator(mode="after")
def cross_field_check(self) -> "LineItem":
if self.currency == "USD" and self.unit_price > Decimal("10000"):
raise ValueError("USD line item exceeds single-item limit")
return self
```
### Key points
- `model_config = ConfigDict(...)` replaces the v1 inner `class Config:` pattern. Importing `ConfigDict` gives you autocomplete.
- `Annotated[T, Field(...)]` or `Annotated[T, StringConstraints(...)]` is the idiomatic v2 way to attach constraints -- prefer over `constr()`, `conint()`, `condecimal()` wrappers (still supported, but Annotated composes better with Python's type system).
- `@computed_field` replaces the v1 `@property` + `validator(always=True)` dance; shows up in `model_dump()` automatically.
- `@field_validator("field_name")` replaces v1 `@validator("field_name")`. Decorator is classmethod; must have `@classmethod` decorator after `@field_validator`.
- `@model_validator(mode="before" | "after")` replaces v1 `@root_validator(pre=True | False)`. In `mode="after"` the method returns `self`, not a dict. **Note (2.12+): `@classmethod` on `mode="after"` is deprecated -- write as a plain instance method.**
- **Prefer `validate_by_alias` / `validate_by_name` / `serialize_by_alias`** (2.11+) over the legacy `populate_by_name=True`. The latter is pending deprecation in v3.
- `Path` and `deque` no longer accept Field constraints (2.11+) -- use a custom validator for length / pattern checks.
- `MISSING` sentinel (2.12, experimental) lets you distinguish "not provided" from "explicit default" at validator time.
## Validators
### Mode decision rules
| Mode | When to use | Performance | Returns |
|------|------------|-------------|---------|
| `after` (default) | 90% of cases -- logic on already-coerced value | Fast | Same type as field |
| `before` | Reshape raw input (string split, legacy key mapping) | Python callback overhead | Any (will be type-coerced afterward) |
| `wrap` | Catch `ValidationError`, add logging, force `PydanticUseDefault` | Slowest -- materializes data in Python | Same type as field |
| `plain` | Fully custom, no coercion, no downstream validators | N/A (terminates validation) | **Trusted as-is** -- dangerous for type safety |
**Performance rule:** express constraints in `Field(...)` or Annotated metadata whenever possible -- the Rust engine handles them. Python-level validators (`@field_validator`, `mode="before"`, `mode="wrap"`) incur per-value Python-call overhead ([Performance guide](https://pydantic.dev/docs/validation/latest/concepts/performance/)).
### Field validators
```python
from pydantic import BaseModel, ValidationInfo, field_validator
class User(BaseModel):
email: str
password: str
@field_validator("email")
@classmethod
def email_lowercase(cls, v: str) -> str:
return v.lower()
@field_validator("password")
@classmethod
def password_strength(cls, v: str, info: ValidationInfo) -> str:
# info.data: already-validated fields (in declaration order -- cannot access later fields)
# info.context: user-supplied dict via Model.model_validate(data, context={...})
# info.mode: "python" | "json" | "strings"
# info.field_name: the field being validated
if len(v) < 12:
raise ValueError("password must be at least 12 chars")
return v
```
### Annotated validators (reusable pattern)
Prefer Annotated metadata over decorator validators when the same logic applies across multiple models:
```python
from typing import Annotated
from pydantic import AfterValidator, BeforeValidator, WrapValidator, BaseModel
def lower(v: str) -> str:
return v.lower()
def ensure_https(v: str) -> str:
if not v.startswith("https://"):
raise ValueError("URL must be https")
return v
LowerStr = Annotated[str, AfterValidator(lower)]
HttpsUrl = Annotated[str, AfterValidator(ensure_https)]
# Reuse across any model
class User(BaseModel):
email: LowerStr
avatar_url: HttpsUrl
```
**Ordering rule:** `Before` and `Wrap` validators run right-to-left; `After` validators run left-to-right; decorator-style `@field_validator`s are appended last.
### ValidationInfo and info.context
Stable API across 2.x. Context passes through to custom serializers (2.7+):
```python
user = User.model_validate(payload, context={"tenant_id": request.tenant_id})
# Inside a field_validator / model_validator / field_serializer:
# info.context["tenant_id"] is available
```
Use context for tenant-aware validation, feature flags, or bypass switches -- NOT for data that should be on the model.
### Model validaRelated in Backend & APIs
jfrog
IncludedInteract with the JFrog Platform via the JFrog CLI and REST/GraphQL APIs. Use this skill when the user wants to manage Artifactory repositories, upload or download artifacts, manage builds, configure permissions, manage users and groups, work with access tokens, configure JFrog CLI servers, search artifacts, manage properties, set up replication, manage JFrog Projects, run security audits or scans, look up CVE details, query exposures scan results from JFrog Advanced Security, manage release bundles and lifecycle operations, aggregate or export platform data, or perform any JFrog Platform administration task. Also use when the user mentions jf, jfrog, artifactory, xray, distribution, evidence, apptrust, onemodel, graphql, workers, mission control, curation, advanced security, exposures, or any JFrog product name.
cupynumeric-migration-readiness
IncludedPre-migration readiness assessor for porting NumPy to cuPyNumeric. Use BEFORE substantial porting work begins when the user asks whether code will scale on GPU, whether they should migrate to cuPyNumeric, which NumPy patterns transfer cleanly, what must be refactored before porting, or mentions pre-port assessment, scaling analysis, or refactor planning. Inspect the user's source code, look up NumPy usage, cross-reference the cuPyNumeric API support manifest, and distinguish distributed-scaling-friendly patterns from blockers such as unsupported APIs, scalar synchronization, host round-trips, Python/object-heavy control flow, shape/data-dependent branching, and in-place mutation hazards. Produce a verdict of READY, LIGHT REFACTOR, SIGNIFICANT REFACTOR, or NOT RECOMMENDED, with concrete refactor pointers.
alibabacloud-data-agent-skill
IncludedInvoke Alibaba Cloud Apsara Data Agent for Analytics via CLI to perform natural language-driven data analysis on enterprise databases. Data Agent for Analytics is an intelligent data analysis agent developed by Alibaba Cloud Database team for enterprise users. It automatically completes requirement analysis, data understanding, analysis insights, and report generation based on natural language descriptions. This tool supports: discovering data resources (instances/databases/tables) managed in DMS, initiating query or deep analysis sessions, real-time progress tracking, and retrieving analysis conclusions and generated reports. Use this Skill when users need to query databases, analyze data trends, generate data reports, ask questions in natural language, or mention "Data Agent", "data analysis", "database query", "SQL analysis", "data insights".
token-optimizer
IncludedReduce OpenClaw token usage and API costs through smart model routing, heartbeat optimization, budget tracking, and native 2026.2.15 features (session pruning, bootstrap size limits, cache TTL alignment). Use when token costs are high, API rate limits are being hit, or hosting multiple agents at scale. The 4 executable scripts (context_optimizer, model_router, heartbeat_optimizer, token_tracker) are local-only — no network requests, no subprocess calls, no system modifications. Reference files (PROVIDERS.md, config-patches.json) document optional multi-provider strategies that require external API keys and network access if you choose to use them. See SECURITY.md for full breakdown.
resend-cli
IncludedUse this skill when the task is specifically about operating Resend from an AI agent, terminal session, or CI job via the official resend CLI: installing/authenticating the CLI, sending/listing/updating/cancelling emails, batch sends, domains and DNS, webhooks and local listeners, inbound receiving, contacts, topics, segments, broadcasts, templates, API keys, profiles, or debugging Resend CLI/API failures. Trigger on mentions of Resend CLI, `resend`, `resend doctor`, `resend emails send`, `resend domains`, `resend webhooks listen`, `resend emails receiving`, or agent-friendly terminal automation.
alibabacloud-odps-maxframe-coding
IncludedUse this skill for MaxFrame SDK development and documentation navigation on Alibaba Cloud MaxCompute (ODPS). Helps answer MaxFrame API, concept, official example, and supported pandas API questions; create data processing programs; read/write MaxCompute tables; debug jobs (remote or local); and build custom DPE runtime images. Trigger when users mention MaxFrame, MaxCompute with MaxFrame, ODPS table processing, DPE runtime, MaxFrame docs/examples, DataFrame/Tensor operations, or GPU runtime setup. Works for both English and Chinese queries about Alibaba Cloud data processing with MaxFrame.