Skip to content

Commit 11683c4

Browse files
committed
Update README.md
1 parent 9f4b981 commit 11683c4

1 file changed

Lines changed: 97 additions & 127 deletions

File tree

README.md

Lines changed: 97 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,131 @@
1-
# FixPrice API (not official / не официальный)
1+
<div align="center">
22

3-
FixPrice - https://fix-price.com/
3+
# FixPrice API (not official)
44

5-
# Usage / Использование
5+
![Tests last run (ISO)](https://img.shields.io/badge/dynamic/json?label=Tests%20last%20run&query=%24.workflow_runs%5B0%5D.updated_at&url=https%3A%2F%2Fapi.github.com%2Frepos%2FOpen-Inflation%2Ffixprice_api%2Factions%2Fworkflows%2Ftests.yml%2Fruns%3Fper_page%3D1%26status%3Dcompleted&logo=githubactions&cacheSeconds=300)
6+
[![Tests](https://github.com/Open-Inflation/fixprice_api/actions/workflows/tests.yml/badge.svg)](https://github.com/Open-Inflation/fixprice_api/actions/workflows/tests.yml)
7+
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/fixprice_api)
8+
![PyPI - Package Version](https://img.shields.io/pypi/v/fixprice_api?color=blue)
9+
[![PyPI - Downloads](https://img.shields.io/pypi/dm/fixprice_api?label=PyPi%20downloads)](https://pypi.org/project/fixprice-api/)
10+
[![License](https://img.shields.io/github/license/Open-Inflation/fixprice_api)](https://github.com/Open-Inflation/fixprice_api/blob/main/LICENSE)
11+
[![Discord](https://img.shields.io/discord/792572437292253224?label=Discord&labelColor=%232c2f33&color=%237289da)](https://discord.gg/UnJnGHNbBp)
12+
[![Telegram](https://img.shields.io/badge/Telegram-24A1DE)](https://t.me/miskler_dev)
613

7-
> `product_info` не реализован т.к. информация вшита в страницу.
14+
FixPrice (Фикс Прайс) - https://fix-price.com/
815

16+
**[⭐ Star us on GitHub](https://github.com/Open-Inflation/fixprice_api)** | **[📚 Read the Docs](https://open-inflation.github.io/fixprice_api/quick_start)** | **[🐛 Report Bug](https://github.com/Open-Inflation/fixprice_api/issues)**
17+
18+
### Принцип работы
19+
20+
</div>
21+
22+
> Библиотека полностью повторяет сетевую работу обычного пользователя на сайте.
23+
24+
<div align="center">
25+
26+
# Usage
27+
28+
</div>
29+
30+
```bash
31+
pip install fixprice_api
32+
python -m camoufox fetch
33+
```
934

10-
### Базовая структура
1135
```py
1236
import asyncio
13-
from fixprice_api import FixPrice, CatalogSort
37+
from fixprice_api import FixPriceAPI, CatalogSort
38+
from PIL import Image
39+
1440

1541
async def main():
16-
...
42+
async with FixPriceAPI() as api:
43+
# 1. Получаем дерево категорий
44+
tree_data = (await api.Catalog.tree()).json()
45+
first_alias = tree_data[next(iter(tree_data))]["alias"]
46+
print(f"Первая категория: {first_alias}")
47+
48+
# 2. Список товаров в категории
49+
products = (
50+
await api.Catalog.products_list(
51+
category_alias=first_alias,
52+
page=1,
53+
limit=24,
54+
sort=CatalogSort.POPULARITY,
55+
)
56+
).json()
57+
first_product_id = products[0]["id"]
58+
print(f"Первый товар: {products[0]['title']!s:.60s} ({first_product_id})")
59+
60+
# 3. Геолокация (влияет на каталог и баланс)
61+
cities = (await api.Geolocation.cities_list(country_id=2)).json() # Россия
62+
api.city_id = cities[0]["id"]
63+
print(f"Текущий city_id: {api.city_id}")
64+
65+
# 4. Проверка наличия товара по магазинам
66+
balance = (await api.Catalog.Product.balance(product_id=first_product_id)).json()
67+
print(f"Проверено магазинов: {len(balance)}")
68+
69+
# 5. Загрузка изображения
70+
image_url = products[0]["images"][0]["src"]
71+
image_stream = await api.General.download_image(image_url)
72+
with Image.open(image_stream) as img:
73+
print(f"Image format: {img.format}, size: {img.size}")
74+
1775

1876
if __name__ == "__main__":
1977
asyncio.run(main())
2078
```
2179

22-
### Взаимодействие с каталогом
23-
24-
```py
25-
async with FixPrice() as Api:
26-
# Получение списка категорий
27-
categories = await Api.Catalog.categories_list()
28-
products = []
29-
tq = tqdm(categories, desc='Обработано категорий')
30-
31-
async def process_sub(category_alias, subcategory_alias=None, depth=0):
32-
page = 1 # Счет от единицы, а не нуля!
33-
limit = 27 # Максимальное значение
34-
35-
while page > 0:
36-
# count - общее количество айтемов на всех страницах (в данном случае не используем)
37-
count, catalog = await Api.Catalog.products_list(
38-
category_alias=category_alias,
39-
subcategory_alias=subcategory_alias,
40-
page=page,
41-
limit=limit,
42-
sort=CatalogSort.POPULARITY
43-
)
44-
if not catalog:
45-
break
46-
47-
for product in catalog:
48-
products.append(f'{product["title"]} ({product["id"]})')
49-
tq.set_description(f'Обработано карточек: {len(products)}')
50-
51-
if len(catalog) <= 0:
52-
break
53-
54-
time.sleep(0.4) # Специально замедляем обработку, чтобы не получить код 429, советую эксперементировать
55-
page += 1
56-
57-
# Обход всех категорий и подкатегорий
58-
for category in tq:
59-
subcategories = category.get("items", [])
60-
# Можно и не обрабатывать подкатегории отдельно, зависит от желания и ТЗ
61-
if subcategories:
62-
for subcategory in subcategories:
63-
await process_sub(category["alias"], subcategory["alias"])
64-
else:
65-
await process_sub(category["alias"])
66-
67-
tq.close()
68-
69-
# Вывод статистики
70-
print(f'Общее количество встреченных карточек: {len(products)}')
71-
print(f'Уникальных товаров: {len(set(products))}')
72-
print(f'Среднее количество повторений карточки: {round(len(products) / len(set(products)), 2)}')
73-
```
7480
```bash
75-
> Обработано карточек: 6019: 100%|███████████████| 29/29 [04:29<00:00, 9.29s/it]
76-
> Общее количество встреченных карточек: 6019
77-
> Уникальных товаров: 4900
78-
> Среднее количество повторений карточки: 1.23
81+
> Первая категория: kosmetika-i-gigiena
82+
> Первый товар: Крем для рук и тела, 150 мл (2345678)
83+
> Текущий city_id: 3
84+
> Проверено магазинов: 339
85+
> Image format: WEBP, size: (190, 190)
7986
```
8087

81-
### Работа с геолокацией в сессии:
82-
*От геолокации зависит выдача каталога!*
83-
```py
84-
async with FixPrice() as Api:
85-
print(f"ID города перед первым запросом: {Api.city_id}, язык: {Api.language}") # По умолчанию не назначено
86-
await Api.Catalog.home_brands_list() # Можем обработать любую функцию
87-
print(f"ID города после первого запроса: {Api.city_id}, язык: {Api.language}") # Сервер прислал стандартные значения
88+
Для более подробной информации смотрите референсы [документации](https://open-inflation.github.io/fixprice_api/quick_start).
8889

89-
country = await Api.Geolocation.country_list(alias="RU") # alias работает сортировкой
90+
---
9091

91-
# получаем объект "Объединенные Арабские Эмираты"
92-
print(f"Найдена страна {country[0]['title']} ({country[0]['id']}), валюта: {country[0]['currency']['title']} / {country[0]['currency']['symbol']}")
92+
## Автотесты API (pytest + snapshots)
9393

94-
citys = await Api.Geolocation.city_list(country_id=country[0]["id"]) # получаем список городов
94+
В проекте используется автотест-фреймворк из `human_requests`:
9595

96-
Api.city_id = citys[0]["id"] # меняем ID города
97-
print(f"Город изменен на {citys[0]['name']} ({citys[0]['id']})")
96+
- endpoint-методы в бизнес-коде помечаются `@autotest`;
97+
- pytest-плагин сам находит эти методы и запускает их;
98+
- JSON-ответы проверяются через `pytest-jsonschema-snapshot` (`schemashot`);
99+
- параметры вызова и пост-обработка результата регистрируются в `tests/api_test.py` через:
100+
- `@autotest_params`
101+
- `@autotest_hook`
102+
- `@autotest_depends_on`
98103

99-
# Вне РФ каталог не работает
100-
print(f"Категории: {len(await Api.Catalog.categories_list())} штук")
101-
```
102-
```bash
103-
> ID города перед первым запросом: None, язык: None
104-
> ID города после первого запроса: 3, язык: ru
105-
> Найдена страна Россия (2), валюта: Рубль / ₽
106-
> Город изменен на Щербинка (229)
107-
> Категории: 29 штук
108-
```
104+
Минимальная конфигурация уже включена в `pyproject.toml`:
109105

110-
### Проверка наличия товара
111-
```py
112-
async with FixPrice() as Api:
113-
Api.city_id = 3 # Обязательно указываем перед запросом город, иначе ошибка
114-
check = await Api.Store.product_balance(1851089) # Круассан, 7DAYS, 110 г, с двойным кремом
115-
116-
stoks = []
117-
for i in check:
118-
stoks.append(i.get("count", 0))
119-
120-
print(f"Самое большое количество: {max(stoks)}")
121-
print(f"Самое малое количество: {min(stoks)}")
122-
print(f"Среднее количество: {round(sum(stoks) / len(stoks), 2)}")
123-
print(f"Обработано {len(stoks)} магазинов")
124-
```
125-
```bash
126-
> Самое большое количество: 67
127-
> Самое малое количество: 10
128-
> Среднее количество: 28.5
129-
> Обработано 339 магазинов
106+
```ini
107+
[tool.pytest.ini_options]
108+
anyio_mode = "auto"
109+
autotest_start_class = "fixprice_api.FixPriceAPI"
130110
```
131111

132-
### Загрузка изображений
133-
```py
134-
async with FixPrice() as Api:
135-
img = await Api.General.download_image("https://img.fix-price.com/190x190/_marketplace/images/origin/90/903ce795a221a6978444a86391816f93.jpg")
112+
Запуск тестов:
136113

137-
with open(img.name, "wb") as f:
138-
f.write(img.read())
114+
```bash
115+
pytest
139116
```
140117

141-
### Или параллельная загрузка
142-
```py
143-
async with FixPrice() as Api:
144-
tasks = [
145-
Api.General.download_image("https://img.fix-price.com/190x190/_marketplace/images/origin/90/903ce795a221a6978444a86391816f93.jpg"),
146-
Api.General.download_image("https://img.fix-price.com/190x190/_marketplace/images/origin/51/519a1d3c838e3e7e30493fb9b1f69a05.jpg")
147-
]
148-
149-
results = await asyncio.gather(*tasks)
150-
for result in results:
151-
with open(result.name, "wb") as f:
152-
f.write(result.read())
153-
```
118+
Важно:
119+
120+
- используется `pytest-anyio` (не `pytest-asyncio`);
121+
- ручные тесты остаются только для кейсов, которые не относятся к JSON-схемам endpoint-методов (например, `download_image`).
154122

155123
---
156124

157-
### Report / Обратная связь
125+
<div align="center">
126+
127+
### Report
158128

159129
If you have any problems using it / suggestions, do not hesitate to write to the [project's GitHub](https://github.com/Open-Inflation/fixprice_api/issues)!
160130

161-
Если у вас возникнут проблемы в использовании / пожелания, не стесняйтесь писать на [GitHub проекта](https://github.com/Open-Inflation/fixprice_api/issues)!
131+
</div>

0 commit comments

Comments
 (0)