aiotvdb 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
aiotvdb-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Olivier Balalud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
aiotvdb-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,172 @@
1
+ Metadata-Version: 2.4
2
+ Name: aiotvdb
3
+ Version: 0.1.0
4
+ Summary: An asyncio interface to TheTVDB v4 API (async port of tvdb-v4-python).
5
+ Author-email: Olivier Balalud <olivier.balalud@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/olivierbalalud/aiotvdb
8
+ Project-URL: Repository, https://github.com/olivierbalalud/aiotvdb
9
+ Project-URL: Changelog, https://github.com/olivierbalalud/aiotvdb/blob/master/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/olivierbalalud/aiotvdb/issues
11
+ Keywords: thetvdb,tvdb,asyncio,async,api,client
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Framework :: AsyncIO
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Multimedia
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: httpx>=0.27
28
+ Provides-Extra: test
29
+ Requires-Dist: pytest>=8; extra == "test"
30
+ Requires-Dist: pytest-asyncio>=0.23; extra == "test"
31
+ Requires-Dist: respx>=0.21; extra == "test"
32
+ Requires-Dist: pytest-httpserver>=1.0; extra == "test"
33
+ Requires-Dist: pytest-cov>=5; extra == "test"
34
+ Requires-Dist: mypy>=1.8; extra == "test"
35
+ Requires-Dist: pyright>=1.1.350; extra == "test"
36
+ Dynamic: license-file
37
+
38
+ # aiotvdb
39
+ asyncio version of tvdb-v4-python
40
+
41
+ [![CI](https://github.com/olivierbalalud/aiotvdb/actions/workflows/ci.yml/badge.svg)](https://github.com/olivierbalalud/aiotvdb/actions/workflows/ci.yml)
42
+
43
+ `aiotvdb` is an async port of the official [`tvdb-v4-python`](https://github.com/thetvdb/tvdb-v4-python)
44
+ client for [TheTVDB](https://thetvdb.com) v4 API. It mirrors upstream's method
45
+ surface exactly, but every endpoint is an `async def` coroutine backed by
46
+ [`httpx`](https://www.python-httpx.org/) — so you can run many requests
47
+ concurrently instead of one at a time.
48
+
49
+ ## Installation
50
+
51
+ Requires Python 3.10+.
52
+
53
+ ```bash
54
+ pip install aiotvdb # once published
55
+ pip install -e ".[test]" # for local development (installs test deps)
56
+ ```
57
+
58
+ You will need an API key from your [TheTVDB account](https://thetvdb.com/dashboard/account/apikey).
59
+ Subscriber API keys also take a PIN.
60
+
61
+ ## Getting Started
62
+
63
+ ```python
64
+ import asyncio
65
+ from aiotvdb import TVDB
66
+
67
+ async def main():
68
+ async with TVDB("YOUR_API_KEY") as tvdb: # add a PIN: TVDB(key, "PIN")
69
+ # Login happens lazily on the first request and is reused afterwards.
70
+ friends = await tvdb.get_series(79168)
71
+ print(friends["name"])
72
+
73
+ # The payoff: fan out many calls concurrently.
74
+ ids = [79168, 81189, 73244]
75
+ series = await asyncio.gather(*(tvdb.get_series(i) for i in ids))
76
+ print([s["name"] for s in series])
77
+
78
+ results = await tvdb.search("Friends", type="series")
79
+ print(len(results))
80
+
81
+ asyncio.run(main())
82
+ ```
83
+
84
+ Methods return the raw `data` payload (`dict`/`list`) exactly as TheTVDB returns
85
+ it. Errors raise `TVDBError` subclasses (`TVDBAuthError`, `TVDBResponseError`);
86
+ an expired token is refreshed and the request retried automatically.
87
+
88
+ Prefer to manage the lifecycle yourself, or share an existing client?
89
+
90
+ ```python
91
+ tvdb = TVDB("YOUR_API_KEY")
92
+ try:
93
+ await tvdb.get_series(79168)
94
+ finally:
95
+ await tvdb.aclose()
96
+ ```
97
+
98
+ ## Changelog
99
+
100
+ Release history is recorded in
101
+ [`CHANGELOG.md`](https://github.com/olivierbalalud/aiotvdb/blob/master/CHANGELOG.md),
102
+ following [Keep a Changelog](https://keepachangelog.com) and
103
+ [Semantic Versioning](https://semver.org).
104
+
105
+ ## Development
106
+
107
+ ```bash
108
+ pytest # full suite (incl. the ~10s concurrency timing test)
109
+ pytest -m "not timing" # fast suite, skip wall-clock timing test
110
+ ruff check . && ruff format .
111
+ mypy && pyright # type checks (strict on src/aiotvdb)
112
+ ```
113
+
114
+ Tests run offline against mocked HTTP (`respx`) and a local socket server
115
+ (`pytest-httpserver`); no API key is needed. Coverage is enforced at 90%.
116
+
117
+ The library is **fully typed** (PEP 561): it ships a `py.typed` marker, so your
118
+ type checker uses its annotations, and both mypy and pyright run strict over the
119
+ package in CI.
120
+
121
+ ### Live integration tests
122
+
123
+ A separate, opt-in suite exercises the client against the **real TheTVDB API**
124
+ (`tests/test_live*.py`). It is **skipped by default** — it runs only when you pass
125
+ `--run-live` *and* a `TVDB_APIKEY` is available, so the normal suite and CI never
126
+ need a key or network.
127
+
128
+ 1. Create a `.env` file at the project root (it is git-ignored):
129
+
130
+ ```dotenv
131
+ TVDB_APIKEY=your-api-key-here
132
+ # TVDB_PIN=your-pin # only for subscriber/user-supported keys
133
+ ```
134
+
135
+ Get a key from your [TheTVDB account](https://thetvdb.com/dashboard/account/apikey).
136
+ The `.env` is loaded automatically by `tests/conftest.py`. (Alternatively, export
137
+ `TVDB_APIKEY` in your shell instead of using `.env`.)
138
+
139
+ 2. Run the live tests with `--run-live`. Use `--no-cov` so the live-only subset
140
+ doesn't trip the 90% coverage gate:
141
+
142
+ ```bash
143
+ pytest --run-live tests/test_live.py tests/test_live_i18n.py tests/test_live_breadth.py --no-cov
144
+ pytest --run-live -m live --no-cov # equivalent: select every live test
145
+ pytest --run-live --no-cov # whole suite, live tests included
146
+ ```
147
+
148
+ Without `--run-live` (or without a key) these tests report as skipped.
149
+
150
+ ## Attribution
151
+
152
+ `aiotvdb` is an **independent async reimplementation** that models the public
153
+ method surface of the official [`tvdb-v4-python`](https://github.com/thetvdb/tvdb-v4-python)
154
+ client — the method names and signatures are kept compatible so it's drop-in
155
+ familiar. The endpoint paths themselves are facts of TheTVDB's public v4 API. The
156
+ implementation here is original async code (httpx-based) and is **not** copied from
157
+ upstream.
158
+
159
+ Note that the upstream `tvdb-v4-python` project **provides no license information**.
160
+ `aiotvdb`'s own code is licensed under the [MIT License](LICENSE); that license
161
+ covers this project's original work only and implies no endorsement by, or
162
+ relationship with, TheTVDB.
163
+
164
+ ## How this code was produced
165
+
166
+ > **Transparency notice.** This project is generated using AI. The code, tests, and
167
+ > documentation are produced with **[Claude Code](https://claude.com/claude-code)**
168
+ > (Anthropic), assisted by the **Matt Pocock skills** collection
169
+ > (<https://github.com/mattpocock/skills>) — e.g. the `grill-me` skill was used to
170
+ > stress-test the design, and others (such as `tdd` and `to-prd`) may be used during
171
+ > implementation. Design decisions and their reasoning are recorded in
172
+ > [`docs/PRD.md`](https://github.com/olivierbalalud/aiotvdb/blob/master/docs/PRD.md).
@@ -0,0 +1,135 @@
1
+ # aiotvdb
2
+ asyncio version of tvdb-v4-python
3
+
4
+ [![CI](https://github.com/olivierbalalud/aiotvdb/actions/workflows/ci.yml/badge.svg)](https://github.com/olivierbalalud/aiotvdb/actions/workflows/ci.yml)
5
+
6
+ `aiotvdb` is an async port of the official [`tvdb-v4-python`](https://github.com/thetvdb/tvdb-v4-python)
7
+ client for [TheTVDB](https://thetvdb.com) v4 API. It mirrors upstream's method
8
+ surface exactly, but every endpoint is an `async def` coroutine backed by
9
+ [`httpx`](https://www.python-httpx.org/) — so you can run many requests
10
+ concurrently instead of one at a time.
11
+
12
+ ## Installation
13
+
14
+ Requires Python 3.10+.
15
+
16
+ ```bash
17
+ pip install aiotvdb # once published
18
+ pip install -e ".[test]" # for local development (installs test deps)
19
+ ```
20
+
21
+ You will need an API key from your [TheTVDB account](https://thetvdb.com/dashboard/account/apikey).
22
+ Subscriber API keys also take a PIN.
23
+
24
+ ## Getting Started
25
+
26
+ ```python
27
+ import asyncio
28
+ from aiotvdb import TVDB
29
+
30
+ async def main():
31
+ async with TVDB("YOUR_API_KEY") as tvdb: # add a PIN: TVDB(key, "PIN")
32
+ # Login happens lazily on the first request and is reused afterwards.
33
+ friends = await tvdb.get_series(79168)
34
+ print(friends["name"])
35
+
36
+ # The payoff: fan out many calls concurrently.
37
+ ids = [79168, 81189, 73244]
38
+ series = await asyncio.gather(*(tvdb.get_series(i) for i in ids))
39
+ print([s["name"] for s in series])
40
+
41
+ results = await tvdb.search("Friends", type="series")
42
+ print(len(results))
43
+
44
+ asyncio.run(main())
45
+ ```
46
+
47
+ Methods return the raw `data` payload (`dict`/`list`) exactly as TheTVDB returns
48
+ it. Errors raise `TVDBError` subclasses (`TVDBAuthError`, `TVDBResponseError`);
49
+ an expired token is refreshed and the request retried automatically.
50
+
51
+ Prefer to manage the lifecycle yourself, or share an existing client?
52
+
53
+ ```python
54
+ tvdb = TVDB("YOUR_API_KEY")
55
+ try:
56
+ await tvdb.get_series(79168)
57
+ finally:
58
+ await tvdb.aclose()
59
+ ```
60
+
61
+ ## Changelog
62
+
63
+ Release history is recorded in
64
+ [`CHANGELOG.md`](https://github.com/olivierbalalud/aiotvdb/blob/master/CHANGELOG.md),
65
+ following [Keep a Changelog](https://keepachangelog.com) and
66
+ [Semantic Versioning](https://semver.org).
67
+
68
+ ## Development
69
+
70
+ ```bash
71
+ pytest # full suite (incl. the ~10s concurrency timing test)
72
+ pytest -m "not timing" # fast suite, skip wall-clock timing test
73
+ ruff check . && ruff format .
74
+ mypy && pyright # type checks (strict on src/aiotvdb)
75
+ ```
76
+
77
+ Tests run offline against mocked HTTP (`respx`) and a local socket server
78
+ (`pytest-httpserver`); no API key is needed. Coverage is enforced at 90%.
79
+
80
+ The library is **fully typed** (PEP 561): it ships a `py.typed` marker, so your
81
+ type checker uses its annotations, and both mypy and pyright run strict over the
82
+ package in CI.
83
+
84
+ ### Live integration tests
85
+
86
+ A separate, opt-in suite exercises the client against the **real TheTVDB API**
87
+ (`tests/test_live*.py`). It is **skipped by default** — it runs only when you pass
88
+ `--run-live` *and* a `TVDB_APIKEY` is available, so the normal suite and CI never
89
+ need a key or network.
90
+
91
+ 1. Create a `.env` file at the project root (it is git-ignored):
92
+
93
+ ```dotenv
94
+ TVDB_APIKEY=your-api-key-here
95
+ # TVDB_PIN=your-pin # only for subscriber/user-supported keys
96
+ ```
97
+
98
+ Get a key from your [TheTVDB account](https://thetvdb.com/dashboard/account/apikey).
99
+ The `.env` is loaded automatically by `tests/conftest.py`. (Alternatively, export
100
+ `TVDB_APIKEY` in your shell instead of using `.env`.)
101
+
102
+ 2. Run the live tests with `--run-live`. Use `--no-cov` so the live-only subset
103
+ doesn't trip the 90% coverage gate:
104
+
105
+ ```bash
106
+ pytest --run-live tests/test_live.py tests/test_live_i18n.py tests/test_live_breadth.py --no-cov
107
+ pytest --run-live -m live --no-cov # equivalent: select every live test
108
+ pytest --run-live --no-cov # whole suite, live tests included
109
+ ```
110
+
111
+ Without `--run-live` (or without a key) these tests report as skipped.
112
+
113
+ ## Attribution
114
+
115
+ `aiotvdb` is an **independent async reimplementation** that models the public
116
+ method surface of the official [`tvdb-v4-python`](https://github.com/thetvdb/tvdb-v4-python)
117
+ client — the method names and signatures are kept compatible so it's drop-in
118
+ familiar. The endpoint paths themselves are facts of TheTVDB's public v4 API. The
119
+ implementation here is original async code (httpx-based) and is **not** copied from
120
+ upstream.
121
+
122
+ Note that the upstream `tvdb-v4-python` project **provides no license information**.
123
+ `aiotvdb`'s own code is licensed under the [MIT License](LICENSE); that license
124
+ covers this project's original work only and implies no endorsement by, or
125
+ relationship with, TheTVDB.
126
+
127
+ ## How this code was produced
128
+
129
+ > **Transparency notice.** This project is generated using AI. The code, tests, and
130
+ > documentation are produced with **[Claude Code](https://claude.com/claude-code)**
131
+ > (Anthropic), assisted by the **Matt Pocock skills** collection
132
+ > (<https://github.com/mattpocock/skills>) — e.g. the `grill-me` skill was used to
133
+ > stress-test the design, and others (such as `tdd` and `to-prd`) may be used during
134
+ > implementation. Design decisions and their reasoning are recorded in
135
+ > [`docs/PRD.md`](https://github.com/olivierbalalud/aiotvdb/blob/master/docs/PRD.md).
@@ -0,0 +1,95 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "aiotvdb"
7
+ version = "0.1.0"
8
+ description = "An asyncio interface to TheTVDB v4 API (async port of tvdb-v4-python)."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Olivier Balalud", email = "olivier.balalud@gmail.com" }]
14
+ keywords = ["thetvdb", "tvdb", "asyncio", "async", "api", "client"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Framework :: AsyncIO",
18
+ "Intended Audience :: Developers",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Multimedia",
26
+ "Topic :: Software Development :: Libraries",
27
+ "Typing :: Typed",
28
+ ]
29
+ dependencies = ["httpx>=0.27"]
30
+
31
+ [project.optional-dependencies]
32
+ test = [
33
+ "pytest>=8",
34
+ "pytest-asyncio>=0.23",
35
+ "respx>=0.21",
36
+ "pytest-httpserver>=1.0",
37
+ "pytest-cov>=5",
38
+ "mypy>=1.8",
39
+ "pyright>=1.1.350",
40
+ ]
41
+
42
+ [project.urls]
43
+ Homepage = "https://github.com/olivierbalalud/aiotvdb"
44
+ Repository = "https://github.com/olivierbalalud/aiotvdb"
45
+ Changelog = "https://github.com/olivierbalalud/aiotvdb/blob/master/CHANGELOG.md"
46
+ Issues = "https://github.com/olivierbalalud/aiotvdb/issues"
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.setuptools.package-data]
52
+ aiotvdb = ["py.typed"]
53
+
54
+ [tool.mypy]
55
+ python_version = "3.10"
56
+ strict = true
57
+ # Endpoint methods return parsed JSON (Any) typed as dict/list at the boundary;
58
+ # that is the library's contract, not an accidental Any leak.
59
+ warn_return_any = false
60
+ files = ["src"]
61
+
62
+ [tool.pyright]
63
+ include = ["src"]
64
+ pythonVersion = "3.10"
65
+ typeCheckingMode = "strict"
66
+ venvPath = "."
67
+ venv = ".venv"
68
+
69
+ [tool.pytest.ini_options]
70
+ testpaths = ["tests"]
71
+ asyncio_mode = "auto"
72
+ addopts = "--cov --cov-report=term-missing --cov-report=xml --cov-report=html"
73
+ markers = [
74
+ "timing: wall-clock timing tests (concurrency proof); deselect with -m 'not timing'",
75
+ "live: opt-in tests against the real TheTVDB API; require --run-live and TVDB_APIKEY",
76
+ ]
77
+
78
+ [tool.coverage.run]
79
+ branch = true
80
+ source = ["aiotvdb"]
81
+
82
+ [tool.coverage.report]
83
+ show_missing = true
84
+ fail_under = 90
85
+
86
+ [tool.ruff]
87
+ target-version = "py310"
88
+ line-length = 100
89
+ src = ["src", "tests"]
90
+
91
+ [tool.ruff.lint]
92
+ select = ["E", "F", "I", "UP", "B", "W"]
93
+
94
+ [tool.ruff.lint.isort]
95
+ known-first-party = ["aiotvdb"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ """aiotvdb — an asyncio interface to TheTVDB v4 API.
2
+
3
+ An async port of the official ``tvdb-v4-python`` client.
4
+ """
5
+
6
+ from importlib.metadata import PackageNotFoundError, version
7
+
8
+ from aiotvdb.client import TVDB
9
+ from aiotvdb.exceptions import TVDBAuthError, TVDBError, TVDBResponseError
10
+
11
+ try:
12
+ __version__ = version("aiotvdb")
13
+ except PackageNotFoundError: # pragma: no cover - package not installed
14
+ __version__ = "0.0.0"
15
+
16
+ __all__ = [
17
+ "TVDB",
18
+ "TVDBAuthError",
19
+ "TVDBError",
20
+ "TVDBResponseError",
21
+ "__version__",
22
+ ]