This commit is contained in:
2024-07-02 08:55:24 +03:00
parent 386ee7e460
commit 7ba3426989
18 changed files with 228 additions and 155 deletions

View File

@@ -1,3 +1,3 @@
from .ozon import OzonMarketplace
from .wildberries import WildberriesMarketplace
from .factory import MarketplaceFactory
from .ozon import OzonMarketplaceApi
from .wildberries import WildberriesMarketplaceApi
from .factory import MarketplaceApiFactory

View File

@@ -7,7 +7,7 @@ from aiohttp import ClientResponse
from database import Marketplace
class BaseJsonMarketplace(ABC):
class BaseMarketplaceApi(ABC):
@abstractmethod
def __init__(self, marketplace: Marketplace):
pass
@@ -20,18 +20,17 @@ class BaseJsonMarketplace(ABC):
def get_headers(self):
pass
@abstractmethod
@property
@abstractmethod
def api_url(self):
pass
async def _method(self, http_method: Literal['POST', 'GET', 'PATCH', 'PUT', 'DELETE'],
method: str,
data: dict) -> ClientResponse:
async with aiohttp.ClientSession as session:
async with session.request(http_method,
f'{self.api_url}{method}',
json=data,
headers=self.get_headers()
) as response:
return response
async with aiohttp.ClientSession() as session:
return await session.request(http_method,
f'{self.api_url}{method}',
json=data,
headers=self.get_headers()
)

View File

@@ -2,18 +2,18 @@ from typing import Union
from database import Marketplace
from database.sipro.enums.general import BaseMarketplace
from .wildberries import WildberriesMarketplace
from .ozon import OzonMarketplace
from .wildberries import WildberriesMarketplaceApi
from .ozon import OzonMarketplaceApi
class MarketplaceFactory:
class MarketplaceApiFactory:
@staticmethod
def get_marketplace(marketplace: Marketplace) -> Union[
WildberriesMarketplace,
OzonMarketplace,
def get_marketplace_api(marketplace: Marketplace) -> Union[
WildberriesMarketplaceApi,
OzonMarketplaceApi,
]:
match marketplace.base_marketplace:
case BaseMarketplace.OZON:
return OzonMarketplace(marketplace)
return OzonMarketplaceApi(marketplace)
case BaseMarketplace.WILDBERRIES:
return WildberriesMarketplace(marketplace)
return WildberriesMarketplaceApi(marketplace)

View File

@@ -1,17 +1,15 @@
import asyncio
import json
import logging
from typing import Union
from aiolimiter import AsyncLimiter
from asynciolimiter import StrictLimiter
import utils
from database import Marketplace
from limiter import BatchLimiter
from marketplaces.base import BaseJsonMarketplace
from marketplaces.base import BaseMarketplaceApi
class OzonMarketplace(BaseJsonMarketplace):
class OzonMarketplaceApi(BaseMarketplaceApi):
def __init__(self, marketplace: Marketplace):
self.marketplace = marketplace
@@ -25,6 +23,7 @@ class OzonMarketplace(BaseJsonMarketplace):
def get_headers(self):
return self.headers
@property
def api_url(self):
return 'https://api-seller.ozon.ru'
@@ -33,22 +32,23 @@ class OzonMarketplace(BaseJsonMarketplace):
return
max_stocks = 100
chunks = utils.chunk_list(data, max_stocks)
limiter = BatchLimiter(max_requests=80,
period=60)
for chunk in chunks:
limiter = BatchLimiter(max_requests=80, period=60)
async def send_stock_chunk(chunk):
try:
await limiter.acquire()
response = await self._method('POST',
'/v2/products/stocks',
data=chunk)
request_data = {'stocks': chunk}
response = await self._method('POST', '/v2/products/stocks', data=request_data)
print(request_data)
response = await response.json()
# response = await
error_message = response.get('message')
error_code = response.get('code')
if error_message:
logging.warning(
f'Error occurred when sending stocks to [{self.marketplace.id}]: {error_message} ({error_code})')
break
except Exception as e:
logging.error(
f'Exception occurred while sending stocks to marketplace ID [{self.marketplace.id}]: {str(e)}')
tasks = [send_stock_chunk(chunk) for chunk in chunks]
await asyncio.gather(*tasks)

View File

@@ -1,3 +1,4 @@
import asyncio
import json
import logging
from typing import Union
@@ -5,10 +6,10 @@ from typing import Union
import utils
from database import Marketplace
from limiter import BatchLimiter
from marketplaces.base import BaseJsonMarketplace
from marketplaces.base import BaseMarketplaceApi
class WildberriesMarketplace(BaseJsonMarketplace):
class WildberriesMarketplaceApi(BaseMarketplaceApi):
def __init__(self, marketplace: Marketplace):
self.marketplace = marketplace
auth_data = json.loads(marketplace.auth_data)
@@ -21,6 +22,7 @@ class WildberriesMarketplace(BaseJsonMarketplace):
def get_headers(self):
return self.headers
@property
def api_url(self):
return 'https://suppliers-api.wildberries.ru'
@@ -29,21 +31,24 @@ class WildberriesMarketplace(BaseJsonMarketplace):
return
max_stocks = 1000
chunks = utils.chunk_list(data, max_stocks)
limiter = BatchLimiter(max_requests=300,
period=60)
for chunk in chunks:
limiter = BatchLimiter(max_requests=300, period=60)
async def send_stock_chunk(chunk):
try:
await limiter.acquire()
response = await self._method('PUT',
'/api/v3/stocks/{warehouseId}',
chunk)
if response.status != 204:
request_data = {'stocks': chunk}
response = await self._method('PUT', f'/api/v3/stocks/{self.marketplace.warehouse_id}',
data=request_data)
print(request_data)
if response.status not in [204, 409]:
response = await response.json()
error_message = response.get('message')
error_code = response.get('code')
logging.warning(
f'Error occurred when sending stocks to [{self.marketplace.id}]: {error_message} ({error_code})')
break
except Exception as e:
logging.error(
f'Exception occurred while sending stocks to marketplace ID [{self.marketplace.id}]: {str(e)}')
tasks = [send_stock_chunk(chunk) for chunk in chunks]
await asyncio.gather(*tasks)