123
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user