Day 13 · ~13m

JSON Schema & Documentation

Generating JSON schemas from models with model_json_schema() and Field descriptions.

🧑‍💻

I've seen APIs that publish a schema describing their data format. Can Pydantic generate that automatically?

👩‍🏫

Yes. Every Pydantic model can generate a JSON Schema — the standard format for describing the structure of JSON data:

from pydantic import BaseModel
import json

class Product(BaseModel):
    name: str
    price: float
    in_stock: bool

schema = Product.model_json_schema()
print(json.dumps(schema, indent=2))

This outputs a JSON Schema object with all the fields, their types, and which ones are required. FastAPI uses exactly this to generate interactive API docs automatically.

🧑‍💻

How do I make the schema more descriptive? Like adding descriptions for each field?

👩‍🏫

Use the description parameter in Field(). These descriptions flow directly into the generated schema:

from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(description="Product display name")
    price: float = Field(gt=0, description="Price in USD")
    in_stock: bool = Field(description="Whether the product is available")

schema = Product.model_json_schema()

Now the schema includes human-readable descriptions for each field. Anyone reading the schema knows exactly what each field means.

🧑‍💻

What about the model itself? Can I add a description for the whole model?

👩‍🏫

Yes — use a docstring on the class. Pydantic includes it in the schema:

class Order(BaseModel):
    """A customer order with line items and shipping details."""
    order_id: str = Field(description="Unique order identifier")
    total: float = Field(ge=0, description="Order total in USD")
    items: list[str] = Field(description="List of product names")

schema = Order.model_json_schema()
print(schema.get("description"))
# "A customer order with line items and shipping details."
🧑‍💻

Can I also add example values to fields?

👩‍🏫

Use the examples parameter in Field() to provide sample values:

class User(BaseModel):
    """A registered user account."""
    username: str = Field(
        min_length=3,
        max_length=20,
        description="Unique username",
        examples=["alice_dev", "bob42"]
    )
    email: str = Field(
        description="User email address",
        examples=["user@example.com"]
    )

Examples show up in the JSON Schema and in API documentation tools. They help consumers understand what valid data looks like without reading the constraints.

🧑‍💻

What does the generated schema actually look like? Can I extract specific information from it?

👩‍🏫

The schema is a plain Python dictionary, so you can navigate it like any dict:

class Config(BaseModel):
    """Application configuration."""
    host: str = Field(description="Server hostname")
    port: int = Field(ge=1, le=65535, description="Server port")
    debug: bool = Field(default=False, description="Enable debug mode")

schema = Config.model_json_schema()

# Get required fields
print(schema["required"])  # ['host', 'port']

# Get properties
for name, props in schema["properties"].items():
    print(f"{name}: {props.get('type', 'N/A')} - {props.get('description', '')}")

The schema is the contract between your code and the outside world. Write good descriptions, and anyone can understand your data model without reading your Python code.

Practice your skills

Sign up to write and run code in this lesson.

Already have an account? Sign in