Fast, modern Python client for Yandex Metrika APIs (Logs, Management, Stats) with built-in rate limiting and parallel execution
Project description
ym-api-client
Fast, modern Python client for Yandex Metrika APIs — with automatic rate limiting, parallel execution, exponential backoff, and optional async+HTTP/2 support.
Features
- ⚡ Fast — up to 8.8× faster than
tapi-yandex-metrikain real-world benchmarks - ⏱ Auto rate limiting — token bucket algorithm prevents 429 errors (default 8 req/s)
- 🔄 Exponential backoff — smart retry with jitter for transient failures
- 🧵 Parallel execution — download from multiple counters concurrently via
ThreadPoolExecutor - 🔩 Automatic field chunking — respects Yandex's 3000‑character
fieldslimit, splits and merges transparently - 🧹 Auto‑cleanup — removes processed log requests to stay within the 10 GB storage quota
- 🌐 Async + HTTP/2 — optional
ym-api-client[async]withhttpx.AsyncClientfor high‑throughput concurrency - 🛡️ Error classification —
YandexMetrikaAuthError(403),YandexMetrikaRateLimitError(429),YandexMetrikaApiError(4xx/5xx)
Installation
pip install ym-api-client
For async/HTTP/2 support:
pip install ym-api-client[async]
Quick Start
Fetch visits for one day
from ym_api_client import YandexMetrikaClient
client = YandexMetrikaClient(access_token="your_oauth_token")
data = client.logs.download_visits(
counter_id="12345678",
date1="2026-06-01",
date2="2026-06-01",
)
print(f"Loaded {len(data)} visits")
# → Loaded 1523 visits
Parallel fetch from multiple counters
from ym_api_client import YandexMetrikaClient
client = YandexMetrikaClient(access_token="token")
results = client.logs.fetch_visits_parallel(
counter_ids=["111", "222", "333"],
date1="2026-06-01",
date2="2026-06-07",
max_workers=5,
)
for counter_id, rows in results.items():
print(f"Counter {counter_id}: {len(rows)} rows")
List counters (Management API)
from ym_api_client import YandexMetrikaClient
client = YandexMetrikaClient(access_token="token")
counters = client.management.list_counters()
for c in counters:
print(f"{c['id']}: {c['name']} — {c['site']}")
Low-level Logs API (step‑by‑step)
# 1. Create a log request
request = client.logs.create_request(
counter_id="12345678",
date1="2026-06-01",
date2="2026-06-01",
fields=["ym:s:visitID", "ym:s:date", "ym:s:pageViews"],
source="visits",
)
request_id = request["log_request"]["request_id"]
# 2. Wait for Yandex to process it (exponential backoff)
client.logs.wait_for_request(counter_id="12345678", request_id=request_id)
# 3. Download all parts
rows = client.logs.download_request(counter_id="12345678", request_id=request_id)
Async with HTTP/2
import asyncio
from ym_api_client import AsyncYandexMetrikaClient
async def main():
async with AsyncYandexMetrikaClient(access_token="token") as client:
data = await client.logs.download_visits(
counter_id="12345678",
date1="2026-06-01",
date2="2026-06-07",
)
print(f"Loaded {len(data)} visits")
asyncio.run(main())
Why not tapi-yandex-metrika?
tapi-yandex-metrika was the go‑to library for years, but it's been stagnant since 2022. ym-api-client is a complete rewrite that fixes its fundamental performance problems.
| Feature | tapi-yandex-metrika |
ym-api-client |
|---|---|---|
| HTTP layer | tapioca-wrapper (dynamic proxy, ~2.5 × overhead) |
requests.Session (direct, pooled) |
| Rate limiting | ❌ None | ✅ Token bucket (8 req/s default, configurable) |
| Parallel downloads | ❌ Sequential only | ✅ ThreadPoolExecutor (up to YM's 3‑request limit) |
| Retry logic | ❌ Fixed 10‑second sleep | ✅ Exponential backoff + jitter (2 s → 30 s) |
| Field chunking | ❌ Manual | ✅ Automatic (respects 3000‑char limit, merges transparently) |
| Async / HTTP/2 | ❌ | ✅ Optional [async] extra |
| Error handling | Basic | Classified: 403 auth, 429 rate limit, 4xx/5xx API errors |
| Last release | April 2022 | 2026 (active) |
| Python support | 3.5+ | 3.7–3.12 |
Real‑world benchmark
| Metric | tapi-yandex-metrika |
ym-api-client |
Speed‑up |
|---|---|---|---|
| Total time (40 counters, 1 day) | 58.89 s | 6.67 s | 8.8 × |
| Wait for YM processing | 58.11 s | 5.52 s | 10.5 × |
Benchmark details: fetching visits from 40 Yandex Metrika counters for the same date.
ym-api-clientupgrades HTTP/1.1 keep‑alive + eliminatestapioca-wrapper's dynamic proxy overhead. The 10.5 × speedup on the wait phase comes from exponential polling (requests that finish early are detected much sooner than a fixed 10‑second interval).
API Overview
YandexMetrikaClient
The main client that provides access to all sub‑APIs.
| Sub‑API | Attribute | Description |
|---|---|---|
| Logs API | .logs |
Download non‑aggregated visit and hit data |
| Management API | .management |
List counters, goals, filters, operations |
Logs API methods
| Method | Description |
|---|---|
create_request(counter_id, date1, date2, fields, source) |
Create a new log request |
wait_for_request(counter_id, request_id) |
Poll until processed (exponential backoff) |
download_request(counter_id, request_id) |
Download all parts → List[Dict] |
get_request_info(counter_id, request_id) |
Check status of a request |
evaluate_request(counter_id, date1, date2, fields, source) |
Pre‑flight check (dry run) |
clean_request(counter_id, request_id) |
Delete request, free storage |
list_requests(counter_id) |
List all log requests for a counter |
| High‑level: | |
download_visits(counter_id, date1, date2, ...) |
Create → wait → download → cleanup |
download_hits(counter_id, date1, date2, ...) |
Same flow, source = "hits" |
fetch_visits_parallel(counter_ids, date1, date2, ...) |
Multi‑counter parallel visits |
fetch_hits_parallel(counter_ids, date1, date2, ...) |
Multi‑counter parallel hits |
fetch_missing_dates_parallel(counter_missing, ...) |
Incremental load for gaps |
Async counterpart
When you install ym-api-client[async], AsyncYandexMetrikaClient is available with the same interface but async methods. All parallel operations use asyncio.gather + httpx.AsyncClient with HTTP/2 multiplexing.
Architecture
ym_api_client/
├── __init__.py # Public exports, optional async imports
├── client.py # YandexMetrikaClient — main entry point
├── base.py # BaseApiClient — HTTP session, auth, retry
├── rate_limiter.py # Token bucket rate limiter
├── logs_api.py # Logs API — visits, hits, parallel downloads
├── management_api.py # Management API — counters, goals
├── exceptions.py # Typed exceptions
│
├── async_base.py # [optional] httpx.AsyncClient + HTTP/2
└── async_logs_api.py # [optional] Async Logs API client
Rate Limiting
The built‑in token bucket prevents 429 errors:
- Default: 8 requests/second (safe under the 10 req/s Logs API limit)
- Burst: same as the configured rate (instant burst up to 8)
- If 429 still occurs: exponential backoff with jitter (2–10 s random sleep)
- Configurable:
YandexMetrikaClient(rate_limit_rps=5.0)
Development
git clone https://github.com/01zhas/ym-api-client.git
cd ym-api-client
pip install -e ".[dev]"
pytest tests/
Releasing
pip install -e ".[dev]" # ensures build + twine
python -m build # builds dist/*.whl and dist/*.tar.gz
twine check dist/* # validates the packages
twine upload dist/* # uploads to PyPI
License
MIT © 2026 im01zhas
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 ym_api_client-0.2.0.tar.gz.
File metadata
- Download URL: ym_api_client-0.2.0.tar.gz
- Upload date:
- Size: 27.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
854e05d1c34e58d42c6e29388f3426308082664f84a5aaea9cce569d8d5d6aaf
|
|
| MD5 |
a748a32cc074729b324983e47c82c689
|
|
| BLAKE2b-256 |
6477f9960acc593c39728606aab49d348523bd0ff950fdc623f9c8204e816d3e
|
File details
Details for the file ym_api_client-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ym_api_client-0.2.0-py3-none-any.whl
- Upload date:
- Size: 27.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d74b2644c7b80a2eff48e5fcd0d9cd9273a9af53b5ed6f25656e004b7a86957
|
|
| MD5 |
7cb3590aa9c87e98d594d2e3e5a5edf7
|
|
| BLAKE2b-256 |
4c326f667d2cc9d043bd57b0044abf745b1e9bc3dac688d35bace6d8b565cdd0
|