import os from pathlib import Path BASE_DIR = Path(__file__).resolve().parent INSTANCE_DIR = Path(os.environ.get("INSTANCE_DIR", BASE_DIR / "instance")) UPLOADS_DIR = INSTANCE_DIR / "uploads" DB_PATH = INSTANCE_DIR / "boarding_pass.db" PORT = int(os.environ.get("PORT", "8080")) MAX_UPLOAD_MB = int(os.environ.get("MAX_UPLOAD_MB", "15")) PUBLIC_BASE_URL = os.environ.get("PUBLIC_BASE_URL", "").rstrip("/") AIRTRAIL_BASE_URL = os.environ.get("AIRTRAIL_BASE_URL", "").rstrip("/") AIRTRAIL_API_KEY = os.environ.get("AIRTRAIL_API_KEY", "") # RapidAPI AeroDataBox key - same provider/plan AirTrail's own "Search" # button uses internally to fill in schedule/actual gate times. Optional: # if unset, gate scheduled/actual times are simply left for AirTrail's own # manual Search to fill in, same as today. AERODATABOX_API_KEY = os.environ.get("AERODATABOX_API_KEY", "") # Shared browser UA for every outbound scrape/API call this pipeline makes. # Both FlightAware and (as of the AeroDataBox 403 debugging session) the # AeroDataBox/RapidAPI gateway sit behind Cloudflare and reject requests # carrying Python urllib's default User-Agent - confirmed live: the exact # same request/key/URL got HTTP 403 with no UA and HTTP 200 with this one. BROWSER_USER_AGENT = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/124.0 Safari/537.36" ) FLIGHTAWARE_USER_AGENT = BROWSER_USER_AGENT # kept for anything still importing the old name MAX_TRACK_POINTS = 2000 MAX_FETCH_ATTEMPTS = 5 def ensure_dirs() -> None: INSTANCE_DIR.mkdir(parents=True, exist_ok=True) UPLOADS_DIR.mkdir(parents=True, exist_ok=True)