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.1.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

Drop an image, get the primary subject squared and cropped.


      
Result
Crop
Annotated source
""" ) @app.post("/api/focus") async def focus(file: UploadFile = File(...), buffer_ratio: float = Form(0.15)): from app.vision import process_image try: payload = await file.read() return process_image(payload, file.filename or "upload", buffer_ratio=buffer_ratio) 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)): from app.vision import process_image try: payload = await file.read() result = process_image(payload, file.filename or "upload", buffer_ratio=buffer_ratio) 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