Pydantic

LLMs speak JSON. JSON lies sometimes. Pydantic is the lie detector every GenAI app runs on.

▶ Watch this reel

What you'll learn

  1. BaseModel
  2. Field validators
  3. pydantic-settings
  4. JSON Schema export

Remember this

BaseModel

class ChatRequest(BaseModel):
    model: str
    prompt: str
    temperature: float = 0.7
req = ChatRequest(**json_from_llm)   # validates + coerces

Validators

pydantic-settings

class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_prefix="APP_")
    openai_api_key: str

JSON Schema export

schema = ChatRequest.model_json_schema()
reply  = ChatRequest.model_validate_json(raw)

Code: Pydantic — the GenAI backbone pattern

from pydantic import BaseModel, Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict

# --- 1. BaseModel: parse, don't pray ---------------------------
class ChatRequest(BaseModel):
    model: str
    prompt: str
    temperature: float = 0.7
    max_tokens: int = Field(default=1000, ge=1, le=128_000)

req = ChatRequest(**{"model": "gpt-4o", "prompt": "hi", "temperature": "0.2"})

# --- 2. Validators: value rules --------------------------------
ALLOWED = {"gpt-4o", "claude-sonnet", "llama-3"}

@field_validator("model")
@classmethod
def model_must_be_supported(cls, v: str) -> str:
    if v not in ALLOWED:
        raise ValueError(f"unsupported model: {v}")
    return v

# --- 3. Settings: validated env config -------------------------
class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_prefix="APP_")
    openai_api_key: str
    model: str = "gpt-4o"
    max_retries: int = 3

# export APP_OPENAI_API_KEY=sk-...
# settings = Settings()   # crashes loudly if the key is missing

# --- 4. JSON Schema: structured output --------------------------
print(ChatRequest.model_json_schema())
# → the schema you pass as response_format / tool parameters

# reply = client.chat(..., response_format=ChatRequestSchema)
# parsed = ChatRequest.model_validate_json(reply)