Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ github.token }}
with:
args: --root-dir "${{ github.workspace }}/site" --exclude "avito\.ru" --exclude "^https://p141592\.github\.io/avito_python_api/" --retry-wait-time 5 --max-retries 3 --timeout 30 site/
args: --root-dir "${{ github.workspace }}/site" --exclude "avito\.ru" --exclude "^https://18studio\.github\.io/avito_python_api/" --retry-wait-time 5 --max-retries 3 --timeout 30 site/

deploy:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ docs-report:

docs-check: docs-strict
ln -sfn . site/avito_python_api
lychee --root-dir "$(PWD)/site" --exclude "avito\.ru" --exclude "^https://p141592\.github\.io/avito_python_api/" --retry-wait-time 5 --max-retries 3 --timeout 30 site/
lychee --root-dir "$(PWD)/site" --exclude "avito\.ru" --exclude "^https://18studio\.github\.io/avito_python_api/" --retry-wait-time 5 --max-retries 3 --timeout 30 site/

qa-docs:
poetry run pydocstyle \
Expand Down
69 changes: 67 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SDK для Avito

[![CI](https://github.com/p141592/avito_python_api/actions/workflows/ci.yml/badge.svg)](https://github.com/p141592/avito_python_api/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/p141592/avito_python_api/badge.svg?branch=main)](https://coveralls.io/github/p141592/avito_python_api?branch=main)
[![CI](https://github.com/18studio/avito_python_api/actions/workflows/ci.yml/badge.svg)](https://github.com/18studio/avito_python_api/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/18studio/avito_python_api/badge.svg?branch=main)](https://coveralls.io/github/18studio/avito_python_api?branch=main)
[![PyPI Downloads](https://img.shields.io/pypi/dm/avito-py.svg)](https://pypi.org/project/avito-py/)
[![Docs](https://img.shields.io/badge/docs-latest-blue)](https://18studio.github.io/avito_python_api/)

Expand Down Expand Up @@ -121,6 +121,71 @@ async with AsyncAvitoClient.from_env() as avito:
- `AvitoSettings.from_env()` и `AvitoClient.from_env()` детерминированно читают `.env` из текущей рабочей директории или из переданного `env_file`;
- при отсутствии `AVITO_CLIENT_ID` или `AVITO_CLIENT_SECRET` SDK поднимает `ConfigurationError` при создании клиента, до первого HTTP-запроса.

## Асинхронный режим

Для async-кода используйте `AsyncAvitoClient`. Он повторяет доменную поверхность
`AvitoClient`: фабрики (`account()`, `ad()`, `chat()`, `order()` и другие),
аргументы методов и возвращаемые SDK-модели остаются теми же, но сетевые вызовы
выполняются через `await`.

`AsyncAvitoClient` обязательно открывается через `async with`: в этот момент SDK
создаёт loop-bound `httpx.AsyncClient`, async locks и transport. Для ручного
закрытия есть `await avito.aclose()`, но для application-кода предпочтителен
контекстный менеджер.

```python
from avito import AsyncAvitoClient


async def load_active_ads() -> list[str]:
async with AsyncAvitoClient.from_env() as avito:
profile = await avito.account().get_self()
ads = await avito.ad(user_id=profile.id).list(status="active", limit=20)
items = await ads.materialize()
return [item.title for item in items]
```

Async-пагинация возвращает `AsyncPaginatedList[T]`, а не обычный `list`.
Читайте страницы через `async for` или явно материализуйте результат:

```python
from avito import AsyncAvitoClient


async def print_ads() -> None:
async with AsyncAvitoClient.from_env() as avito:
ads = await avito.ad(user_id=123).list(status="active", limit=100)

async for item in ads:
print(item.title)
```

Для ASGI-приложений создавайте один `AsyncAvitoClient` в lifespan приложения и
закрывайте его на shutdown. Один экземпляр клиента нельзя переносить между event
loop.

```python
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager

from fastapi import FastAPI

from avito import AsyncAvitoClient


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
async with AsyncAvitoClient.from_env() as avito:
app.state.avito = avito
yield


app = FastAPI(lifespan=lifespan)
```

Подробнее: [Асинхронный режим](https://18studio.github.io/avito_python_api/how-to/async/)
и справочник [AvitoClient и AsyncAvitoClient](https://18studio.github.io/avito_python_api/reference/client/).

## Примеры по доменам

### Аккаунт и объявления
Expand Down
2 changes: 1 addition & 1 deletion docs/site/assets/_gen_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

EXCLUDED_PACKAGES = {"auth", "core", "testing"}
PACKAGE_ROOT = Path("avito")
GITHUB_API_URL = "https://github.com/p141592/avito_python_api/blob/main/docs/avito/api"
GITHUB_API_URL = "https://github.com/18studio/avito_python_api/blob/main/docs/avito/api"


def public_domain_packages() -> list[str]:
Expand Down
1 change: 1 addition & 0 deletions docs/site/explanations/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ nav:
- pagination-semantics.md
- dry-run-and-idempotency.md
- testing-strategy.md
- async-domain-template.md
- api-coverage-and-deprecations.md
- swagger-binding-subsystem.md
- config-resolution.md
Expand Down
1 change: 1 addition & 0 deletions docs/site/explanations/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Explanations описывают причины архитектурных реш
| [Семантика пагинации](pagination-semantics.md) | Почему `PaginatedList` ленивый и когда загружаются страницы |
| [Dry-run и идемпотентность](dry-run-and-idempotency.md) | Как write-операции проверяются без сетевого вызова |
| [Стратегия тестирования](testing-strategy.md) | Как `FakeTransport`, contract-тесты и docs-harness проверяют SDK |
| [Шаблон async-домена](async-domain-template.md) | Как портировать доменный объект в `async_domain.py` без нарушения Swagger bindings |
| [Покрытие API и deprecation](api-coverage-and-deprecations.md) | Как specs, reference и runtime warnings связаны между собой |
| [Swagger binding subsystem](swagger-binding-subsystem.md) | Как Swagger specs, bindings, strict lint, JSON report и contract runner сохраняют coverage-контекст |
| [Resolution конфигурации](config-resolution.md) | Как env, `.env` и defaults превращаются в `AvitoSettings` |
Expand Down
2 changes: 1 addition & 1 deletion docs/site/how-to/async.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Async API
# Асинхронный режим

`AsyncAvitoClient` повторяет доменную поверхность `AvitoClient`, но все сетевые
методы вызываются через `await`. Клиент обязательно открывается через `async with`:
Expand Down
2 changes: 1 addition & 1 deletion docs/site/how-to/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ How-to раздел собирает рецепты для конкретных
| Рецепт | Задача |
|---|---|
| [Авторизация и конфигурация](auth-and-config.md) | Создать клиент через env, явные ключи или `AvitoSettings` |
| [Async API](async.md) | Использовать `AsyncAvitoClient`, ASGI lifespan и async fake transport |
| [Асинхронный режим](async.md) | Использовать `AsyncAvitoClient`, ASGI lifespan и async fake transport |
| [Профиль, баланс и иерархия аккаунта](account-profile.md) | Получить профиль, баланс, историю операций и данные сотрудников |
| [Объявления, статистика и продвижение](ad-listing-and-stats.md) | Найти объявления, открыть карточку, прочитать статистику и подготовить VAS |
| [Продвижение с dry-run](promotion-dry-run.md) | Проверить payload write-операции без сетевого вызова |
Expand Down
14 changes: 12 additions & 2 deletions docs/site/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ pip install avito-py

<div class="avito-badges" markdown>

[![CI](https://github.com/p141592/avito_python_api/actions/workflows/ci.yml/badge.svg)](https://github.com/p141592/avito_python_api/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/p141592/avito_python_api/badge.svg?branch=main)](https://coveralls.io/github/p141592/avito_python_api?branch=main)
[![CI](https://github.com/18studio/avito_python_api/actions/workflows/ci.yml/badge.svg)](https://github.com/18studio/avito_python_api/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/18studio/avito_python_api/badge.svg?branch=main)](https://coveralls.io/github/18studio/avito_python_api?branch=main)
[![PyPI Downloads](https://img.shields.io/pypi/dm/avito-py.svg)](https://pypi.org/project/avito-py/)
[![API coverage](https://img.shields.io/badge/API%20coverage-204%2F204-success)](reference/coverage.md)

Expand All @@ -43,6 +43,14 @@ pip install avito-py

[:octicons-arrow-right-24: How-to рецепты](how-to/index.md)

- :material-sync:{ .lg .middle } **Асинхронный режим**

---

`AsyncAvitoClient`, `async with`, ASGI lifespan, async-пагинация и тестирование без HTTP.

[:octicons-arrow-right-24: Async how-to](how-to/async.md)

- :material-code-tags:{ .lg .middle } **Нужен точный контракт**

---
Expand Down Expand Up @@ -70,3 +78,5 @@ pip install avito-py
| **Режим** | Tutorials | How-to | Reference | Explanations |
| **Цель** | Обучение через действие | Решить конкретную задачу | Точная информация | Понять «почему» |
| **Раздел** | [Tutorials](tutorials/index.md) | [How-to](how-to/index.md) | [Reference](reference/index.md) | [Explanations](explanations/index.md) |

Для async-кода начните с рецепта [Асинхронный режим](how-to/async.md), а точный контракт смотрите в [AvitoClient и AsyncAvitoClient](reference/client.md).
3 changes: 2 additions & 1 deletion docs/site/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

| Страница | Что искать |
|---|---|
| [AvitoClient](client.md) | Инициализация, контекстный менеджер, фабричные методы, `debug_info()` |
| [AvitoClient и AsyncAvitoClient](client.md) | Sync/async инициализация, контекстные менеджеры, фабричные методы, `debug_info()` |
| [Асинхронный режим](../how-to/async.md) | Практический lifecycle `AsyncAvitoClient`, ASGI и async fake transport |
| [Конфигурация](config.md) | `AvitoSettings`, `AuthSettings`, env-переменные, per-operation overrides |
| [Покрытие API](coverage.md) | 204/204 Swagger operations из binding report |
| [Методы API](operations.md) | Карта Swagger operation → публичный SDK-метод |
Expand Down
4 changes: 2 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
site_name: avito-py
site_description: Sync/async Python SDK для Avito API
site_url: https://18studio.github.io/avito_python_api/
repo_url: https://github.com/p141592/avito_python_api
repo_name: p141592/avito_python_api
repo_url: https://github.com/18studio/avito_python_api
repo_name: 18studio/avito_python_api
edit_uri: edit/main/docs/site/

docs_dir: docs/site
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ packages=[
]
license="MIT"
readme="README.md"
homepage="https://github.com/p141592/avito_python_api"
repository="https://github.com/p141592/avito_python_api"
homepage="https://github.com/18studio/avito_python_api"
repository="https://github.com/18studio/avito_python_api"
documentation="https://18studio.github.io/avito_python_api/"
keywords=["avito", "sdk", "python", "api"]
classifiers=[
Expand All @@ -29,14 +29,14 @@ python = ">=3.12,<4.0"
httpx = "^0.28.1"

[tool.poetry.group.dev.dependencies]
pytest = "^8.3.5"
pytest = ">=9.0.3,<10.0.0"
coverage = "^7.10.6"
mypy = "^1.18.2"
ruff = "^0.12.12"
respx = "^0.22.0"
libcst = "^1.8.6"
bowler = "^0.9.0"
pytest-asyncio = "^0.24"
pytest-asyncio = ">=1.3,<2.0"

[tool.poetry.group.docs.dependencies]
mkdocs-material = "^9.5"
Expand Down
Loading