129 lines
4.0 KiB
Python
129 lines
4.0 KiB
Python
from typing import AsyncIterator, Optional
|
|
|
|
from external.marketplace.base.core import BaseMarketplaceApi
|
|
from models import Marketplace
|
|
from utils.list_utils import chunk_list
|
|
|
|
|
|
class YandexMarketplaceApi(BaseMarketplaceApi):
|
|
def __init__(self, marketplace: Marketplace):
|
|
token = marketplace.auth_data.get('Api-Key')
|
|
if not token:
|
|
raise ValueError(
|
|
f"Authorization token is missing for Marketplace ID: {marketplace.id}. "
|
|
"Please check the marketplace credentials."
|
|
)
|
|
self.token = token
|
|
self.headers = {'Api-Key': token}
|
|
self.marketplace = marketplace
|
|
|
|
@property
|
|
def get_headers(self) -> dict:
|
|
return self.headers
|
|
|
|
@property
|
|
def base_url(self) -> str:
|
|
return 'https://api.partner.market.yandex.ru'
|
|
|
|
def _get_campaign_id(self) -> Optional[int]:
|
|
campaign_id: Optional[str] = self.marketplace.auth_data.get('CampaignId')
|
|
if not campaign_id:
|
|
return None
|
|
if not str(campaign_id).isdigit():
|
|
return None
|
|
return int(campaign_id)
|
|
|
|
async def get_campaigns(self) -> AsyncIterator[dict]:
|
|
method = '/campaigns'
|
|
page = 1
|
|
while True:
|
|
params = {
|
|
'page': page,
|
|
}
|
|
response = await self._method('GET', method, params=params)
|
|
if not response:
|
|
break
|
|
campaigns = response.get('campaigns')
|
|
if not campaigns:
|
|
break
|
|
for campaign in campaigns:
|
|
yield campaign
|
|
|
|
pager = response.get('pager')
|
|
if not pager:
|
|
break
|
|
pages_count = pager.get('pagesCount')
|
|
if not pages_count:
|
|
break
|
|
if page >= pages_count:
|
|
break
|
|
page += 1
|
|
|
|
async def get_business_id(self, campaign_id: int) -> Optional[int]:
|
|
async for campaign in self.get_campaigns():
|
|
if campaign['id'] == campaign_id:
|
|
return campaign['business']['id']
|
|
return None
|
|
|
|
async def get_all_products(self) -> AsyncIterator[dict]:
|
|
campaign_id = self._get_campaign_id()
|
|
if not campaign_id:
|
|
return
|
|
business_id = await self.get_business_id(campaign_id)
|
|
if not business_id:
|
|
return
|
|
|
|
method = f'/businesses/{business_id}/offer-mappings'
|
|
limit = 200
|
|
page_token = ''
|
|
while True:
|
|
params = {
|
|
'limit': limit,
|
|
'page_token': page_token,
|
|
}
|
|
response = await self._method('POST', method, params=params)
|
|
if not response:
|
|
break
|
|
response = response.get('result')
|
|
if not response:
|
|
break
|
|
offers = response.get('offerMappings')
|
|
if not offers:
|
|
break
|
|
for offer in offers:
|
|
yield offer
|
|
paging = response.get('paging')
|
|
if not paging:
|
|
break
|
|
|
|
next_page_token = paging.get('nextPageToken')
|
|
if not next_page_token:
|
|
break
|
|
page_token = next_page_token
|
|
|
|
async def get_products_by_offer_ids(self, offer_ids: list[str]) -> AsyncIterator[dict]:
|
|
campaign_id = self._get_campaign_id()
|
|
if not campaign_id:
|
|
return
|
|
business_id = await self.get_business_id(campaign_id)
|
|
if not business_id:
|
|
return
|
|
|
|
method = f'/businesses/{business_id}/offer-mappings'
|
|
limit = 200
|
|
for chunk in chunk_list(offer_ids, limit):
|
|
params = {
|
|
'offer_ids': chunk,
|
|
}
|
|
response = await self._method('POST', method, params=params)
|
|
if not response:
|
|
break
|
|
response = response.get('result')
|
|
if not response:
|
|
break
|
|
offers = response.get('offerMappings')
|
|
if not offers:
|
|
break
|
|
for offer in offers:
|
|
yield offer
|