Latticework

Command Palette

Search for a command to run...

Pydantic

Models & Validation

20 min

Explanation

Prompt Engineering's structured-output module validated a dict by hand: check each field exists, check its type with isinstance(). Pydantic automates this with declarative models — define the shape once as a class, and get validation (plus something isinstance() doesn't do: automatic type COERCION for compatible values) for free every time you construct one.

from pydantic import BaseModel, ValidationError

class User(BaseModel):
    name: str
    age: int
    active: bool = True

def validate_user(data):
    try:
        user = User(**data)
        return ("ok", user.name, user.age, user.active)
    except ValidationError as e:
        return ("error", len(e.errors()))
Try it

This coercion behavior is a real, easy-to-miss gotcha -- a hand-written isinstance() check (like Prompt Engineering's structured-output) would have flatly rejected a numeric string passed as age, while pydantic accepts it because it can be unambiguously converted. Worth knowing before assuming pydantic validation is exactly as strict as manual type-checking.

Loading editor…
Exercise

Given the provided `User` model (`name: str`, `age: int`, `active: bool = True`), write `validate_user(data)`: try constructing `User(**data)`. On success, return `("ok", user.name, user.age, user.active)`. On a `ValidationError`, return `("error", len(e.errors()))` — the number of fields that failed.

Quiz

Prompt Engineering's structured-output module hand-wrote a validator checking field presence and exact type with isinstance(). What does pydantic do differently when a field like age: int receives the string "25"?

Checkpoint

You can validate data against a pydantic model and handle ValidationError, and understand pydantic's automatic type coercion behavior versus a strict isinstance() check.