Skip to content

Commit 67db752

Browse files
committed
prepare to release
1 parent de0e1f0 commit 67db752

7 files changed

Lines changed: 109 additions & 66 deletions

File tree

chizhik_api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from .manager import ChizhikAPI
22

33
__all__ = ["ChizhikAPI"]
4-
__version__ = "0.2.4"
4+
__version__ = "0.2.5"

chizhik_api/abstraction.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
class DeliveryMode:
32
"""Я хз что это такое"""
43

chizhik_api/endpoints/catalog.py

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,36 @@ async def tree(self, city_id: Optional[str] = None) -> FetchResponse:
3939
if city_id:
4040
url += f"?city_id={city_id}"
4141
return await self._parent._request(HttpMethod.GET, url)
42-
42+
4343
@autotest
44-
async def delivery_tree(self,
45-
store_id: str,
46-
mode: DeliveryMode = DeliveryMode.STORE,
47-
include_restrict: bool = True):
44+
async def delivery_tree(
45+
self,
46+
store_id: str,
47+
mode: DeliveryMode = DeliveryMode.STORE,
48+
include_restrict: bool = True,
49+
):
4850
url = f"{self._parent.DELIVERY_API_URL}/catalog/v3/stores/{store_id}/categories?mode={mode}&include_subcategories=1&include_restrict={str(include_restrict).lower()}"
4951
return await self._parent._request(HttpMethod.GET, url)
5052

5153
@autotest
52-
async def delivery_tree_extended(self,
53-
store_id: str,
54-
category_alias: str,
55-
mode: DeliveryMode = DeliveryMode.STORE,
56-
include_restrict: bool = True):
54+
async def delivery_tree_extended(
55+
self,
56+
store_id: str,
57+
category_alias: str,
58+
mode: DeliveryMode = DeliveryMode.STORE,
59+
include_restrict: bool = True,
60+
):
5761
url = f"{self._parent.DELIVERY_API_URL}/catalog/v2/stores/{store_id}/categories/{category_alias}/extended?mode={mode}&include_restrict={str(include_restrict).lower()}"
5862
return await self._parent._request(HttpMethod.GET, url)
5963

6064
@autotest
61-
async def delivery_tree_ancestors(self,
62-
store_id: str,
63-
category_alias: str,
64-
mode: DeliveryMode = DeliveryMode.STORE,
65-
include_restrict: bool = True):
65+
async def delivery_tree_ancestors(
66+
self,
67+
store_id: str,
68+
category_alias: str,
69+
mode: DeliveryMode = DeliveryMode.STORE,
70+
include_restrict: bool = True,
71+
):
6672
url = f"{self._parent.DELIVERY_API_URL}/catalog/v3/stores/{store_id}/categories/{category_alias}/ancestors?mode={mode}&include_restrict={str(include_restrict).lower()}"
6773
return await self._parent._request(HttpMethod.GET, url)
6874

