Files
politics-tracking/backend/politrack/config.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

49 lines
1.7 KiB
Python

from functools import lru_cache
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
"""All settings come from environment variables prefixed POLITRACK_ (see .env.example)."""
model_config = SettingsConfigDict(env_prefix="POLITRACK_", env_file=".env", extra="ignore")
database_url: str = "postgresql://politrack:politrack@localhost:5432/politrack"
reader_password: str | None = None
# Crawling identity & politeness
user_agent: str = "PolitrackBot/0.2 (+https://github.com/your-user/politics-tracking; contact: admin@example.org)"
min_request_interval: float = 2.0
http_timeout: float = 60.0
# Raw archive (fetched responses, gzip, content-addressed)
raw_dir: Path = Path("/data/raw")
config_dir: Path = Path(__file__).resolve().parent.parent / "config"
# Parliament: legislative periods (GP) ingested in detail
parlament_periods: list[str] = ["XXVII", "XXVIII"]
# Embeddings via Ollama (optional)
ollama_url: str | None = None
embedding_model: str = "bge-m3"
# Optional credentials for sources that require them (adapters skip themselves when unset)
youtube_api_key: str | None = None
meta_ad_library_token: str | None = None
x_bearer_token: str | None = None
# Bulk sources: how far back to backfill on the first run
procurement_since: str = "2024-01-01"
ad_archive_since: str = "2023-01-01"
api_cors_origins: list[str] = ["http://localhost:3000"]
# Bearer token for moderation/admin endpoints. Empty = disabled (use the CLI).
admin_token: str | None = None
@lru_cache
def get_settings() -> Settings:
return Settings()