"""OpenFoodFacts proxy (spec §3.5). All OFF calls go through this router. OFF etiquette (spec §8.1 rule 10): descriptive User-Agent, timeouts, and kcal-vs-kJ normalization in exactly one module. Tests mock at the httpx boundary — never hit the real OFF API (spec §8.4). """ import httpx from fastapi import APIRouter OFF_BASE_URL = "https://world.openfoodfacts.org" OFF_USER_AGENT = "CalCount/0.1 (personal self-hosted calorie counter)" OFF_TIMEOUT = 10.0 router = APIRouter(prefix="/api/off", tags=["off"]) @router.get("/product/{barcode}") def get_product(barcode: str): """Proxy a product lookup by barcode. Returns raw OFF JSON for now. TODO: normalize to our foods schema (spec §3.5) in one shared module. """ resp = httpx.get( f"{OFF_BASE_URL}/api/v2/product/{barcode}", headers={"User-Agent": OFF_USER_AGENT}, timeout=OFF_TIMEOUT, ) resp.raise_for_status() return resp.json()