What Is Pydantic? Python Validation Explained

How Pydantic validates and parses data using Python type hints, and why it’s become the default choice underneath FastAPI and most of the modern AI stack

Pydantic validates and parses data using ordinary Python type hints — define a class with typed fields, and it checks, converts, and rejects incoming data against those types automatically. It’s become the default data-validation layer across most of the modern Python web and AI ecosystem.

The basic idea

from pydantic import BaseModel

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

user = User(name="Ada", age="36")  # "36" (str) is coerced to 36 (int)

A BaseModel subclass with type-annotated fields becomes a schema. Pydantic validates incoming data against it, coercing compatible types where reasonable and raising a detailed ValidationError where it isn’t — turning “some dict of unknown shape” into a typed, IDE-autocomplete-friendly Python object.

Pydantic vs a plain dataclass

Python’s built-in dataclasses also turn annotated fields into a class, but they don’t enforce those annotations at runtime, so a field typed int will happily accept a string. Pydantic checks and converts the data. For trusted data that stays inside your own code, a dataclass is often enough; for data arriving from outside (a request body, a config file, LLM output), Pydantic’s validation is the point. dataclasses vs Pydantic vs attrs compares all three.

Why FastAPI is built around it

FastAPI uses Pydantic models to validate request bodies and query parameters, and generates its interactive OpenAPI docs directly from those same models — the type-annotated class you write for validation is the same one that produces the documentation, with no separate schema to maintain.

Beyond web APIs

Pydantic shows up well beyond request validation: settings/config management (pydantic-settings), data pipeline validation, and increasingly as the backbone of structured LLM output — Instructor uses Pydantic models to extract typed, validated data from LLM responses, and Pydantic AI (built by the same team) uses it as the type-safety layer for agent outputs and dependencies.

v1 vs v2

Pydantic v2 rewrote its core validation engine in Rust (pydantic-core), giving a substantial performance improvement over v1’s pure-Python implementation, alongside some API changes (.dict() → .model_dump(), among others). Any new project should use v2 — v1 is legacy at this point.

Where you’ll run into it

If you’re using FastAPI, Instructor, or Pydantic AI, you’re using Pydantic whether or not you import it directly. Understanding it directly pays off the moment you need custom validators, nested models, or want to debug a validation error rather than just working around it.

Frequently Asked Questions

What is Pydantic used for?

Validating and parsing data using Python type hints — you define a model as a class with typed fields, and Pydantic checks incoming data against those types, converts what it can, and raises a clear error for what it can’t.

Why does FastAPI use Pydantic?

FastAPI uses Pydantic models to validate request bodies and query parameters automatically, and to generate its interactive API docs directly from the same type-annotated models — one definition serves both validation and documentation.

Is Pydantic just for API frameworks?

No — it’s widely used for settings/config management, data pipelines, and increasingly as the structured-output layer for LLM applications (see Instructor and Pydantic AI), anywhere you need to turn loosely-typed data into validated, typed Python objects.

What’s the difference between Pydantic v1 and v2?

Pydantic v2 rewrote its core validation logic in Rust (via pydantic-core), giving substantial performance improvements over v1’s pure-Python implementation, alongside some API changes. New projects should use v2.