import asyncio from typing import TYPE_CHECKING from marketplaces import WildberriesMarketplaceApi from sender.base import SendStockStatus, BaseStocksSender if TYPE_CHECKING: from updaters.base import BaseMarketplaceUpdater class WildberriesStocksSender(BaseStocksSender): def __init__(self, updater: "BaseMarketplaceUpdater"): super().__init__(updater) self.remaining = 1 self.sleep_time = 60 / 300 @property def max_retries(self) -> int: return 5 async def _process_chunk(self, chunk: list[dict]) -> SendStockStatus: response = await self.api.update_stocks(chunk) headers = response.headers status_code = response.status if status_code in [ 401, # Invalid token 403, # Access denied 404, # Not found 400, # Other ]: return SendStockStatus.ERROR # If there is rate limit if status_code == 429: delay_time = float(headers.get('X-Ratelimit-Reset', self.sleep_time)) await asyncio.sleep(delay_time) self.remaining = int(headers.get('X-Ratelimit-Limit', 1)) return SendStockStatus.SHOULD_RETRY self.remaining = int(headers.get('X-Ratelimit-Remaining', 0)) return SendStockStatus.SUCCESS async def after_chunk_processed(self): if self.remaining <= 0: await asyncio.sleep(self.sleep_time) self.remaining = 1 async def before_chunk_processed(self): if self.remaining <= 0: await asyncio.sleep(self.sleep_time) self.remaining = 1 @property def chunk_size(self) -> int: return 1000