55 lines
1.7 KiB
Python
55 lines
1.7 KiB
Python
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
|