Files
politics-tracking/backend/politrack/worker.py
T
simonandClaude Opus 5.5 583ccba31c Politrack: track Austrian politicians from public sources
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>
2026-10-28 20:02:01 +01:00

42 lines
1.6 KiB
Python

"""Background jobs on Procrastinate (Postgres-backed queue; no Redis).
One periodic task is generated per registered adapter/enricher from its `schedule` (cron, UTC) and
`queue`. Run workers per queue so heavy jobs don't block light ones:
procrastinate --app=politrack.worker.app worker --queues=scrape,social
procrastinate --app=politrack.worker.app worker --queues=bulk
procrastinate --app=politrack.worker.app worker --queues=enrich
Periodic tasks are deferred by every running worker and de-duplicated by Procrastinate; queueing locks
prevent two runs of the same adapter at once. Workers can run on other machines that reach the DB.
"""
from __future__ import annotations
import logging
from procrastinate import App, PsycopgConnector
from politrack.config import get_settings
from politrack.core import registry
from politrack.core.runner import run
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
app = App(connector=PsycopgConnector(conninfo=get_settings().database_url))
def _make_task(name: str, queue: str, schedule: str | None) -> None:
def job(timestamp: int | None = None, **params) -> dict:
return run(name, params=params or None)
job.__name__ = f"run_{name.replace('.', '_')}"
task = app.task(name=f"politrack.run.{name}", queue=queue, queueing_lock=name, pass_context=False)(job)
if schedule:
app.periodic(cron=schedule, periodic_id=name)(task)
registry.load_builtin()
for _name, _cls in {**registry.ADAPTERS, **registry.ENRICHERS}.items():
_make_task(_name, _cls.queue, _cls.schedule)