from __future__ import annotations from pathlib import Path import httpx from fastapi import APIRouter, HTTPException, Request from fastapi.responses import Response from fastapi.templating import Jinja2Templates from pydantic import BaseModel, Field from app.config import settings router = APIRouter(tags=["packaging"]) BASE_DIR = Path(__file__).resolve().parent.parent.parent templates = Jinja2Templates(directory=str(BASE_DIR / "templates")) class PackagingGenerateBody(BaseModel): type: str = Field(default="folding_box") width_mm: float = Field(default=120, gt=0) height_mm: float = Field(default=80, gt=0) depth_mm: float = Field(default=40, ge=0) elements: dict[str, bool] = Field(default_factory=dict) brand: dict[str, str] = Field(default_factory=dict) barcode_value: str | None = Field(default=None) @router.get("/packaging") async def packaging_page(request: Request): return templates.TemplateResponse( "packaging.html", {"request": request, "page_title": "Packaging Studio"}, ) @router.post("/api/packaging/generate") async def proxy_packaging_generate(body: PackagingGenerateBody): try: async with httpx.AsyncClient(timeout=60.0) as client: r = await client.post( f"{settings.TOOLS_API_URL.rstrip('/')}/packaging/generate", json=body.model_dump(), ) r.raise_for_status() return r.json() except httpx.HTTPStatusError as exc: detail = exc.response.text[:400] if exc.response else str(exc) raise HTTPException(status_code=exc.response.status_code if exc.response else 502, detail=detail) from exc except Exception as exc: raise HTTPException(status_code=502, detail=str(exc)) from exc @router.get("/api/packaging/projects") async def proxy_packaging_projects(limit: int = 30): try: async with httpx.AsyncClient(timeout=30.0) as client: r = await client.get( f"{settings.TOOLS_API_URL.rstrip('/')}/packaging/projects", params={"limit": limit}, ) r.raise_for_status() return r.json() except httpx.HTTPStatusError as exc: detail = exc.response.text[:400] if exc.response else str(exc) raise HTTPException(status_code=exc.response.status_code if exc.response else 502, detail=detail) from exc except Exception as exc: raise HTTPException(status_code=502, detail=str(exc)) from exc @router.get("/api/packaging/download/{project_id}") async def proxy_packaging_download(project_id: str, format: str = "svg"): try: async with httpx.AsyncClient(timeout=120.0) as client: r = await client.get( f"{settings.TOOLS_API_URL.rstrip('/')}/packaging/download/{project_id}", params={"format": format}, ) r.raise_for_status() media = r.headers.get("content-type", "application/octet-stream") disposition = r.headers.get("content-disposition") headers = {"content-disposition": disposition} if disposition else {} return Response(content=r.content, media_type=media, headers=headers) except httpx.HTTPStatusError as exc: detail = exc.response.text[:400] if exc.response else str(exc) raise HTTPException(status_code=exc.response.status_code if exc.response else 502, detail=detail) from exc except Exception as exc: raise HTTPException(status_code=502, detail=str(exc)) from exc