@@ -85,26 +91,31 @@ async def products_list(
8591
return await self._parent._request(HttpMethod.GET, url)
8692

8793
@autotest
88-
async def delivery_products_list(self,
89-
store_id: str,
90-
category_alias: str,
91-
offset: int = 0,
92-
limit: int = 499,
93-
mode: DeliveryMode = DeliveryMode.STORE,
94-
include_restrict: bool = True):
94+
async def delivery_products_list(
95+
self,
96+
store_id: str,
97+
category_alias: str,
98+
offset: int = 0,
99+
limit: int = 499,
100+
mode: DeliveryMode = DeliveryMode.STORE,
101+
include_restrict: bool = True,
102+
):
95103
url = f"{self._parent.DELIVERY_API_URL}/catalog/v2/stores/{store_id}/categories/{category_alias}/products?mode={mode}&include_restrict={str(include_restrict).lower()}&limit={limit}&offset={offset}"
96104
return await self._parent._request(HttpMethod.GET, url)
97105

98106
@autotest
99-
async def delivery_search(self,
100-
store_id: str,
101-
query: str,
102-
limit: int = 12,
103-
mode: DeliveryMode = DeliveryMode.STORE,
104-
include_restrict: bool = True):
107+
async def delivery_search(
108+
self,
109+
store_id: str,
110+
query: str,
111+
limit: int = 12,
112+
mode: DeliveryMode = DeliveryMode.STORE,
113+
include_restrict: bool = True,
114+
):
105115
url = f"{self._parent.DELIVERY_API_URL}/catalog/v3/stores/{store_id}/search?mode={mode}&include_restrict={str(include_restrict).lower()}&q={query}&limit={limit}"
106116
return await self._parent._request(HttpMethod.GET, url)
107117

118+
108119
class ProductService(ApiChild["ChizhikAPI"]):
109120
"""Сервис для работы с товарами в каталоге."""
110121

@@ -126,13 +137,15 @@ async def info(
126137
if city_id:
127138
url += f"?city_id={city_id}"
128139
return await self._parent._request(HttpMethod.GET, url)
129-
140+
130141
@autotest
131-
async def delivery_info(self,
132-
store_id: str,
133-
product_id: int,
134-
mode: DeliveryMode = DeliveryMode.STORE,
135-
include_restrict: bool = True):
142+
async def delivery_info(
143+
self,
144+
store_id: str,
145+
product_id: int,
146+
mode: DeliveryMode = DeliveryMode.STORE,
147+
include_restrict: bool = True,
148+
):
136149
# TODO
137150
url = f"{self._parent.DELIVERY_API_URL}/catalog/v2/stores/{store_id}/products/{product_id}?mode={mode}&include_restrict={str(include_restrict).lower()}"
138151
return await self._parent._request(HttpMethod.GET, url)

chizhik_api/endpoints/general.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ async def download_image(
2828
attempts=retry_attempts, start_timeout=3.0, max_timeout=timeout
2929
)
3030

31-
px = self._parent.proxy if isinstance(self._parent.proxy, Proxy) else Proxy(self._parent.proxy)
31+
px = (
32+
self._parent.proxy
33+
if isinstance(self._parent.proxy, Proxy)
34+
else Proxy(self._parent.proxy)
35+
)
3236
async with RetryClient(retry_options=retry_options) as retry_client:
3337
async with retry_client.get(
3438
url,

chizhik_api/endpoints/geolocation.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
from __future__ import annotations
44

5-
from typing import TYPE_CHECKING
65
from dataclasses import dataclass
6+
from typing import TYPE_CHECKING
77

88
from human_requests import ApiChild, ApiParent, api_child_field, autotest
99
from human_requests.abstraction import FetchResponse, HttpMethod
@@ -23,7 +23,6 @@ class ClassGeolocation(ApiChild["ChizhikAPI"]):
2323
Shop: ShopService = api_child_field(lambda parent: ShopService(parent.parent))
2424
"""Сервис для работы с информацией о магазинах."""
2525

26-
2726
def __init__(self, parent: "ChizhikAPI"):
2827
super().__init__(parent)
2928
ApiParent.__post_init__(self)
@@ -36,6 +35,7 @@ async def cities_list(self, search_name: str, page: int = 1) -> FetchResponse:
3635
f"{self._parent.API_URL}/v1/geo/cities/?name={search_name}&page={page}",
3736
)
3837

38+
3939
class ShopService(ApiChild["ChizhikAPI"]):
4040
"""Сервис для работы с информацией о магазинах."""
4141

@@ -44,7 +44,7 @@ async def all(self) -> FetchResponse:
4444
"""Получить список всех точек магазинов."""
4545
url = f"{self._parent.API_URL}/v1/shops"
4646
return await self._parent._request(HttpMethod.GET, url)
47-
47+
4848
@autotest
4949
async def search(self, query: str) -> FetchResponse:
5050
"""Получить список всех точек магазинов."""

chizhik_api/manager.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from __future__ import annotations
22

3+
import asyncio
34
from collections import defaultdict
45
from dataclasses import dataclass, field
56
from typing import Any
6-
import asyncio
77

88
from camoufox.async_api import AsyncCamoufox
99
from human_requests import (
@@ -13,13 +13,8 @@
1313
HumanPage,
1414
api_child_field,
1515
)
16-
from human_requests.network_analyzer.anomaly_sniffer import (
17-
HeaderAnomalySniffer,
18-
WaitHeader,
19-
WaitSource,
20-
)
2116
from human_requests.abstraction import FetchResponse, HttpMethod, Proxy
22-
from playwright.async_api import TimeoutError as PWTimeoutError
17+
from human_requests.network_analyzer.anomaly_sniffer import HeaderAnomalySniffer
2318

2419
from .endpoints.advertising import ClassAdvertising
2520
from .endpoints.catalog import ClassCatalog
@@ -104,6 +99,7 @@ async def _warmup(self) -> None:
10499
await sniffer.start(self.ctx)
105100

106101
collected = {}
102+
107103
def on_request(request):
108104
if request.url.startswith(self.API_URL):
109105
collected[request.url] = request.headers
@@ -113,11 +109,15 @@ def on_request(request):
113109
await self.page.goto(self.MAIN_SITE_URL, wait_until="networkidle")
114110
await self.page.wait_for_selector("next-route-announcer", state="attached")
115111
await asyncio.sleep(1)
116-
await self.page.locator('main a[data-qa^="sidebar-sub-category-"][data-qa$="-link"]').first.click()
117-
await self.page.locator('main div[itemtype="https://schema.org/Product"]').first.click()
112+
await self.page.locator(
113+
'main a[data-qa^="sidebar-sub-category-"][data-qa$="-link"]'
114+
).first.click()
115+
await self.page.locator(
116+
'main div[itemtype="https://schema.org/Product"]'
117+
).first.click()
118118
await asyncio.sleep(1)
119119
await self.page.wait_for_load_state("load")
120-
120+
121121
await self.ctx.unroute("**/api/**", on_request)
122122
result_sniffer = await sniffer.complete()
123123

@@ -127,7 +127,9 @@ def on_request(request):
127127
# Проходим по всем URL в 'request'
128128
for _url, headers in result_sniffer["request"].items():
129129
for header, values in headers.items():
130-
result[header].update(values) # добавляем значения, set уберёт дубли
130+
result[header].update(
131+
values
132+
) # добавляем значения, set уберёт дубли
131133

132134
# Преобразуем set обратно в list
133135
self.unstandard_headers = {k: list(v)[0] for k, v in result.items()}

tests/api_test.py

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
from typing import Any
22

33
import pytest
4-
from human_requests import autotest_depends_on, autotest_hook, autotest_params, autotest_data
5-
from human_requests.autotest import AutotestCallContext, AutotestContext,AutotestDataContext
6-
4+
from human_requests import (
5+
autotest_data,
6+
autotest_depends_on,
7+
autotest_hook,
8+
autotest_params,
9+
)
10+
from human_requests.autotest import (
11+
AutotestCallContext,
12+
AutotestContext,
13+
AutotestDataContext,
14+
)
715
from PIL import Image
816

917
from chizhik_api import ChizhikAPI
@@ -69,25 +77,32 @@ def _capture_first_store_id(
6977
def _delivery_tree(ctx: AutotestContext):
7078
return {"store_id": ctx.state["autotest_store_id"]}
7179

80+
7281
@autotest_depends_on(ShopService.search)
7382
@autotest_depends_on(ClassCatalog.delivery_tree)
7483
@autotest_params(target=ClassCatalog.delivery_tree_extended)
7584
def _delivery_tree_extended(ctx: AutotestContext):
76-
return {"store_id": ctx.state["autotest_store_id"],
77-
"category_alias": ctx.state.get("autotest_category_alias")}
85+
return {
86+
"store_id": ctx.state["autotest_store_id"],
87+
"category_alias": ctx.state.get("autotest_category_alias"),
88+
}
89+
7890

7991
@autotest_depends_on(ShopService.search)
8092
@autotest_depends_on(ClassCatalog.delivery_tree)
8193
@autotest_params(target=ClassCatalog.delivery_products_list)
8294
def _delivery_products_list(ctx: AutotestContext):
83-
return {"store_id": ctx.state["autotest_store_id"],
84-
"category_alias": ctx.state.get("autotest_category_alias")}
95+
return {
96+
"store_id": ctx.state["autotest_store_id"],
97+
"category_alias": ctx.state.get("autotest_category_alias"),
98+
}
99+
85100

86101
@autotest_depends_on(ShopService.search)
87102
@autotest_params(target=ClassCatalog.delivery_search)
88103
def _delivery_search(ctx: AutotestContext):
89-
return {"store_id": ctx.state["autotest_store_id"],
90-
"query": "кола"}
104+
return {"store_id": ctx.state["autotest_store_id"], "query": "кола"}
105+
91106

92107
@autotest_hook(target=ClassCatalog.delivery_products_list)
93108
def _capture_first_plu(
@@ -100,15 +115,21 @@ def _capture_first_plu(
100115

101116
store_id = data.get("products")
102117
if not isinstance(store_id, list):
103-
pytest.fail("ClassCatalog.delivery_products_list did not return a valid category id.")
118+
pytest.fail(
119+
"ClassCatalog.delivery_products_list did not return a valid category id."
120+
)
104121

105122
ctx.state["autotest_plu"] = store_id[0]["plu"]
106123

124+
107125
@autotest_depends_on(ClassCatalog.delivery_tree)
108126
@autotest_params(target=ProductService.delivery_info)
109127
def _delivery_info(ctx: AutotestContext):
110-
return {"store_id": ctx.state["autotest_store_id"],
111-
"product_id": ctx.state.get("autotest_plu")}
128+
return {
129+
"store_id": ctx.state["autotest_store_id"],
130+
"product_id": ctx.state.get("autotest_plu"),
131+
}
132+
112133

113134
@autotest_hook(target=ClassCatalog.delivery_tree_extended)
114135
def _capture_first_subcategory_alias(
@@ -125,12 +146,16 @@ def _capture_first_subcategory_alias(
125146

126147
ctx.state["autotest_subcategory_alias"] = store_id[0]["id"]
127148

149+
128150
@autotest_depends_on(ShopService.search)
129151
@autotest_depends_on(ClassCatalog.delivery_tree_extended)
130152
@autotest_params(target=ClassCatalog.delivery_tree_ancestors)
131153
def _delivery_tree_ancestors(ctx: AutotestContext):
132-
return {"store_id": ctx.state["autotest_store_id"],
133-
"category_alias": ctx.state.get("autotest_subcategory_alias")}
154+
return {
155+
"store_id": ctx.state["autotest_store_id"],
156+
"category_alias": ctx.state.get("autotest_subcategory_alias"),
157+
}
158+
134159

135160
@autotest_depends_on(ClassCatalog.tree)
136161
@autotest_params(target=ClassCatalog.products_list)
@@ -189,11 +214,11 @@ def _product_info_params(ctx: AutotestCallContext) -> dict[str, int]:
189214
pytest.fail("ProductService.info depends on Catalog.products_list.")
190215

191216

192-
193217
@autotest_data(name="unstandard_headers")
194218
def _unstandard_headers_data(ctx: AutotestDataContext) -> dict[str, Any]:
195219
return ctx.api.unstandard_headers
196220

221+
197222
@autotest_data(name="unstandard_urls")
198223
def _unstandard_urls_data(ctx: AutotestDataContext) -> dict[str, Any]:
199224
return ctx.api.unstandard_urls

0 commit comments

Comments
 (0)