Initial import of Politrack, a self-hosted service that tracks Austrian politicians from federal to municipal level - roles, votes, money flows, statements, meetings, social media and legal proceedings - with every claim linked to its sources. - backend: FastAPI + Postgres/pgvector; adapter framework (fetch -> parse -> load -> enrich) with robots.txt/TDM-aware fetching, a raw-response archive for reparsing, and a claim/evidence model with corroboration - sources: Parliament, Wikidata, EU Parliament/Commission, Council of Ministers, Rechnungshof party reports and donations, procurement, RTR media transparency, political ad libraries, WKStA, news feeds, Wikipedia edits, Bluesky, Mastodon, public Telegram channels, YouTube and X (official API) - web: Next.js frontend in German and English with typed API client - mcp: MCP server for AI agents and RAG - docs: architecture, data model, sources, legal notes, Unraid deployment and contributor guides; Docker Compose setup for Unraid Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2.7 KiB
2.7 KiB
Extending the API (and the MCP server)
Data flows out through three layers that are kept deliberately thin:
politrack/queries/<domain>.py SQL, returns dicts (shared by REST API and MCP server)
politrack/api/schemas.py Pydantic response models (the contract → OpenAPI → TypeScript)
politrack/api/main.py FastAPI endpoints (parameters, 404s, response_model)
politrack/mcp_server.py MCP tools for AI agents (same query functions)
Adding an endpoint, step by step
- Query – add a function to the matching module in
politrack/queries/(people, organizations, claims, votes, money, search, admin) and export it fromqueries/__init__.py.- Only show visible claims: use
VISIBLE(published, not merged) fromqueries/common.py. - Respect the user's source filter: take a
SourceFilterand useevidence_json(source_sql)to aggregate evidence – claims whose evidence is entirely filtered out must disappear. - Always parameterise (
%(name)s), never format user input into SQL.LIMIT/OFFSETon lists.
- Only show visible claims: use
- Response model – add a class to
api/schemas.py(inherit fromModel). Field names = column names. - Endpoint – in
api/main.py, withresponse_model=.... Reuse the dependenciesDB,Sources,Limit,Offset; comma-separated list parameters go throughcsv_list(). - Types for the web app:
Then add a typed function to
cd backend && politrack openapi --ts ../web/src/lib/api-types.tsweb/src/lib/api.ts. Commit the regeneratedapi-types.ts. - MCP tool (if agents should use it) – a
@mcp.tool()inmcp_server.pywith a docstring that tells the agent what the data means and how to cite it. - Test – extend the API smoke test (see testing.md).
Conventions
- URLs:
/api/v1/<plural noun>[/<slug>[/<sub-resource>]]; slugs, never internal ids, for people, parties and organisations (vote events use ids – they have no natural slug). - Every claim-like object carries
evidence: [{url, title, source, published_at, quote, …}]andsource_count. - Legal matters always include
legal_stage; the client decides about the presumption-of-innocence notice (needsInnocenceNoticein the web app, theinstructionsin the MCP server). - Admin endpoints require
Authorization: Bearer $POLITRACK_ADMIN_TOKENand are excluded from the schema.
Read-only database access for agents and BI tools
The role politrack_reader (password POLITRACK_READER_PASSWORD) can SELECT everything. Useful views:
claim_with_evidence, person_status, person_identifier. See ../data-model.md.