from fastapi import FastAPI, File, Form, HTTPException, UploadFile from fastapi.responses import HTMLResponse, StreamingResponse from app.config import settings app = FastAPI(title="face-lock", version="0.2.0") @app.get("/health") def health(): return {"ok": True, "env": settings.env} @app.get("/", response_class=HTMLResponse) def index(): if settings.env != "dev": return HTMLResponse("

face-lock

Set ENV=dev for the UI.

") return HTMLResponse( """ face-lock

face-lock

Auto-detect the subject, square it up, and crop with buffer.


      
Result
Crop
Annotated source
""" ) @app.post("/api/focus") async def focus( file: UploadFile = File(...), buffer_ratio: float = Form(0.15), detector: str = Form("auto"), ): from app.vision import process_image try: payload = await file.read() return process_image(payload, file.filename or "upload", buffer_ratio=buffer_ratio, detector=detector) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc @app.post("/api/focus/image") async def focus_image( file: UploadFile = File(...), buffer_ratio: float = Form(0.15), detector: str = Form("auto"), ): from app.vision import process_image try: payload = await file.read() result = process_image(payload, file.filename or "upload", buffer_ratio=buffer_ratio, detector=detector) return StreamingResponse(result["crop_bytes_io"], media_type=result["mime_type"]) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc