Metadata-Version: 2.4
Name: mrjprotank
Version: 0.1.1
Summary: Official Python client for the Miranjo ProTanki stats & tracker API
Author: Miranjo
License: MIT
Project-URL: Homepage, https://protanki-stats.miranjo.dev
Project-URL: Repository, https://protanki-stats.miranjo.dev
Keywords: protanki,tanki,api,client,stats,tracker
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Games/Entertainment
Classifier: Intended Audience :: Developers
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25
Dynamic: license-file

# mrjprotank

Official Python client for the Miranjo ProTanki stats & tracker API. Works
on Linux, Windows, and macOS -- anywhere Python and `pip` run.

```bash
pip install mrjprotank
```

## Quick start

```python
from mrjprotank import ProTankClient

client = ProTankClient()

# Online right now, plus today's/this week's peak
print(client.online())
# {"current_online": 214, "max_today": 331, "max_week": 402, ...}

# How many were online during a specific 10-minute window in the past
print(client.online_at("2026-07-30T18:20:00"))

# Everything about a player in ONE request: online/offline, last seen,
# current battle (if any), clan tag, garage, and stats.
print(client.player("SomeUsername"))

# Clan leaderboard (takes ~5s to respond -- see "Rate limiting" below)
print(client.clan_leaderboard())

# Search for a clan (also ~5s)
print(client.search_clan("ABC"))

# Full clan profile (also ~5s)
print(client.clan("ABC"))

# One page (100 rows) of a leaderboard, or all of it:
page = client.leaderboard_page("kd", offset=0)
for row in client.leaderboard("kd"):          # auto-pages until it runs out
    print(row["position"], row["username"], row["value_human"])
```

## API surface

| Method | What it returns |
|---|---|
| `client.online()` | current online count, today's peak, this week's peak |
| `client.online_at(when)` | online count for the 10-minute window containing `when` (datetime or ISO string) |
| `client.player(username)` | online/offline, last seen, battle status, clan, garage, and stats -- in one call |
| `client.clan_leaderboard()` | full clan leaderboard |
| `client.search_clan(query)` | clans matching a tag/name |
| `client.clan(tag, refresh=False)` | full profile + stats for one clan |
| `client.leaderboard_page(category, offset=0, **extra)` | one page (up to 100 rows) of a player leaderboard |
| `client.leaderboard(category, **extra)` | generator that yields every row, auto-paging until the leaderboard runs out |

Leaderboard `category` values: any of the site's simple categories (e.g.
`"rating"`, `"kd"`, `"kills"`, `"score"`, `"playtime"`, ...), plus:
- `category="mode", mode="DM"/"TDM"/"CTF"/"CP", mode_metric="time"/"score"`
- `category="supplies", supply=<key>` (omit `supply` for the combined total)

## Rate limiting

The server paces requests per IP address. If you go over it, the client
automatically retries a few times (see `retries=` below) before raising
`ProTankRateLimitedError`. Please don't try to defeat this with many
parallel connections or processes -- it exists to keep the API fast and
available for everyone, including you.

The clan and leaderboard endpoints (`clan_leaderboard`, `search_clan`,
`clan`, `leaderboard_page`/`leaderboard`) intentionally take about 5 seconds
to respond. That is a deliberate server-side design choice, not network
lag -- it makes bulk-scraping expensive without meaningfully affecting a
normal script. The server also caps how many of those slow requests it will
run at once; if you're unlucky enough to hit that cap you'll get a prompt
429 instead of a long queue.

## Configuration

```python
client = ProTankClient(
    base_url="https://protanki-stats-by-miranjo.duckdns.org/",  # override if needed
    timeout=30,      # seconds; keep well above 5 because of the delay above
    retries=3,       # automatic retries on HTTP 429
)
```

`base_url` can also be set once via the `MRJPROTANK_BASE_URL` environment
variable instead of passing it to every `ProTankClient()` call.

## Errors

All exceptions inherit from `mrjprotank.ProTankAPIError`:

- `ProTankNotFoundError` -- 404 from the server
- `ProTankServerError` -- 5xx from the server
- `ProTankRateLimitedError` -- 429, retries exhausted (`.retry_after` has
  the server-suggested wait in seconds)

## License

MIT
