"""Реальный клиент Nova Poshta (`TrackingDocument.getStatusDocuments`).""" from __future__ import annotations import httpx from app.schemas.tracking import TrackingStatusOut from app.services.nova_poshta.client import NovaPoshtaError _API_URL = "https://api.novaposhta.ua/v2.0/json/" # NP отклоняет запросы с более чем 100 накладными за раз. _MAX_DOCUMENTS_PER_REQUEST = 100 class NpTrackingClient: async def get_statuses( self, *, api_key: str, waybill_numbers: list[str] ) -> list[TrackingStatusOut]: if not waybill_numbers: return [] if len(waybill_numbers) > _MAX_DOCUMENTS_PER_REQUEST: raise NovaPoshtaError( f"Забагато ТТН за один запит: {len(waybill_numbers)} " f"(максимум {_MAX_DOCUMENTS_PER_REQUEST})" ) body = { "apiKey": api_key, "modelName": "TrackingDocument", "calledMethod": "getStatusDocuments", "methodProperties": { "Documents": [{"DocumentNumber": number, "Phone": ""} for number in waybill_numbers] }, } async with httpx.AsyncClient(timeout=30) as client: response = await client.post(_API_URL, json=body) response.raise_for_status() data = response.json() if not data.get("success"): errors = data.get("errors") or [] message = "; ".join(str(error) for error in errors) raise NovaPoshtaError(f"NP повернув помилку: {message or 'невідома помилка'}") return [TrackingStatusOut.model_validate(item) for item in data.get("data", [])]