"""NeuroFocus object detection API. A neuro-inspired SIMULATION of selective attention. It detects objects in an image and returns labels, confidence scores, and bounding boxes plus simple scene scores. It does not measure or diagnose attention, ADHD, fatigue, or any condition. """ import io from fastapi import FastAPI, File, HTTPException, Query, UploadFile from fastapi.middleware.cors import CORSMiddleware from PIL import Image, UnidentifiedImageError from detection import DEFAULT_THRESHOLD, DEVICE, MODEL_NAME, detect from scoring import compute_scores DISCLAIMER = "This is a neuro-inspired simulation, not a medical diagnosis." app = FastAPI(title="NeuroFocus Object Detection API", version="0.1.0") # Permissive CORS for local development / demo. app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) async def _read_image(file: UploadFile) -> Image.Image: """Read an UploadFile into a PIL image, raising HTTP 400 on bad input.""" if file.content_type and not file.content_type.startswith("image/"): raise HTTPException(status_code=400, detail="Uploaded file is not an image.") data = await file.read() if not data: raise HTTPException(status_code=400, detail="Uploaded file is empty.") try: return Image.open(io.BytesIO(data)) except UnidentifiedImageError: raise HTTPException(status_code=400, detail="Could not read image file.") @app.get("/") def root(): return {"name": "NeuroFocus Object Detection API", "status": "running"} @app.get("/health") def health(): return {"status": "ok", "device": DEVICE, "model": MODEL_NAME} @app.post("/detect") async def detect_objects( file: UploadFile = File(...), threshold: float = Query(DEFAULT_THRESHOLD, ge=0.0, le=1.0), ): image = await _read_image(file) return detect(image, threshold=threshold) @app.post("/analyze-focus") async def analyze_focus( file: UploadFile = File(...), threshold: float = Query(DEFAULT_THRESHOLD, ge=0.0, le=1.0), ): image = await _read_image(file) detection = detect(image, threshold=threshold) return { "image_size": detection["image_size"], "objects": detection["objects"], "scores": compute_scores(detection), "note": DISCLAIMER, }