cocapi 3.1.0__tar.gz → 4.0.1__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.
Files changed (65) hide show
  1. cocapi-4.0.1/.github/workflows/docs.yml +33 -0
  2. {cocapi-3.1.0 → cocapi-4.0.1}/.gitignore +3 -0
  3. cocapi-4.0.1/PKG-INFO +256 -0
  4. cocapi-4.0.1/README.md +217 -0
  5. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/__init__.py +15 -2
  6. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/async_client.py +109 -7
  7. cocapi-4.0.1/cocapi/cli.py +535 -0
  8. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/client.py +300 -7
  9. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/config.py +8 -0
  10. cocapi-4.0.1/cocapi/events/__init__.py +50 -0
  11. cocapi-4.0.1/cocapi/events/_diff.py +120 -0
  12. cocapi-4.0.1/cocapi/events/_state.py +130 -0
  13. cocapi-4.0.1/cocapi/events/_stream.py +278 -0
  14. cocapi-4.0.1/cocapi/events/_types.py +75 -0
  15. cocapi-4.0.1/cocapi/events/_war_fsm.py +38 -0
  16. cocapi-4.0.1/cocapi/events/_watchers.py +639 -0
  17. cocapi-4.0.1/cocapi/key_manager.py +825 -0
  18. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/model_registry.py +2 -5
  19. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/schemas.py +90 -0
  20. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/utils.py +27 -0
  21. cocapi-4.0.1/docs/changelog.md +46 -0
  22. cocapi-4.0.1/docs/examples.md +123 -0
  23. cocapi-4.0.1/docs/getting-started/authentication.md +82 -0
  24. cocapi-4.0.1/docs/getting-started/installation.md +53 -0
  25. cocapi-4.0.1/docs/getting-started/quickstart.md +76 -0
  26. cocapi-4.0.1/docs/guides/async.md +112 -0
  27. cocapi-4.0.1/docs/guides/caching.md +57 -0
  28. cocapi-4.0.1/docs/guides/cli.md +94 -0
  29. cocapi-4.0.1/docs/guides/configuration.md +88 -0
  30. cocapi-4.0.1/docs/guides/error-handling.md +86 -0
  31. cocapi-4.0.1/docs/guides/events.md +152 -0
  32. cocapi-4.0.1/docs/guides/metrics.md +54 -0
  33. cocapi-4.0.1/docs/guides/middleware.md +83 -0
  34. cocapi-4.0.1/docs/guides/pagination-batch.md +88 -0
  35. cocapi-4.0.1/docs/guides/pydantic-models.md +70 -0
  36. cocapi-4.0.1/docs/index.md +62 -0
  37. cocapi-4.0.1/mkdocs.yml +135 -0
  38. {cocapi-3.1.0 → cocapi-4.0.1}/pyproject.toml +37 -4
  39. cocapi-4.0.1/sonar-project.properties +4 -0
  40. cocapi-4.0.1/uv.lock +1305 -0
  41. cocapi-3.1.0/PKG-INFO +0 -1402
  42. cocapi-3.1.0/README.md +0 -1377
  43. cocapi-3.1.0/_config.yml +0 -1
  44. cocapi-3.1.0/tests/conftest.py +0 -158
  45. cocapi-3.1.0/tests/test_async_api.py +0 -303
  46. cocapi-3.1.0/tests/test_cocapi.py +0 -414
  47. cocapi-3.1.0/uv.lock +0 -585
  48. {cocapi-3.1.0 → cocapi-4.0.1}/.github/FUNDING.yml +0 -0
  49. {cocapi-3.1.0 → cocapi-4.0.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  50. {cocapi-3.1.0 → cocapi-4.0.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  51. {cocapi-3.1.0 → cocapi-4.0.1}/.github/workflows/ci.yml +0 -0
  52. {cocapi-3.1.0 → cocapi-4.0.1}/.github/workflows/release.yml +0 -0
  53. {cocapi-3.1.0 → cocapi-4.0.1}/.pre-commit-config.yaml +0 -0
  54. {cocapi-3.1.0 → cocapi-4.0.1}/CODE_OF_CONDUCT.md +0 -0
  55. {cocapi-3.1.0 → cocapi-4.0.1}/LICENSE +0 -0
  56. {cocapi-3.1.0 → cocapi-4.0.1}/SECURITY.md +0 -0
  57. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/api_methods.py +0 -0
  58. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/cache.py +0 -0
  59. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/cocapi.py +0 -0
  60. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/metrics.py +0 -0
  61. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/middleware.py +0 -0
  62. {cocapi-3.1.0 → cocapi-4.0.1}/cocapi/models.py +0 -0
  63. /cocapi-3.1.0/tests/__init__.py → /cocapi-4.0.1/cocapi/py.typed +0 -0
  64. {cocapi-3.1.0 → cocapi-4.0.1}/mypy.ini +0 -0
  65. {cocapi-3.1.0 → cocapi-4.0.1}/setup.py +0 -0
@@ -0,0 +1,33 @@
1
+ name: Deploy Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ concurrency:
12
+ group: deploy-docs
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ deploy:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v3
28
+
29
+ - name: Install dependencies
30
+ run: uv sync --dev --extra pydantic --extra docs
31
+
32
+ - name: Build and deploy docs
33
+ run: uv run mkdocs gh-deploy --force
@@ -160,3 +160,6 @@ cython_debug/
160
160
  #.idea/
161
161
  .vscode/
162
162
  .ruff_cache/
163
+
164
+ # cocapi key storage (credential-based auth)
165
+ .cocapi/
cocapi-4.0.1/PKG-INFO ADDED
@@ -0,0 +1,256 @@
1
+ Metadata-Version: 2.4
2
+ Name: cocapi
3
+ Version: 4.0.1
4
+ Summary: Async & sync Python wrapper for the Clash of Clans API with auto key management
5
+ Project-URL: Homepage, https://github.com/tonybenoy/cocapi
6
+ Project-URL: Documentation, https://tonybenoy.github.io/cocapi/
7
+ Project-URL: Repository, https://github.com/tonybenoy/cocapi
8
+ Project-URL: Issues, https://github.com/tonybenoy/cocapi/issues
9
+ Author-email: Tony Benoy <me@tonybenoy.com>
10
+ License: GPL-3.0
11
+ License-File: LICENSE
12
+ Keywords: api-wrapper,async,clans,clash,clash-of-clans,coc,coc-api,game-api,supercell
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Framework :: AsyncIO
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Games/Entertainment :: Real Time Strategy
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Requires-Dist: httpx>=0.23.0
27
+ Provides-Extra: cli
28
+ Requires-Dist: typer>=0.9.0; extra == 'cli'
29
+ Provides-Extra: docs
30
+ Requires-Dist: mkdocs-gen-files>=0.5.0; extra == 'docs'
31
+ Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == 'docs'
32
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
33
+ Requires-Dist: mkdocs-section-index>=0.3.9; extra == 'docs'
34
+ Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
35
+ Requires-Dist: mkdocstrings[python]>=0.27.0; extra == 'docs'
36
+ Provides-Extra: pydantic
37
+ Requires-Dist: pydantic>=2.0.0; extra == 'pydantic'
38
+ Description-Content-Type: text/markdown
39
+
40
+ <p>
41
+ <a href="https://github.com/tonybenoy/cocapi/actions">
42
+ <img src="https://github.com/tonybenoy/cocapi/workflows/CI/badge.svg" alt="CI Status" height="20">
43
+ </a>
44
+ <a href="https://pypi.org/project/cocapi/"><img src="https://img.shields.io/pypi/v/cocapi" alt="Pypi version" height="21"></a>
45
+ <a href="https://pypi.org/project/cocapi/"><img src="https://img.shields.io/pypi/dm/cocapi" alt="PyPI Downloads" height="21"></a>
46
+ <a href="https://tonybenoy.github.io/cocapi/"><img src="https://img.shields.io/badge/docs-mkdocs-blue.svg" alt="Documentation" height="21"></a>
47
+ </p>
48
+ <p>
49
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python version" height="17"></a>
50
+ <a href="https://github.com/tonybenoy/cocapi/blob/main/LICENSE"><img src="https://img.shields.io/github/license/tonybenoy/cocapi" alt="License" height="17"></a>
51
+ <a href="https://github.com/astral-sh/ruff">
52
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" height="17">
53
+ </a>
54
+ </p>
55
+
56
+ # cocapi
57
+
58
+ A Python wrapper for the official [Clash of Clans API](https://developer.clashofclans.com/) with full async support, automatic key management, caching, retries, and optional Pydantic models.
59
+
60
+ **[Full Documentation](https://tonybenoy.github.io/cocapi/)**
61
+
62
+ ## Features
63
+
64
+ - **Sync & async** — same methods, same names, both modes
65
+ - **Automatic key management** — login with email/password, keys are created, reused, and rotated automatically
66
+ - **Caching** — TTL-based response caching with stats
67
+ - **Retries** — exponential backoff for rate limits and server errors
68
+ - **Pagination & batch** — `paginate()` auto-follows cursors, `batch()` fetches many resources at once
69
+ - **Event polling** — real-time monitoring of clans, wars, and players with `async for` or callbacks
70
+ - **Pydantic models** — optional typed response objects with IDE autocompletion
71
+ - **Middleware** — plug in custom request/response processing
72
+ - **CLI** — `cocapi clan "#2PP"` from the terminal
73
+ - **Maintenance detection** — automatic detection of API maintenance windows
74
+
75
+ ## Install
76
+
77
+ ```bash
78
+ pip install cocapi
79
+
80
+ # With Pydantic model support
81
+ pip install 'cocapi[pydantic]'
82
+
83
+ # With CLI
84
+ pip install 'cocapi[cli]'
85
+ ```
86
+
87
+ Requires Python 3.10+.
88
+
89
+ ## Quick Start
90
+
91
+ ### With an API Token
92
+
93
+ Get a token from [developer.clashofclans.com](https://developer.clashofclans.com/):
94
+
95
+ ```python
96
+ from cocapi import CocApi
97
+
98
+ api = CocApi("your_api_token")
99
+
100
+ clan = api.clan_tag("#2PP")
101
+ print(clan["name"])
102
+
103
+ player = api.players("#900PUCPV")
104
+ print(player["trophies"])
105
+ ```
106
+
107
+ ### With Email/Password (Automatic Key Management)
108
+
109
+ Skip manual key creation entirely. cocapi logs into the developer portal, detects your IP, and manages keys for you:
110
+
111
+ ```python
112
+ from cocapi import CocApi
113
+
114
+ api = CocApi.from_credentials("you@example.com", "your_password")
115
+ clan = api.clan_tag("#2PP")
116
+ ```
117
+
118
+ Keys are created automatically, reused when valid, and rotated when your IP changes. See the [Authentication guide](https://tonybenoy.github.io/cocapi/getting-started/authentication/) for details.
119
+
120
+ ### Async
121
+
122
+ ```python
123
+ import asyncio
124
+ from cocapi import CocApi
125
+
126
+ async def main():
127
+ async with CocApi("your_token") as api:
128
+ clan = await api.clan_tag("#2PP")
129
+ player = await api.players("#900PUCPV")
130
+ print(clan["name"], player["trophies"])
131
+
132
+ asyncio.run(main())
133
+ ```
134
+
135
+ See the [Async guide](https://tonybenoy.github.io/cocapi/guides/async/) for more patterns.
136
+
137
+ ## Configuration
138
+
139
+ All options are set through `ApiConfig`:
140
+
141
+ ```python
142
+ from cocapi import CocApi, ApiConfig
143
+
144
+ config = ApiConfig(
145
+ timeout=30,
146
+ max_retries=3,
147
+ enable_caching=True,
148
+ cache_ttl=600,
149
+ enable_rate_limiting=True, # async only
150
+ requests_per_second=10.0,
151
+ enable_metrics=True,
152
+ use_pydantic_models=True, # requires cocapi[pydantic]
153
+ )
154
+
155
+ api = CocApi("your_token", config=config)
156
+ ```
157
+
158
+ See the [Configuration guide](https://tonybenoy.github.io/cocapi/guides/configuration/) for all options.
159
+
160
+ ## Pagination & Batch
161
+
162
+ ```python
163
+ # Auto-paginate through all clan members
164
+ for member in api.paginate(api.clan_members, "#CLAN_TAG"):
165
+ print(member["name"])
166
+
167
+ # Fetch multiple players at once
168
+ results = api.batch(api.players, ["#TAG1", "#TAG2", "#TAG3"])
169
+ ```
170
+
171
+ Both work in sync and async. See the [Pagination & Batch guide](https://tonybenoy.github.io/cocapi/guides/pagination-batch/).
172
+
173
+ ## Event Polling
174
+
175
+ Monitor clans, wars, and players in real time. Async only.
176
+
177
+ ```python
178
+ from cocapi.events import EventStream, EventType
179
+
180
+ async with CocApi("token") as api:
181
+ stream = EventStream(api)
182
+ stream.watch_clans(["#2PP"], interval=60)
183
+ stream.watch_wars(["#2PP"], interval=30)
184
+ stream.watch_players(["#900PUCPV"], interval=120)
185
+
186
+ async with stream:
187
+ async for event in stream:
188
+ print(event.event_type, event.tag)
189
+ for change in event.changes:
190
+ print(f" {change.field}: {change.old_value} -> {change.new_value}")
191
+ ```
192
+
193
+ Supports 20+ event types including member join/leave, war state transitions, troop/hero upgrades, maintenance detection, and more. See the [Event Polling guide](https://tonybenoy.github.io/cocapi/guides/events/).
194
+
195
+ ## CLI
196
+
197
+ ```bash
198
+ pip install 'cocapi[cli]'
199
+
200
+ # Login once (key is persisted)
201
+ cocapi login --email you@example.com --password yourpass
202
+
203
+ # Use without --token
204
+ cocapi clan "#2PP"
205
+ cocapi player "#900PUCPV"
206
+ cocapi war "#2PP"
207
+ cocapi search "clash" --limit 5
208
+ cocapi goldpass
209
+ ```
210
+
211
+ See the [CLI guide](https://tonybenoy.github.io/cocapi/guides/cli/) for all commands.
212
+
213
+ ## Error Handling
214
+
215
+ All endpoints return a dict (or Pydantic model). Errors never raise exceptions:
216
+
217
+ ```python
218
+ result = api.clan_tag("#INVALID")
219
+ if result.get("result") == "error":
220
+ print(result["message"]) # Human-readable message
221
+ print(result["error_type"]) # "timeout", "connection", "http", "json", etc.
222
+ print(result.get("status_code"))
223
+ ```
224
+
225
+ See the [Error Handling guide](https://tonybenoy.github.io/cocapi/guides/error-handling/).
226
+
227
+ ## Examples
228
+
229
+ Runnable scripts in the [`examples/`](examples/) folder:
230
+
231
+ | Script | What it covers |
232
+ |---|---|
233
+ | [`basic_usage.py`](examples/basic_usage.py) | Sync: clan info, player info, search, error handling |
234
+ | [`async_usage.py`](examples/async_usage.py) | Async with context manager, concurrent requests |
235
+ | [`credential_auth.py`](examples/credential_auth.py) | Email/password login, key persistence, auto-refresh |
236
+ | [`pagination_batch.py`](examples/pagination_batch.py) | `paginate()` and `batch()` in sync and async |
237
+ | [`event_polling.py`](examples/event_polling.py) | `EventStream` with `async for` — real-time monitoring |
238
+ | [`event_callbacks.py`](examples/event_callbacks.py) | `@stream.on()` decorators and `stream.run()` |
239
+ | [`configuration.py`](examples/configuration.py) | ApiConfig, caching, metrics, middleware |
240
+
241
+ ## API Reference
242
+
243
+ Full API reference with all endpoints, parameters, and response schemas is available in the [documentation](https://tonybenoy.github.io/cocapi/reference/).
244
+
245
+ Key classes:
246
+ - [`CocApi`](https://tonybenoy.github.io/cocapi/reference/client/) — main entry point (sync/async)
247
+ - [`ApiConfig`](https://tonybenoy.github.io/cocapi/reference/config/) — configuration options
248
+ - [`EventStream`](https://tonybenoy.github.io/cocapi/reference/events/) — real-time event polling
249
+ - [Pydantic Schemas](https://tonybenoy.github.io/cocapi/reference/schemas/) — typed response models
250
+ - [All Endpoints](https://tonybenoy.github.io/cocapi/reference/api_methods/) — every API method
251
+
252
+ ## Credits
253
+
254
+ - [All Contributors](../../contributors)
255
+
256
+ *cocapi is not affiliated with SuperCell.*
cocapi-4.0.1/README.md ADDED
@@ -0,0 +1,217 @@
1
+ <p>
2
+ <a href="https://github.com/tonybenoy/cocapi/actions">
3
+ <img src="https://github.com/tonybenoy/cocapi/workflows/CI/badge.svg" alt="CI Status" height="20">
4
+ </a>
5
+ <a href="https://pypi.org/project/cocapi/"><img src="https://img.shields.io/pypi/v/cocapi" alt="Pypi version" height="21"></a>
6
+ <a href="https://pypi.org/project/cocapi/"><img src="https://img.shields.io/pypi/dm/cocapi" alt="PyPI Downloads" height="21"></a>
7
+ <a href="https://tonybenoy.github.io/cocapi/"><img src="https://img.shields.io/badge/docs-mkdocs-blue.svg" alt="Documentation" height="21"></a>
8
+ </p>
9
+ <p>
10
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python version" height="17"></a>
11
+ <a href="https://github.com/tonybenoy/cocapi/blob/main/LICENSE"><img src="https://img.shields.io/github/license/tonybenoy/cocapi" alt="License" height="17"></a>
12
+ <a href="https://github.com/astral-sh/ruff">
13
+ <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" height="17">
14
+ </a>
15
+ </p>
16
+
17
+ # cocapi
18
+
19
+ A Python wrapper for the official [Clash of Clans API](https://developer.clashofclans.com/) with full async support, automatic key management, caching, retries, and optional Pydantic models.
20
+
21
+ **[Full Documentation](https://tonybenoy.github.io/cocapi/)**
22
+
23
+ ## Features
24
+
25
+ - **Sync & async** — same methods, same names, both modes
26
+ - **Automatic key management** — login with email/password, keys are created, reused, and rotated automatically
27
+ - **Caching** — TTL-based response caching with stats
28
+ - **Retries** — exponential backoff for rate limits and server errors
29
+ - **Pagination & batch** — `paginate()` auto-follows cursors, `batch()` fetches many resources at once
30
+ - **Event polling** — real-time monitoring of clans, wars, and players with `async for` or callbacks
31
+ - **Pydantic models** — optional typed response objects with IDE autocompletion
32
+ - **Middleware** — plug in custom request/response processing
33
+ - **CLI** — `cocapi clan "#2PP"` from the terminal
34
+ - **Maintenance detection** — automatic detection of API maintenance windows
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ pip install cocapi
40
+
41
+ # With Pydantic model support
42
+ pip install 'cocapi[pydantic]'
43
+
44
+ # With CLI
45
+ pip install 'cocapi[cli]'
46
+ ```
47
+
48
+ Requires Python 3.10+.
49
+
50
+ ## Quick Start
51
+
52
+ ### With an API Token
53
+
54
+ Get a token from [developer.clashofclans.com](https://developer.clashofclans.com/):
55
+
56
+ ```python
57
+ from cocapi import CocApi
58
+
59
+ api = CocApi("your_api_token")
60
+
61
+ clan = api.clan_tag("#2PP")
62
+ print(clan["name"])
63
+
64
+ player = api.players("#900PUCPV")
65
+ print(player["trophies"])
66
+ ```
67
+
68
+ ### With Email/Password (Automatic Key Management)
69
+
70
+ Skip manual key creation entirely. cocapi logs into the developer portal, detects your IP, and manages keys for you:
71
+
72
+ ```python
73
+ from cocapi import CocApi
74
+
75
+ api = CocApi.from_credentials("you@example.com", "your_password")
76
+ clan = api.clan_tag("#2PP")
77
+ ```
78
+
79
+ Keys are created automatically, reused when valid, and rotated when your IP changes. See the [Authentication guide](https://tonybenoy.github.io/cocapi/getting-started/authentication/) for details.
80
+
81
+ ### Async
82
+
83
+ ```python
84
+ import asyncio
85
+ from cocapi import CocApi
86
+
87
+ async def main():
88
+ async with CocApi("your_token") as api:
89
+ clan = await api.clan_tag("#2PP")
90
+ player = await api.players("#900PUCPV")
91
+ print(clan["name"], player["trophies"])
92
+
93
+ asyncio.run(main())
94
+ ```
95
+
96
+ See the [Async guide](https://tonybenoy.github.io/cocapi/guides/async/) for more patterns.
97
+
98
+ ## Configuration
99
+
100
+ All options are set through `ApiConfig`:
101
+
102
+ ```python
103
+ from cocapi import CocApi, ApiConfig
104
+
105
+ config = ApiConfig(
106
+ timeout=30,
107
+ max_retries=3,
108
+ enable_caching=True,
109
+ cache_ttl=600,
110
+ enable_rate_limiting=True, # async only
111
+ requests_per_second=10.0,
112
+ enable_metrics=True,
113
+ use_pydantic_models=True, # requires cocapi[pydantic]
114
+ )
115
+
116
+ api = CocApi("your_token", config=config)
117
+ ```
118
+
119
+ See the [Configuration guide](https://tonybenoy.github.io/cocapi/guides/configuration/) for all options.
120
+
121
+ ## Pagination & Batch
122
+
123
+ ```python
124
+ # Auto-paginate through all clan members
125
+ for member in api.paginate(api.clan_members, "#CLAN_TAG"):
126
+ print(member["name"])
127
+
128
+ # Fetch multiple players at once
129
+ results = api.batch(api.players, ["#TAG1", "#TAG2", "#TAG3"])
130
+ ```
131
+
132
+ Both work in sync and async. See the [Pagination & Batch guide](https://tonybenoy.github.io/cocapi/guides/pagination-batch/).
133
+
134
+ ## Event Polling
135
+
136
+ Monitor clans, wars, and players in real time. Async only.
137
+
138
+ ```python
139
+ from cocapi.events import EventStream, EventType
140
+
141
+ async with CocApi("token") as api:
142
+ stream = EventStream(api)
143
+ stream.watch_clans(["#2PP"], interval=60)
144
+ stream.watch_wars(["#2PP"], interval=30)
145
+ stream.watch_players(["#900PUCPV"], interval=120)
146
+
147
+ async with stream:
148
+ async for event in stream:
149
+ print(event.event_type, event.tag)
150
+ for change in event.changes:
151
+ print(f" {change.field}: {change.old_value} -> {change.new_value}")
152
+ ```
153
+
154
+ Supports 20+ event types including member join/leave, war state transitions, troop/hero upgrades, maintenance detection, and more. See the [Event Polling guide](https://tonybenoy.github.io/cocapi/guides/events/).
155
+
156
+ ## CLI
157
+
158
+ ```bash
159
+ pip install 'cocapi[cli]'
160
+
161
+ # Login once (key is persisted)
162
+ cocapi login --email you@example.com --password yourpass
163
+
164
+ # Use without --token
165
+ cocapi clan "#2PP"
166
+ cocapi player "#900PUCPV"
167
+ cocapi war "#2PP"
168
+ cocapi search "clash" --limit 5
169
+ cocapi goldpass
170
+ ```
171
+
172
+ See the [CLI guide](https://tonybenoy.github.io/cocapi/guides/cli/) for all commands.
173
+
174
+ ## Error Handling
175
+
176
+ All endpoints return a dict (or Pydantic model). Errors never raise exceptions:
177
+
178
+ ```python
179
+ result = api.clan_tag("#INVALID")
180
+ if result.get("result") == "error":
181
+ print(result["message"]) # Human-readable message
182
+ print(result["error_type"]) # "timeout", "connection", "http", "json", etc.
183
+ print(result.get("status_code"))
184
+ ```
185
+
186
+ See the [Error Handling guide](https://tonybenoy.github.io/cocapi/guides/error-handling/).
187
+
188
+ ## Examples
189
+
190
+ Runnable scripts in the [`examples/`](examples/) folder:
191
+
192
+ | Script | What it covers |
193
+ |---|---|
194
+ | [`basic_usage.py`](examples/basic_usage.py) | Sync: clan info, player info, search, error handling |
195
+ | [`async_usage.py`](examples/async_usage.py) | Async with context manager, concurrent requests |
196
+ | [`credential_auth.py`](examples/credential_auth.py) | Email/password login, key persistence, auto-refresh |
197
+ | [`pagination_batch.py`](examples/pagination_batch.py) | `paginate()` and `batch()` in sync and async |
198
+ | [`event_polling.py`](examples/event_polling.py) | `EventStream` with `async for` — real-time monitoring |
199
+ | [`event_callbacks.py`](examples/event_callbacks.py) | `@stream.on()` decorators and `stream.run()` |
200
+ | [`configuration.py`](examples/configuration.py) | ApiConfig, caching, metrics, middleware |
201
+
202
+ ## API Reference
203
+
204
+ Full API reference with all endpoints, parameters, and response schemas is available in the [documentation](https://tonybenoy.github.io/cocapi/reference/).
205
+
206
+ Key classes:
207
+ - [`CocApi`](https://tonybenoy.github.io/cocapi/reference/client/) — main entry point (sync/async)
208
+ - [`ApiConfig`](https://tonybenoy.github.io/cocapi/reference/config/) — configuration options
209
+ - [`EventStream`](https://tonybenoy.github.io/cocapi/reference/events/) — real-time event polling
210
+ - [Pydantic Schemas](https://tonybenoy.github.io/cocapi/reference/schemas/) — typed response models
211
+ - [All Endpoints](https://tonybenoy.github.io/cocapi/reference/api_methods/) — every API method
212
+
213
+ ## Credits
214
+
215
+ - [All Contributors](../../contributors)
216
+
217
+ *cocapi is not affiliated with SuperCell.*
@@ -1,5 +1,5 @@
1
1
  """
2
- Clash of Clans API Wrapper - cocapi v3.1.0
2
+ Clash of Clans API Wrapper - cocapi v4.0.0
3
3
 
4
4
  A Python wrapper for the official Clash of Clans API with enhanced features:
5
5
  - Async and sync support
@@ -48,6 +48,14 @@ from .client import CocApi
48
48
 
49
49
  # Configuration classes
50
50
  from .config import ApiConfig, CacheEntry, RequestMetric
51
+
52
+ # Key management (credential-based auth)
53
+ from .key_manager import (
54
+ AsyncKeyManager,
55
+ InvalidCredentials,
56
+ KeyManagerError,
57
+ SyncKeyManager,
58
+ )
51
59
  from .metrics import MetricsTracker
52
60
 
53
61
  # Common middleware functions
@@ -115,7 +123,7 @@ except (ImportError, SyntaxError):
115
123
  _SCHEMAS_AVAILABLE = False
116
124
 
117
125
  # Version info
118
- __version__ = "3.1.0"
126
+ __version__ = "4.0.1"
119
127
  __author__ = "Tony Benoy"
120
128
  __email__ = "me@tonybenoy.com"
121
129
 
@@ -131,6 +139,11 @@ __all__ = [
131
139
  "MetricsTracker",
132
140
  "MiddlewareManager",
133
141
  "AsyncRateLimiter",
142
+ # Key management
143
+ "SyncKeyManager",
144
+ "AsyncKeyManager",
145
+ "KeyManagerError",
146
+ "InvalidCredentials",
134
147
  # Data structures
135
148
  "CacheEntry",
136
149
  "RequestMetric",