Prompt file imported from debabratahazra/hotspot-sentinels (
.github/prompts/fastapi-controller.prompt.md). Copyright stays with the author.
Build the agentic API controller for HotSpot Sentinels (Epic 4 / Story 4.1).
Project rules: COPILOT_GUIDE.md. All routes are async def.
Target file
backend/main.py
Endpoints
GET /api/health— reports readiness of each cloud dependency (GenAI client, Firestore, Pub/Sub, BigQuery) plus project and region. Never return credentials or full client config.POST /api/analyze— multipart upload:image: UploadFileandambient_temp: float = Form(...), optionalzone_name: str = Form("Unnamed Zone").- If
ambient_tempis not supplied or is out of range, fall back toclimate_service.get_latest_temperature(). - Call
vision_analyzer.analyze_urban_hotspot(...), persist viadatabase.save_hotspot_report(...), then callalert_dispatcher.dispatch_heat_alert(...). - Set
alert_dispatchedfrom whether a message ID came back, and return the unified Heat Analysis Result JSON plusdoc_idandclimate_source.
GET /api/scans?limit=10— returns recent scans fromdatabase.get_recent_reports(limit).
Implementation rules
- Define Pydantic v2 response models mirroring the guide's schema; do not return bare dicts from route handlers.
- CORS: read allowed origins from an
ALLOWED_ORIGINSenv var (comma-separated), defaulting tohttp://localhost:8501. Do not pairallow_origins=["*"]withallow_credentials=True. - Validate uploads at the boundary: reject content types outside
image/png,image/jpeg,image/webpwith 415, and reject bodies over aMAX_UPLOAD_BYTESconstant (e.g. 10 MB) with 413. - Wrap blocking service calls in
asyncio.to_threadwhere the underlying helper is synchronous. - Map
VisionAnalysisErrorto 502 andDatabaseErrorto 503 via exception handlers; return generic messages to clients and log details server-side — never leak stack traces or cloud error payloads in responses. - Load
.envwithpython-dotenvat import; bind uvicorn to thePORTenv var (default 8080) in the__main__guard.
Done when
uvicorn main:app --port 8080starts from thebackend/directory andGET /api/healthreturns 200.
