From 273b11f5e1e5d1386645ed80fc276d764d839c5a Mon Sep 17 00:00:00 2001 From: Anatoly Raev Date: Mon, 8 Jan 2024 22:14:29 +0300 Subject: [PATCH] write better docs, fix exception handling errors --- README.md | 70 +++++++++++++++++++++++++-- marketplace_apis/__init__.py | 2 +- marketplace_apis/ozon/seller_api.py | 40 +++++++-------- marketplace_apis/yandex/market_api.py | 46 ++++++++---------- 4 files changed, 109 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 11735bc..c6dba58 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,73 @@ Easy way to communicate with russian marketplaces! -## Currently supported apis: +## Features: +* Fully async +* Uses httpx and mashumaro - blazing fast! +* Easy and not verbose to use +* Supports Ozon SellerAPI and Yandex MarketAPI - support for Wildberries API planned -#### OZON Seller api +## Usage example +### Ozon SellerAPI + +```python +import asyncio +from datetime import datetime, timedelta +from marketplace_apis.ozon.seller_api import SellerApi +import os + + +async def main(): + async with SellerApi(os.getenv("API_KEY"), os.getenv("CLIENT_ID")) as client: + # print all postings from 14 days before now to now: + now = datetime.now() + postings = await client.posting.list_postings( + filter_since=now - timedelta(14), + filter_to=now) + print(postings) + # get product infos and attributes from first posting products concurrently + async with asyncio.TaskGroup() as tg: + posting = postings[0] + offer_ids = [product.offer_id for product in posting.products] + info = tg.create_task(client.product.list_info(["112026854"])) + attributes = tg.create_task( + client.product.list_attributes(offer_id=["112026854"])) + print(info.result(), attributes.result()) + +asyncio.run(main()) +``` +### Yandex MarketAPI + +```python +import asyncio +from datetime import datetime, timedelta +from marketplace_apis.yandex.market_api import MarketApi +import os + + +async def main(): + # you don't have to pass campaign_id or business_id, + # if you will not use methods, that require them + async with MarketApi(os.getenv("TOKEN"), os.getenv("CAMPAIGN_ID"), + os.getenv("BUSINESS_ID")) as client: + # print all orders from 14 days before now to now: + now = datetime.now() + orders = await client.order.list_orders( + fromDate=(now - timedelta(14)).date(), + toDate=now.date()) + print(orders) + # get offer_mappings of first order items + order = orders[0] + offer_ids = [item.offerId for item in order.items] + offer_mappings = await client.offer_mapping.list_offer_mappings(offerIds=offer_ids) + print(offer_mappings) + +asyncio.run(main()) +``` + +## Currently supported api endpoints: + +#### OZON SellerAPI Supports endpoints for: @@ -13,7 +77,7 @@ Supports endpoints for: * posting, * product. -#### YANDEX MARKET api +#### Yandex MarketAPI Supports endpoints for: diff --git a/marketplace_apis/__init__.py b/marketplace_apis/__init__.py index 746be8a..6952905 100644 --- a/marketplace_apis/__init__.py +++ b/marketplace_apis/__init__.py @@ -14,4 +14,4 @@ """Easy way to communicate with russian marketplaces""" -__version__ = "2.0.0" +__version__ = "2.0.1" diff --git a/marketplace_apis/ozon/seller_api.py b/marketplace_apis/ozon/seller_api.py index c10af13..141628c 100644 --- a/marketplace_apis/ozon/seller_api.py +++ b/marketplace_apis/ozon/seller_api.py @@ -45,7 +45,7 @@ class SellerApi(AsyncRequester): async def check_for_errors(func, self, *args, **kwargs): response_, data = await func(self, *args, **kwargs) if response_.status_code != HTTPStatus.OK: - raise SellerApiError(response_.json()) + raise SellerApiError(response_.status_code, response_.json()) return response_, data def __init__( @@ -66,9 +66,10 @@ def __init__( if __name__ == "__main__": from pathlib import Path - import time import os + import asyncio from datetime import datetime, timedelta + from marketplace_apis.ozon.seller_api import SellerApi with Path.open(".env", "r") as f: for line in f.readlines(): @@ -76,21 +77,22 @@ def __init__( k, v = line.split("=") os.environ[k] = v.strip() - async def async_function(): - start_time = datetime.now() - start_time_count = time.monotonic() - async with (os.getenv("API_KEY"), os.getenv("CLIENT_ID")) as client: - print( # noqa: T201 - await client.posting.list_postings( - filter_since=start_time - timedelta(14), - filter_to=start_time + timedelta(14), - ) + async def main(): + async with SellerApi(os.getenv("API_KEY"), os.getenv("CLIENT_ID")) as client: + # print all postings from 14 days before now to now: + now = datetime.now() + postings = await client.posting.list_postings( + filter_since=now - timedelta(14), filter_to=now ) - end_time = time.monotonic() - print(timedelta(seconds=end_time - start_time_count)) # noqa: T201 - - asyncio.run(async_function()) - # print(api.posting.label_task_get(45342209)) - # [print([attribute.values[0].value for attribute in product.attributes if - # attribute.attribute_id == 4191]) for product in - # api.product.list_attribute()] + print(postings) + # get product infos and attributes from first posting products concurrently + async with asyncio.TaskGroup() as tg: + posting = postings[0] + offer_ids = [product.offer_id for product in posting.products] + info = tg.create_task(client.product.list_info(["112026854"])) + attributes = tg.create_task( + client.product.list_attributes(offer_id=["112026854"]) + ) + print(info.result(), attributes.result()) + + asyncio.run(main()) diff --git a/marketplace_apis/yandex/market_api.py b/marketplace_apis/yandex/market_api.py index d6439bf..2386a51 100644 --- a/marketplace_apis/yandex/market_api.py +++ b/marketplace_apis/yandex/market_api.py @@ -23,8 +23,6 @@ from marketplace_apis.yandex.offer_mapping.methods import OfferMappingMethods from marketplace_apis.yandex.order.methods import OrderMethods - -# from marketplace_apis.yandex.order.methods import OrderMethods from marketplace_apis.yandex.warehouse.methods import WarehouseMethods @@ -48,7 +46,7 @@ class MarketApi(AsyncRequester): async def check_for_errors(func, self, *args, **kwargs): response_, data = await func(self, *args, **kwargs) if response_.status_code != HTTPStatus.OK: - raise MarketApiError(response_.json()) + raise MarketApiError(response_.status_code, response_.json()) return response_, data def build_campaign_url(self, endpoint): @@ -86,8 +84,7 @@ def __init__( if __name__ == "__main__": from pathlib import Path import os - import time - from datetime import timedelta + from datetime import timedelta, datetime with Path.open(".env", "r") as f: for line in f.readlines(): @@ -95,27 +92,24 @@ def __init__( k, v = line.split("=") os.environ[k] = v.strip() - async def async_function(): - start_time_count = time.monotonic() + async def main(): + # you don't have to pass campaign_id or business_id, + # if you will not use methods, that require them async with MarketApi( os.getenv("TOKEN"), os.getenv("CAMPAIGN_ID"), os.getenv("BUSINESS_ID") ) as client: - print(len(await client.offer_mapping.list_offer_mappings())) # noqa: T201 - end_time = time.monotonic() - print(timedelta(seconds=end_time - start_time_count)) # noqa: T201 - - asyncio.run(async_function()) - # print(api.warehouse.list_fby_warehouses()) - # print(api.warehouse.list_warehouses()) - # print(api.order.list_orders(status=OrderStatusType.PROCESSING)[-1]) - # print(MarketApi.oauth.get_tokens_by_code( - # os.getenv("CLIENT_ID"), - # os.getenv("CLIENT_SECRET"), 8863298 - # )) - # print( - # MarketApi.oauth.get_tokens_by_refresh( - # os.getenv("CLIENT_ID"), - # os.getenv("CLIENT_SECRET"), - # os.getenv("REFRESH_TOKEN"), - # ) - # ) + # print all orders from 14 days before now to now: + now = datetime.now() + orders = await client.order.list_orders( + fromDate=(now - timedelta(14)).date(), toDate=now.date() + ) + print(orders) + # get offer_mappings of first order items + order = orders[0] + offer_ids = [item.offerId for item in order.items] + offer_mappings = await client.offer_mapping.list_offer_mappings( + offerIds=offer_ids + ) + print(offer_mappings) + + asyncio.run(main())