← back to Paul Conrad Archive
src/conrad/config.py
50 lines
"""Central configuration. Values can be overridden by environment variables (see .env.example)."""
from __future__ import annotations
import os
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
DATA = Path(os.environ.get("CONRAD_DATA_DIR", ROOT / "data"))
DB_PATH = Path(os.environ.get("CONRAD_DB", DATA / "conrad.db"))
CACHE_DIR = DATA / "cache"
CHECKPOINT_DIR = CACHE_DIR / "checkpoints"
EXPORT_DIR = DATA / "exports"
SOURCES_JSON = DATA / "sources.json"
# READ-ONLY seed corpus (owned by TK-12179 shadow-man-build; never write there).
SEED_ROOT = Path(os.environ.get("CONRAD_SEED_ROOT", Path.home() / "Projects/paul-conrad-cartoons"))
SEED_RESEARCH = SEED_ROOT / "research"
MAX_CONCURRENCY = int(os.environ.get("MAX_CONCURRENCY", 3))
REQUEST_DELAY = float(os.environ.get("REQUEST_DELAY", 2.0)) # seconds per host (robots Crawl-delay wins if larger)
TIMEOUT = int(os.environ.get("TIMEOUT", 30))
USER_AGENT = os.environ.get(
"CONRAD_USER_AGENT",
"paul-conrad-archive/0.1 research metadata-only; contact steve@designerwallcoverings.com",
)
CREATOR = "Conrad, Paul, 1924-2010"
YEAR_MIN, YEAR_MAX = 1945, 2010
# Optional free API keys, read from the environment or ~/Projects/secrets-manager/.env
# (never printed, never committed).
SECRETS_ENV = Path.home() / "Projects/secrets-manager/.env"
def secret(name: str) -> str | None:
if os.environ.get(name):
return os.environ[name]
try:
for line in SECRETS_ENV.read_text().splitlines():
if line.startswith(name + "="):
v = line.split("=", 1)[1].strip().strip('"').strip("'")
return v or None
except OSError:
return None
return None
for _d in (DATA, CACHE_DIR, CHECKPOINT_DIR, EXPORT_DIR):
_d.mkdir(parents=True, exist_ok=True)