GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - 18studio/avito_python_api: Avito SDK для python

BranchesTags
Open more actions menu

Latest commit

 

History

56 Commits
56 Commits

Folders and files

NameName
Last commit message
Last commit date
.ai
.ai
 
 
.claude
.claude
 
 
.github
.github
 
 
avito
avito
 
 
docs
docs
 
 
scripts
scripts
 
 
tests
tests
 
 
.gitignore
.gitignore
 
 
.interrogate-baseline
.interrogate-baseline
 
 
AGENTS.md
AGENTS.md
 
 
CHANGELOG.md
CHANGELOG.md
 
 
CLAUDE.md
CLAUDE.md
 
 
CONTRIBUTING.md
CONTRIBUTING.md
 
 
LICENSE
LICENSE
 
 
Makefile
Makefile
 
 
README.md
README.md
 
 
context7.json
context7.json
 
 
mkdocs.yml
mkdocs.yml
 
 
poetry.lock
poetry.lock
 
 
pyproject.toml
pyproject.toml
 
 

Repository files navigation

SDK для Avito

CI Coverage Status PyPI Downloads Docs

Отчёт покрытия 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_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-кода предпочтителен контекстный менеджер.

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 → ValidationError
  • 401 → AuthenticationError
  • 403 → AuthorizationError
  • 409 → ConflictError
  • 429 → 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

About

Avito SDK для python

18studio.github.io/avito_python_api/

Topics

asyncasyncioavitoavito-apiavito-ruavito-sdkpythonpython3

Resources

Readme
MIT license

Contributing

Contributing
Activity
Custom properties

Stars

9 stars

Watchers

2 watching

Forks

0 forks
Report repository

Releases

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.