SDK для разработки инструментов на базе Avito API
Project description
SDK для Avito
Отчёт покрытия Avito API: покрытие API.
Быстрый старт
Получение ключей — https://www.avito.ru/professionals/api
from avito import AvitoClient
with AvitoClient.from_env() as avito:
profile = avito.account().get_self()
ad = avito.ad(item_id=42, user_id=123).get()
print(profile.name)
print(ad.title)
По умолчанию настройки читаются из переменных окружения с префиксом AVITO_.
CLI использует тот же публичный SDK и удобен для smoke-проверок, скриптов и операционных задач:
avito account add main --client-id client-id --user-id 123
avito --profile main account get-self
avito --json --no-input --profile main account get-balance --user-id 123
account add спросит Client Secret скрытым prompt. Для CI используйте
--client-secret-stdin, чтобы не передавать секрет в аргументах shell.
Подробно: CLI how-to
и CLI reference.
avito-py — Python SDK для работы с Avito API через единые sync/async фасады
AvitoClient и AsyncAvitoClient.
Установка
poetry add avito-py
или
pip install avito-py
Требование к интерпретатору: Python 3.12, 3.13 или 3.14.
Инициализация клиента
SDK предоставляет три нормативных способа создания клиента — от самого простого к самому явному.
1. Из переменных окружения
from avito import AvitoClient
with AvitoClient.from_env() as avito:
...
2. Напрямую через client_id / client_secret
Короткий путь без промежуточных объектов:
from avito import AvitoClient
with AvitoClient(client_id="client-id", client_secret="client-secret") as avito:
...
3. Полная конфигурация через AvitoSettings
from avito import AuthSettings, AvitoClient, AvitoSettings
settings = AvitoSettings(
base_url="https://api.avito.ru",
user_id=123,
auth=AuthSettings(
client_id="client-id",
client_secret="client-secret",
),
)
with AvitoClient(settings) as avito:
...
Все опциональные параметры конструктора — keyword-only. AvitoClient иммутабелен: base_url, таймауты, retry-политика и auth не меняются у живого клиента — вместо этого создаётся новый клиент.
Async-поверхность использует те же доменные методы и модели, но требует async with:
from avito import AsyncAvitoClient
async with AsyncAvitoClient.from_env() as avito:
profile = await avito.account().get_self()
listings = await (await avito.ad(user_id=123).list(limit=20)).materialize()
Подробный контракт async lifecycle, ASGI-рецепты и ограничения описаны в async how-to.
Переменные окружения
| Переменная | Обязательная | Описание |
|---|---|---|
AVITO_CLIENT_ID |
да | Client ID OAuth-приложения |
AVITO_CLIENT_SECRET |
да | Client Secret OAuth-приложения |
AVITO_BASE_URL |
нет | Базовый URL API (по умолчанию https://api.avito.ru) |
AVITO_USER_ID |
нет | ID пользователя по умолчанию |
AVITO_USER_AGENT_SUFFIX |
нет | Суффикс к заголовку User-Agent |
AVITO_SCOPE |
нет | OAuth scope |
AVITO_REFRESH_TOKEN |
нет | Refresh token для предварительного обмена |
AVITO_AUTOTEKA_CLIENT_ID |
нет | Client ID для Автотека API |
AVITO_AUTOTEKA_CLIENT_SECRET |
нет | Client Secret для Автотека API |
AVITO_AUTOTEKA_SCOPE |
нет | OAuth scope для Автотека API |
Полный список переменных, включая URL-overrides, таймауты и retry-политику, — в справочнике по конфигурации.
Правила resolution:
- значения из process environment имеют приоритет над
.env; AvitoSettings.from_env()иAvitoClient.from_env()детерминированно читают.envиз текущей рабочей директории или из переданногоenv_file;- при отсутствии
AVITO_CLIENT_IDилиAVITO_CLIENT_SECRETSDK поднимает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-кода предпочтителен
контекстный менеджер.
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 или явно материализуйте результат:
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.
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)
Подробнее: Асинхронный режим и справочник AvitoClient и AsyncAvitoClient.
Примеры по доменам
Аккаунт и объявления
from avito import AvitoClient
with AvitoClient.from_env() as avito:
account = avito.account(user_id=123)
balance = account.get_balance()
ad = avito.ad(item_id=42, user_id=123).get()
stats = avito.ad_stats(item_id=42, user_id=123).get_item_stats(
date_from="2026-04-01",
date_to="2026-04-23",
)
user_id можно передать явно, задать через AVITO_USER_ID или оставить пустым для read-only вызовов, где SDK может определить пользователя через account().get_self(). Если идентификатор не удалось определить, SDK поднимает ValidationError с подсказкой, как вызвать метод правильно. Для OAuth secret используйте AVITO_CLIENT_SECRET.
Статистические методы принимают date, datetime и ISO-строки, а в Avito API отправляют дату в формате YYYY-MM-DD. Модель Listing нормализует основные поля объявления: title, price, status, description, url, category, city, published_at, updated_at, is_moderated, is_visible.
Автозагрузка
from avito import AvitoClient
with AvitoClient.from_env() as avito:
profile = avito.autoload_profile(user_id=123).get()
report = avito.autoload_report(report_id=777).get()
Мессенджер
from avito import AvitoClient
from avito.messenger import UploadImageFile
with AvitoClient.from_env() as avito:
chats = avito.chat(user_id=123).list()
message = avito.chat_message(chat_id="chat-1", user_id=123).send_message(
message="Здравствуйте"
)
uploaded = avito.chat_media(user_id=123).upload_images(
files=[
UploadImageFile(
field_name="image",
filename="photo.jpg",
content=b"...",
content_type="image/jpeg",
)
]
)
subscriptions = avito.chat_webhook().list()
Продвижение
from avito import AvitoClient
from datetime import datetime
with AvitoClient.from_env() as avito:
services = avito.promotion_order().list_orders()
forecast = avito.bbip_promotion(item_id=42).get_forecasts(items=[])
budget = avito.autostrategy_campaign().create_budget(
campaign_type="AS",
start_time=datetime(2026, 4, 20),
finish_time=datetime(2026, 4, 27),
items=[42, 43],
)
campaign = avito.autostrategy_campaign(campaign_id=15).get()
campaigns = avito.autostrategy_campaign().list(
limit=50,
status_id=[1, 2],
order_by=[("startTime", "asc")],
updated_from=datetime(2026, 4, 1),
updated_to=datetime(2026, 4, 30),
)
print(budget.calc_id)
print(campaign.campaign.title if campaign.campaign else None)
print(campaigns.total_count)
Write-операции продвижения, поддерживающие сухой прогон, принимают dry_run: bool = False. При dry_run=True SDK валидирует параметры, строит тот же payload, что и в реальном вызове, но не выполняет сетевой запрос и возвращает PromotionActionResult со статусом preview/validated.
Заказы и доставка
from avito import AvitoClient
with AvitoClient.from_env() as avito:
orders = avito.order().list()
label_task = avito.order_label().create(order_ids=["100500"])
label_pdf = avito.order_label(task_id=label_task.task_id).download()
stock_info = avito.stock().get(item_ids=[100500])
Работа
from avito import AvitoClient
with AvitoClient.from_env() as avito:
vacancies = avito.vacancy().list(query="python")
application_ids = avito.application().get_ids(updated_at_from="2026-04-18")
applications = avito.application().get_by_ids(ids=[application_ids.items[0].id])
resumes = avito.resume().list(query="оператор")
webhooks = avito.job_webhook().list()
CPA и CallTracking
from avito import AvitoClient
with AvitoClient.from_env() as avito:
calls = avito.cpa_call().list(
date_time_from="2026-04-18T00:00:00Z",
limit=100,
)
calltracking = avito.call_tracking_call(10).get()
records = avito.call_tracking_call(10).download()
Автотека
from avito import AvitoClient
with AvitoClient.from_env() as avito:
catalog = avito.autoteka_vehicle().resolve_catalog(brand_id=1)
preview = avito.autoteka_vehicle().create_preview_by_vin(vin="XTA00000000000000")
report = avito.autoteka_report().create_report(preview_id=int(preview.preview_id or 0))
reports = avito.autoteka_report().list_reports()
Недвижимость, отзывы и тарифы
from avito import AvitoClient
from avito.realty import RealtyPricePeriod
with AvitoClient.from_env() as avito:
booking = avito.realty_booking(20, user_id=10)
booking.update_bookings_info(blocked_dates=["2026-05-01"])
bookings = booking.list_realty_bookings(date_start="2026-05-01", date_end="2026-05-05")
avito.realty_pricing(20, user_id=10).update_realty_prices(
periods=[RealtyPricePeriod(date_from="2026-05-01", price=5000)]
)
reviews = avito.review().list()
tariff = avito.tariff().get_tariff_info()
review().list() по умолчанию запрашивает первую страницу отзывов (page=1, limit=50). Для явной пагинации передайте page, offset или limit напрямую.
Пагинация
Публичные list-операции, которые поддерживают lazy pagination, возвращают обычные SDK-результаты, а поле items в них типизировано как PaginatedList[T] и ведёт себя как list-like коллекция.
Стабильный публичный контракт:
- первая страница загружается сразу, остальные подгружаются только при чтении элементов за её пределами;
- доступ к уже загруженным элементам не делает повторных запросов;
- частичная итерация и slicing загружают только необходимые страницы;
- пустая коллекция не приводит к дополнительным запросам;
- ошибка на последующей странице поднимается в момент её чтения;
- явная полная материализация выполняется через
items.materialize()и загружает всё ровно один раз.
Пример:
from avito import AvitoClient
with AvitoClient.from_env() as avito:
items = avito.ad(user_id=123).list(status="active", limit=50, page_size=25)
first = items[0]
preview = items[:10]
all_items = items.materialize()
В ad().list() параметр limit ограничивает общий максимум элементов результата, а page_size задаёт размер страницы upstream API.
Ошибки
Все исключения SDK наследуются от AvitoError и импортируются из avito.core.exceptions. HTTP-коды отображаются в конкретные типы:
400,422→ValidationError401→AuthenticationError403→AuthorizationError409→ConflictError429→RateLimitError- прочие
5xxи нераспознанные ответы →UpstreamApiError - транспортные сбои →
TransportError - ошибки маппинга ответа →
ResponseMappingError
AuthenticationError (401) и AuthorizationError (403) — семантически разные ошибки и не состоят в отношении наследования. Тексты сообщений написаны на русском языке. Секреты (access token, client_secret, Authorization) автоматически санитайзятся из сообщений и metadata.
Для диагностики доступны структурированные поля operation, status / status_code, error_code, message, details, retry_after, request_id, metadata, payload и headers. Например, у RateLimitError можно прочитать retry_after, а у ошибок валидации — details, если upstream вернул подробности по параметрам.
Отладка интеграции
SDK не раскрывает сырой transport в основном API, но даёт безопасный debug snapshot без секретов:
from avito import AvitoClient
client = AvitoClient.from_env()
info = client.debug_info()
print(info.base_url)
print(info.user_id)
print(info.retry_max_attempts)
client.close()
debug_info() подходит для smoke-проверок окружения и диагностики конфигурации. Стабильный контракт включает base_url, user_id, флаг requires_auth, таймауты и retry-настройки. Access token, client_secret и Authorization header в этот снимок не попадают.
Проверки качества
Минимальный релизный набор:
make check
Для локальной разработки команды разделены:
make fmt
make lint
make typecheck
make test
make quality
make build
GitHub Actions
Для репозитория настроены два workflow:
CIзапускается на каждыйpushвmain/masterи на каждыйpull_request, выполняетmake quality, docs-gates и один полный pytest-прогон через coverage.Releaseзапускается при пуше тега видаv*, выставляет версию пакета из тега, повторно выполняетmake check, публикует пакет на PyPI и создаёт GitHub Release.
Для публикации релиза нужно добавить secret:
PYPI_API_TOKEN— токен публикации в PyPI дляpoetry publish.
Порядок релиза:
git tag v1.0.2
git push origin v1.0.2
Документация репозитория
- STYLEGUIDE.md — нормативные архитектурные правила
- docs/site/reference — справочник публичного API SDK
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file avito_py-2.2.0.1.tar.gz.
File metadata
- Download URL: avito_py-2.2.0.1.tar.gz
- Upload date:
- Size: 472.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.14.4 Linux/6.17.0-1010-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58af2f66686e9f4223b270d5a1af6cc89d53310d55de7dea7cb8ba309347ccaa
|
|
| MD5 |
37ef25cd240a4d5d277ab1a6c21bb965
|
|
| BLAKE2b-256 |
769b913e56aa276d8afaa77ee174ee3d0bd23df0e243e66e31aa08cb6c369d9f
|
File details
Details for the file avito_py-2.2.0.1-py3-none-any.whl.
File metadata
- Download URL: avito_py-2.2.0.1-py3-none-any.whl
- Upload date:
- Size: 574.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.14.4 Linux/6.17.0-1010-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
291d85e774d7fae26d47453641fcaaa1b8b0efb1b0e5a2caa1ecab0065718a67
|
|
| MD5 |
6443c79e9757499bda84442b07160abb
|
|
| BLAKE2b-256 |
ad9228ac4f7521de731d2e6a97bf1da4720427db22f4bb204f0d927dbb5f26cb
|