Internal Streamlit app for the ODI tech team to monitor the health and quality of data
published by the ~170 OpenActive publishers. Read-only, behind Google SSO, restricted to the
theodi.org workspace.
Data comes from the stewards REST API, which fronts a daily BigQuery batch — every page states the snapshot date rather than implying live data.
uv sync --extra devOnly part of the backing API is built, so the app ships sample payloads and can be run in full today:
STEWARDS_USE_SAMPLE_DATA=true STEWARDS_ENV=dev STEWARDS_DISABLE_AUTH=true \
uv run streamlit run src/stewards/app.pyAgainst the real API, copy .streamlit/secrets.toml.example to
.streamlit/secrets.toml, fill in the Google OIDC client, the API token and — for the
interim admin API — api_style = "admin" with api_token_param = "token", then run:
uv run streamlit run src/stewards/app.pyEndpoints that a deployment has not implemented yet report themselves as not live on the page that needs them; nothing else on the app is affected. Today that is the fleet summary, the contact queue and every monitor except single-feed stalls.
uv run pytest -q --cov=src/stewards --cov-report=term-missing
uv run ruff check --fix . && uv run ruff format .
uv run mypy src.github/workflows/ci.yml runs on every pull request to main, and on pushes to main:
- Lint —
ruff check,ruff format --check,mypy --strict - Tests —
pytest, with the coverage bars enforced rather than aspirational:= 80% project-wide, and >= 90% across
monitors/,components/andapi/
Dependencies install with uv sync --extra dev --locked, so a pyproject.toml change
committed without a refreshed uv.lock fails the build instead of silently resolving to
something the lockfile does not describe.
BUILD_BRIEF.md— settled product decisions, page map, API contract, visual languageCLAUDE.md— architecture, hard rules, configuration, testing bar.claude/skills/add-monitor/SKILL.md— how to add the next monitorData Stewards Dashboard.dc.html— the approved UI mockup
Two of the eight monitors are built (single_feed_stall, http_failure), plus the overview,
and the cross-monitor contact queue. The rest follow their API endpoints. Runbooks are
published separately from docs/ to GitHub Pages.