Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

src/models/

Pydantic contracts that cross module or process seams. Import-linter enforces that nothing outside this package matters here — src.models depends on nothing in src/ (forbidden contract in pyproject.toml). The point: schema bugs surface at construction with clear ValidationErrors, not as AttributeErrors deep in the request path.

Key interfaces

  • _base.StrictModelBaseModel subclass with model_config = ConfigDict(extra="forbid"). Inherit this for any contract that crosses a boundary; opt into stricter type coercion with class Foo(StrictModel, strict=True) when JSON coercion (UUID, int) is undesirable.
  • health.HealthResponsestatus: Literal["ok"] + version: str. Returned by GET /api/v1/health.
  • session.SessionCreate / session.SessionInfo — the create-empty / public-info shapes used by src.api.sessions.SessionStore.
  • config.Settingspydantic_settings.BaseSettings reading the four LLM_* env vars (LLM_PROVIDER, LLM_API_KEY, LLM_BASE_URL, LLM_MODEL). Provider-pluggable seam — wire OpenAI, Anthropic, Azure, or vLLM by swapping the values without touching this code.
  • config.get_settings() — fresh Settings constructor (deliberately unmemoised so tests can re-construct after monkeypatch.setenv). Real callers should hold a single instance at startup.

Conventions

  • One module per logical contract group — health, session, config. Add a new file rather than appending to an existing one.
  • Per-class strict=True is the call site for any model that should reject "3.14" for a float; HTTP-boundary models often skip it because JSON requires the coercion.
  • pyproject.toml [tool.ruff.lint.per-file-ignores] adds "src/models/**" = ["TCH003"] because Pydantic needs runtime imports for type annotations.