Serving
The serving module is the app contract half of the two-contracts architecture (ADR-0006). It exposes a small, OpenAPI-documented HTTP API on top of the data platform and ranker so application clients — the TypeScript editor, the Streamlit swap-demo, anything else that speaks the contract — can drive the recommender without touching DuckDB directly.
The whole module is also where most of the FastAPI + Python code lives that
the other modules anchor to. If you are exploring the repo top-down,
tutorial/serving/
is the directory with the most going on.
The endpoints
Section titled “The endpoints”| Endpoint | What it does | Source |
|---|---|---|
GET /articles/{id} | Single-article lookup | articles.py |
GET /recommendations/{user_id} | Generates a candidate set, applies the persisted configuration’s ranker, returns the ranked list | recommendations.py |
POST /preview | Same ranker, but takes the configuration inline (does not persist). Powers the editor’s live preview. | recommendations.py |
GET / POST / PUT / DELETE /constraint-configurations* | Full CRUD against the constraint_configurations table | configurations.py |
POST /assistants/change-explainer | Editorial AI assistant: explains why a recommendation list changed | agents/change-explainer.ts (TS side) + serving glue |
The application entry point is
app.py.
FastAPI generates the OpenAPI spec automatically; the API reference
page on this docs site renders that spec for readers, and the TypeScript
editor consumes it as auto-generated typed clients (see the editor module).
The OpenAPI file is the swappable boundary
Section titled “The OpenAPI file is the swappable boundary”The architectural claim (ADR-0006)
is that any client speaking the same OpenAPI contract is interchangeable
with any other. The TypeScript editor is one client; the Streamlit
swap-demo is a deliberately different one (different language, different
UI runtime) — and the
swap_demo.py
script makes the swappability claim falsifiable rather than rhetorical.
A side-by-side integration test feeds the same fake app-contract server to both clients and asserts they produce identical rankings for the same user and configuration. Read serving’s lesson prose for the full walkthrough.
Tests as documentation
Section titled “Tests as documentation”The
tests/
directory carries integration tests for every endpoint:
Each test makes the response schema explicit and verifies behaviour against the ranker module without going through the network. The OpenAPI contract is enforced at the boundary.
After this module
Section titled “After this module”The editor module is the primary application client. The assistants module hangs its endpoints off the same FastAPI app. The evaluation module reads the same ranker behaviour the serving endpoints expose.