Files
foodlinkk-command-center/tools-api/app/packaging_routes.py
T

81 lines
2.8 KiB
Python
Raw Normal View History

"""Packaging generation API routes."""
from __future__ import annotations
from datetime import datetime
from typing import Any, Literal
from uuid import uuid4
from fastapi import APIRouter, HTTPException, Query
from fastapi.responses import Response
from pydantic import BaseModel, Field
from app.packaging.export import svg_to_pdf_bytes, svg_to_png_bytes
from app.packaging.generator import FOODLINKK_BRAND, generate_packaging
router = APIRouter(prefix="/packaging", tags=["packaging"])
_PROJECTS: dict[str, dict[str, Any]] = {}
class PackagingSpec(BaseModel):
type: Literal["folding_box", "wrap", "round_label"]
width_mm: float = Field(default=120, gt=0, le=4000)
height_mm: float = Field(default=80, gt=0, le=4000)
depth_mm: float = Field(default=40, ge=0, le=4000)
elements: dict[str, bool] = Field(default_factory=dict)
brand: dict[str, str] = Field(default_factory=dict)
barcode_value: str | None = Field(default=None, max_length=64)
@router.post("/generate")
def packaging_generate(spec: PackagingSpec) -> dict[str, Any]:
spec_data = spec.model_dump()
if not spec_data["brand"]:
spec_data["brand"] = dict(FOODLINKK_BRAND)
svg = generate_packaging(spec_data)
project_id = uuid4().hex
now = datetime.utcnow().isoformat() + "Z"
_PROJECTS[project_id] = {
"id": project_id,
"created_at": now,
"spec": spec_data,
"svg": svg,
}
return {"id": project_id, "created_at": now, "svg": svg, "spec": spec_data}
@router.get("/projects")
def packaging_projects(limit: int = Query(default=30, ge=1, le=200)) -> dict[str, Any]:
items = sorted(_PROJECTS.values(), key=lambda x: x["created_at"], reverse=True)[:limit]
return {
"items": [{"id": p["id"], "created_at": p["created_at"], "spec": p["spec"]} for p in items],
"count": len(items),
}
@router.get("/download/{project_id}")
def packaging_download(project_id: str, format: str = Query(default="svg", pattern="^(svg|png|pdf)$")):
project = _PROJECTS.get(project_id)
if not project:
raise HTTPException(status_code=404, detail="Packaging project not found")
svg = project["svg"]
filename = f"foodlinkk-packaging-{project_id[:8]}.{format}"
if format == "svg":
return Response(
content=svg.encode("utf-8"),
media_type="image/svg+xml",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
if format == "png":
return Response(
content=svg_to_png_bytes(svg),
media_type="image/png",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
return Response(
content=svg_to_pdf_bytes(svg),
media_type="application/pdf",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)