import httpx class ApiError(Exception): def __init__(self, detail: str) -> None: super().__init__(detail) self.detail = detail class ShopApi: def __init__(self, base_url: str, secret: str) -> None: self.client = httpx.AsyncClient( base_url=base_url.rstrip("/"), headers={"X-Bot-Secret": secret}, timeout=10, ) async def close(self) -> None: await self.client.aclose() async def _request(self, method: str, path: str, json: dict | None = None): response = await self.client.request(method, path, json=json) if response.status_code >= 400: detail = "Ошибка запроса" try: body = response.json() if isinstance(body.get("detail"), str): detail = body["detail"] except Exception: pass raise ApiError(detail) if response.status_code == 204 or not response.content: return None return response.json() async def products(self) -> list[dict]: data = await self._request("GET", "/products?limit=100") return data["products"] async def product(self, product_id: int) -> dict: return await self._request("GET", f"/products/{product_id}") async def add(self, telegram_user_id: int, product_id: int) -> dict: return await self._request( "POST", "/internal/cart/items", {"telegram_user_id": telegram_user_id, "product_id": product_id, "qty": 1}, ) async def cart(self, telegram_user_id: int) -> dict: return await self._request("GET", f"/internal/cart/{telegram_user_id}") async def dialog(self, telegram_user_id: int) -> dict | None: return await self._request("GET", f"/internal/dialog/{telegram_user_id}") async def save_dialog(self, telegram_user_id: int, step: str, name: str | None) -> dict: return await self._request( "PUT", f"/internal/dialog/{telegram_user_id}", {"step": step, "name": name}, ) async def clear_dialog(self, telegram_user_id: int) -> None: await self._request("DELETE", f"/internal/dialog/{telegram_user_id}") async def order(self, telegram_user_id: int, name: str, phone: str) -> dict: return await self._request( "POST", "/internal/orders", {"telegram_user_id": telegram_user_id, "customer_name": name, "customer_phone": phone}, )