Metadata-Version: 2.4
Name: arr-py-client
Version: 0.1.0
Summary: Typed sync + async Python client for Radarr v3 and Sonarr v3 APIs
Project-URL: Homepage, https://github.com/allada-homelab/arr-py-client
Project-URL: Source, https://github.com/allada-homelab/arr-py-client
Project-URL: Issues, https://github.com/allada-homelab/arr-py-client/issues
Author-email: David Allada <davidanilallada@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: <3.15,>=3.11
Requires-Dist: anyio>=4.13.0
Requires-Dist: httpx<1.0,>=0.28
Requires-Dist: pydantic-settings<3.0,>=2.2
Requires-Dist: pydantic<3.0,>=2.13.3
Provides-Extra: api
Provides-Extra: mcp
Requires-Dist: mcp<2.0,>=1.27; extra == 'mcp'
Description-Content-Type: text/markdown

# arr-py-client

Typed synchronous and asynchronous Python client for [Radarr](https://radarr.video) and [Sonarr](https://sonarr.tv) v3 APIs.

[![CI](https://github.com/allada-homelab/arr-py-client/actions/workflows/ci.yml/badge.svg)](https://github.com/allada-homelab/arr-py-client/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/arr-py-client.svg)](https://pypi.org/project/arr-py-client/)
[![Python](https://img.shields.io/pypi/pyversions/arr-py-client.svg)](https://pypi.org/project/arr-py-client/)
[![License](https://img.shields.io/pypi/l/arr-py-client.svg)](LICENSE)

## Features

- Pydantic v2 models for every request and response
- Sync (`RadarrClient`, `SonarrClient`) and async (`AsyncRadarrClient`, `AsyncSonarrClient`) clients sharing the same API
- Full v3 endpoint coverage for both apps, generated from upstream OpenAPI specs
- Typed exceptions (`ArrNotFoundError`, `ArrValidationError`, etc.) with validation-detail parsing
- Env / `.env` fallback for credentials via `pydantic-settings`
- Configurable retry policy (idempotent GET only by default)
- Ships `py.typed` (PEP 561) — IDEs and type checkers just work
- Python 3.11–3.14

## Install

```bash
pip install arr-py-client
```

## Quickstart

```python
from arr_py_client import RadarrClient

with RadarrClient(base_url="http://radarr:7878", api_key="YOUR_KEY") as client:
    movies = client.movies.list()
    for m in movies[:5]:
        print(m.id, m.title, m.year)
```

Or via environment variables — set `RADARR_BASE_URL` and `RADARR_API_KEY` and:

```python
from arr_py_client import RadarrClient

with RadarrClient() as client:
    print(len(client.movies.list()))
```

Async mirrors the sync API:

```python
from arr_py_client import AsyncRadarrClient

async def main() -> None:
    async with AsyncRadarrClient() as client:
        movies = await client.movies.list()
        print(len(movies))
```

The client also exposes auto-generated wrappers for every OpenAPI tag — for example
`client.tag.list_()`, `client.queue.list_()`, `client.system.list_status()`. Method names follow
`<verb>[_<distinguisher>]` (e.g., `list_`, `get_by_id`, `create`, `update_by_id`, `delete_by_id`).

## Compared to pyarr

|  | arr-py-client | pyarr |
| :-- | :-- | :-- |
| Pydantic v2 models | yes | no (returns dicts) |
| Async support | yes | no |
| Full Radarr/Sonarr v3 coverage | yes | yes |
| Lidarr/Readarr/Prowlarr | not yet | yes |
| Ships `py.typed` | yes | no |

## Documentation

API reference: <https://allada-homelab.github.io/arr-py-client/>

## Development

```bash
git clone https://github.com/allada-homelab/arr-py-client
cd arr-py-client
uv sync --all-groups
just test
```

Integration tests (require Docker):
```bash
just test-int
```

Regenerate clients from upstream specs:
```bash
just gen-radarr <radarr-tag>
just gen-sonarr <sonarr-tag>
```

## License

MIT. See [LICENSE](LICENSE).
