from typing import Annotated from fastapi import APIRouter, HTTPException, Query, Response from app.deps import SessionDep from app.schemas import CatalogOut, ProductOut from app.services import _product_out, catalog, product_detail from app.storage import get_object router = APIRouter() @router.get("/products", response_model=CatalogOut) async def list_products( db: SessionDep, category_id: int | None = None, sort: Annotated[str, Query(pattern=r"^(price_asc|price_desc|new)$")] = "price_asc", limit: Annotated[int, Query(ge=1, le=100)] = 20, ) -> CatalogOut: return await catalog(db, category_id=category_id, sort=sort, limit=limit) @router.get("/products/{product_id}", response_model=ProductOut) async def get_product(product_id: int, db: SessionDep) -> ProductOut: product, category_name = await product_detail(db, product_id) return _product_out(product, category_name) @router.get("/products/{product_id}/image") async def product_image(product_id: int, db: SessionDep) -> Response: product, _category_name = await product_detail(db, product_id) if not product.image_key: raise HTTPException(status_code=404, detail="Изображение не найдено") payload, media_type = await get_object(product.image_key) return Response(content=payload, media_type=media_type)