Metadata-Version: 2.4
Name: overfast-client
Version: 0.1.0
Summary: Async Python client for the OverFast API (Overwatch data).
Project-URL: Homepage, https://github.com/Leo890728/overwatch_py
Project-URL: Repository, https://github.com/Leo890728/overwatch_py
Project-URL: Issues, https://github.com/Leo890728/overwatch_py/issues
Project-URL: Changelog, https://github.com/Leo890728/overwatch_py/blob/main/CHANGELOG.md
Author-email: Leo890728 <Leo890728@users.noreply.github.com>
License: MIT
License-File: LICENSE
Keywords: api,async,httpx,overfast,overwatch,pydantic
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Framework :: Pydantic :: 2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: hishel<0.2,>=0.0.30
Requires-Dist: httpx-retries>=0.3
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.5
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# overfast-client

Async Python client for the [OverFast API](https://overfast-api.tekrop.fr) — comprehensive Overwatch data (heroes, maps, gamemodes, player stats) via a typed, pydantic-backed interface.

## Install

```bash
pip install overfast-client
```

> The PyPI distribution is `overfast-client`; the import name is `overwatch_py`.

Or from source (editable):

```bash
pip install -e .
```

## Quick start

```python
import asyncio
from overwatch_py import Client
from overwatch_py.enums import Hero, Locale, Role, HeroGamemode, PlayerGamemode, Platform

async def main():
    client = Client()

    # List heroes
    heroes = await client.get_heroes(role=Role.SUPPORT, locale=Locale.EN_US)
    for h in heroes:
        print(h.key, h.name)

    # Full hero data (abilities, story, hitpoints, ...)
    ana = await client.get_hero_data(Hero.ANA)
    print(ana.hitpoints, len(ana.abilities))

    # Maps & gamemodes
    maps = await client.get_maps()
    gamemodes = await client.get_gamemode_details()

    # Hero usage stats (pickrate / winrate)
    stats = await client.get_heroes_stats(
        platform=Platform.PC,
        gamemode=PlayerGamemode.COMPETITIVE,
    )

    # Players
    result = await client.search_players("TeKrop", limit=10)
    player = await client.get_player(result.results[0].player_id)
    summary = await client.get_player_summary("TeKrop-2217")
    stats_summary = await client.get_player_stats("TeKrop-2217", gamemode=PlayerGamemode.COMPETITIVE)

asyncio.run(main())
```

## Configuration

```python
from overwatch_py import Client
from overwatch_py.config import Config
from overwatch_py.session import HTTPSession

config = Config(
    timeout=10,          # seconds
    retries=3,           # retries on 5xx
    cache=True,          # HTTP-level cache (hishel), respects server Cache-Control
    cache_backend="sqlite",  # "memory" | "sqlite" | "file"
)
client = Client(HTTPSession(config))
```

### Caching

Caching is disabled by default. When enabled, [hishel](https://hishel.com) sits in the httpx transport stack and honors each endpoint's `Cache-Control` / `Age` headers (e.g. `/heroes` is cached ~1 day, `/heroes/stats` ~1 hour by the upstream API).

## Exceptions

All non-2xx responses map to subclasses of `APIError`:

| Status | Exception |
|--------|-----------|
| 400    | `BadRequestError` |
| 404    | `NotFoundError` |
| 422    | `ValidationError` |
| 429    | `APIRateLimitError` |
| 500    | `InternalServerError` |
| 503    | `BlizzardRateLimitError` |
| 504    | `BlizzardServerError` |

```python
from overwatch_py.exceptions import NotFoundError, APIRateLimitError

try:
    await client.get_player_summary("does-not-exist-1234")
except NotFoundError:
    ...
except APIRateLimitError as e:
    print("rate limited:", e.response.headers.get("retry-after"))
```

## API surface

Exposed on `Client`:

- **Heroes** — `get_heroes`, `get_hero_data`, `get_heroes_stats`
- **Maps / Gamemodes** — `get_maps`, `get_gamemode_details`
- **Players** — `search_players`, `get_player`, `get_player_summary`, `get_player_stats`, `get_player_career_stats`, `get_player_career_stats_with_labels`, `get_player_full_stats`

The underlying services (`client.heros`, `client.maps`, `client.players`) are also available if you prefer service-level access.

## Development

```bash
pip install -e ".[dev]"
pytest                     # unit + mocked HTTP tests
pytest -m live             # hits the real API (rate-limited)
pytest -m 'live or not live'  # run everything
```

## License

MIT.