POST with a Pydantic body

A GET that returns a constant is easy. Now we need to accept structured input. That means a POST route and a Pydantic model that describes the body. The model is the contract: fields, types, required vs optional, all declared once.

models.py
python
from pydantic import BaseModel, Field

class StoryRequest(BaseModel):
    """Defines what data we need to generate a story."""

    character_name: str = Field(
        ...,
        min_length=1,
        max_length=50,
        description="The name of the story's main character"
    )

    character_age: int = Field(
        ...,
        ge=1,
        le=18,
        description="Age of the character (1-18 years)"
    )

A Pydantic BaseModel declares the request contract. Field adds validation rules that FastAPI will enforce before your handler runs.

router.py
python
from models import StoryRequest
from service import generate_story_stream

@router.post("/stream")
async def stream_story(request: StoryRequest):
    """Receives story parameters and kicks off generation."""
    return await generate_story_stream(request)

The type hint StoryRequest is the body contract. FastAPI parses the JSON body, validates it, and passes you a typed object. No manual json.loads needed.

FastAPI returns a 422 Unprocessable Entity response with a JSON body describing exactly which field failed and why. Your handler never runs. This is the single best reason to use Pydantic: you get input validation for free, and the errors are structured enough to show in a UI.

Fill in the blanks: Complete the POST route

Loading practice…