""" trigger_proactive/app.py ───────────────────────── Lightweight HF Space trigger. Wakes quickly, then polls the main Socrates Docker until ready, then calls /proactive/run. Env vars required: SOCRATES_URL – main Docker URL (e.g. https://alesamodio.hf.space) PROACTIVE_TRIGGER_SECRET – shared secret (must match main Docker) """ import os import time import requests from fastapi import FastAPI, Request, HTTPException app = FastAPI() SOCRATES_URL = os.environ.get("SOCRATES_URL", "").rstrip("/") TRIGGER_SECRET = os.environ.get("PROACTIVE_TRIGGER_SECRET", "") POLL_INTERVAL = 15 # seconds between readiness checks POLL_MAX = 40 # max attempts → 40 × 15s = 10 minutes @app.get("/") def health(): return {"status": "trigger_proactive alive"} @app.get("/run") def run(request: Request): # ── Auth ────────────────────────────────────────────────────────────────── if TRIGGER_SECRET: provided = request.headers.get("x-trigger-secret", "") if provided != TRIGGER_SECRET: raise HTTPException(status_code=403, detail="Invalid trigger secret") if not SOCRATES_URL: raise HTTPException(status_code=500, detail="SOCRATES_URL not configured") # ── Step 1: send wake-up ping ───────────────────────────────────────────── print(f"[trigger] Waking {SOCRATES_URL} ...") try: requests.get(SOCRATES_URL + "/ready", timeout=10) except Exception: pass # expected to fail or time out while waking # ── Step 2: poll until ready ────────────────────────────────────────────── print("[trigger] Polling until main Docker is ready ...") ready = False for attempt in range(1, POLL_MAX + 1): try: r = requests.get(SOCRATES_URL + "/ready", timeout=10) if r.status_code in (200, 422): print(f"[trigger] Ready after {attempt} attempts ({attempt * POLL_INTERVAL}s)") ready = True break except Exception as e: print(f"[trigger] attempt {attempt}: {e}") time.sleep(POLL_INTERVAL) if not ready: raise HTTPException(status_code=504, detail="Main Docker did not wake in time") # ── Step 3: call /proactive/run ─────────────────────────────────────────── print("[trigger] Calling /proactive/run ...") try: resp = requests.post( SOCRATES_URL + "/proactive/run", headers={ "Content-Type": "application/json", "x-trigger-secret": TRIGGER_SECRET, }, json={}, timeout=300, # proactive pipeline can take a few minutes for many users ) result = resp.json() print(f"[trigger] Done. sent={result.get('sent', '?')}") return result except Exception as e: raise HTTPException(status_code=502, detail=f"Proactive pipeline error: {e}")