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