Phase 1 — Foundations · Lesson 8 · 20 XP
Pydantic: validating data
A @dataclass (Lesson 3) accepts whatever you hand it — Book("Dune", "Frank Herbert", "not a year") constructs happily even though year should be an int. A Pydantic BaseModel validates on construction: bad data raises a clear ValidationError immediately, at the boundary, instead of failing mysteriously three functions later.
from pydantic import BaseModel, Field
class User(BaseModel):
name: str
age: int = Field(ge=0)
User.model_validate({"name": "Dilan", "age": -1}) # raises ValidationError: age must be >= 0This matters enormously for AI engineering: every LLM API response, every piece of "structured output" a model returns, and every incoming API request body is untrusted JSON until something checks its shape. Pydantic is that check — model_validate(raw_dict) either gives you a trustworthy object or tells you exactly what's wrong.
Exercise
Define a Pydantic model matching an API response shape, then validate a batch of raw dicts — some valid, some deliberately broken — and report which ones failed and why, using the fields on the ValidationError.
Check yourself
1. How is a Pydantic model different from a plain @dataclass in terms of what happens the moment you construct one?
2. Why is Pydantic especially useful for JSON that came from an external API or an LLM, rather than data you generated yourself?
Async Python: asyncio and concurrency
Answer the check-yourself questions to unlock this