capmonster-client 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.
- capmonster_client-0.1.0/.gitignore +46 -0
- capmonster_client-0.1.0/LICENSE +15 -0
- capmonster_client-0.1.0/PKG-INFO +211 -0
- capmonster_client-0.1.0/README.md +199 -0
- capmonster_client-0.1.0/examples/check.py +19 -0
- capmonster_client-0.1.0/pyproject.toml +42 -0
- capmonster_client-0.1.0/src/capmonster/__init__.py +79 -0
- capmonster_client-0.1.0/src/capmonster/client.py +299 -0
- capmonster_client-0.1.0/src/capmonster/errors.py +96 -0
- capmonster_client-0.1.0/src/capmonster/tasks.py +230 -0
- capmonster_client-0.1.0/src/capmonster/types.py +76 -0
- capmonster_client-0.1.0/tests/test_client.py +215 -0
- capmonster_client-0.1.0/tests/test_live.py +53 -0
- capmonster_client-0.1.0/uv.lock +291 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
.pnp.*
|
|
4
|
+
.yarn/
|
|
5
|
+
.pnpm-store/
|
|
6
|
+
|
|
7
|
+
# Build
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.tsbuildinfo
|
|
11
|
+
*.egg-info/
|
|
12
|
+
.eggs/
|
|
13
|
+
wheels/
|
|
14
|
+
|
|
15
|
+
# Tests and coverage
|
|
16
|
+
coverage/
|
|
17
|
+
.nyc_output/
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.mypy_cache/
|
|
20
|
+
.ruff_cache/
|
|
21
|
+
htmlcov/
|
|
22
|
+
.coverage
|
|
23
|
+
.coverage.*
|
|
24
|
+
|
|
25
|
+
# Python
|
|
26
|
+
__pycache__/
|
|
27
|
+
*.py[cod]
|
|
28
|
+
*$py.class
|
|
29
|
+
.venv/
|
|
30
|
+
venv/
|
|
31
|
+
env/
|
|
32
|
+
|
|
33
|
+
# Secrets
|
|
34
|
+
.env
|
|
35
|
+
.env.*
|
|
36
|
+
!.env.example
|
|
37
|
+
AGENTS.md
|
|
38
|
+
|
|
39
|
+
# GitBook / HonKit
|
|
40
|
+
_book/
|
|
41
|
+
|
|
42
|
+
# OS and editors
|
|
43
|
+
.DS_Store
|
|
44
|
+
Thumbs.db
|
|
45
|
+
.idea/
|
|
46
|
+
*.swp
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 api-kit contributors
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: capmonster-client
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the CapMonster Cloud captcha recognition API
|
|
5
|
+
Project-URL: Repository, https://github.com/TysikGG/api-kit
|
|
6
|
+
Project-URL: Documentation, https://docs.capmonster.cloud
|
|
7
|
+
License-Expression: ISC
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Python: >=3.10
|
|
10
|
+
Requires-Dist: httpx>=0.27
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# capmonster-client
|
|
14
|
+
|
|
15
|
+
[](https://pypi.org/project/capmonster-client/)
|
|
16
|
+
[](https://pypi.org/project/capmonster-client/)
|
|
17
|
+
[](https://opensource.org/licenses/ISC)
|
|
18
|
+
|
|
19
|
+
Typed Python client for the [CapMonster Cloud API](https://docs.capmonster.cloud). Supports reCAPTCHA v2/v3/Enterprise, Cloudflare Turnstile (including Challenge and Waiting Room), GeeTest, ImageToText, ComplexImage, DataDome, Amazon AWS WAF, TenDI (Tencent), Binance, and the other task types documented by CapMonster Cloud. Built on [HTTPX](https://www.python-httpx.org).
|
|
20
|
+
|
|
21
|
+
Official API documentation: <https://docs.capmonster.cloud>
|
|
22
|
+
|
|
23
|
+
The import package is `capmonster`. The distribution name is `capmonster-client` so it does not collide with other projects on PyPI.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- 🧩 **Documented task types** — Helpers for reCAPTCHA v2/v3/Enterprise, Turnstile, GeeTest, ImageToText, ComplexImage, DataDome, Amazon WAF, TenDI, Binance, FunCaptcha, hCaptcha, Basilisk, Imperva, Prosopo, Yidun, MTCaptcha, Altcha, Friendly Captcha, Temu, Castle, TSPD, Hunt, and Alibaba.
|
|
30
|
+
- ⏳ **Automated polling** — `wait_for_result()` and `solve()` poll until the solution is ready. `CAPTCHA_NOT_READY` stays in the processing state.
|
|
31
|
+
- 💰 **Balance tracking** — `get_balance()` reads the account balance and does not spend credit.
|
|
32
|
+
- 🏷️ **Developer id** — `softId` is omitted until you set it. CapMonster's developer program is still pending, so `DEFAULT_SOFT_ID` is empty.
|
|
33
|
+
- 🐍 **Modern Python** — Type annotations, context manager support (`with CapMonster(...) as client:`).
|
|
34
|
+
- 🚨 **Structured errors** — `CapMonsterError` carries `error_id` and `error_code` for every documented API error.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install capmonster-client
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Requires Python 3.10 or higher.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quick Start (Safe Check)
|
|
49
|
+
|
|
50
|
+
The quick check only inspects your account balance. It does not submit tasks or spend credits.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import os
|
|
54
|
+
from capmonster import CapMonster
|
|
55
|
+
|
|
56
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
57
|
+
balance = client.get_balance()
|
|
58
|
+
print(f"Balance: {balance['balance']}")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Usage Guide
|
|
64
|
+
|
|
65
|
+
### 1. High-Level Solve (Recommended)
|
|
66
|
+
|
|
67
|
+
`client.solve()` submits the task and waits until the solution is ready:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
import os
|
|
71
|
+
from capmonster import CapMonster, turnstile
|
|
72
|
+
|
|
73
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
74
|
+
solution = client.solve(turnstile("https://example.com/", "0x4AAAAAAA..."))
|
|
75
|
+
print("Turnstile token:", solution["token"])
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 2. Solving reCAPTCHA v2
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from capmonster import CapMonster, recaptcha_v2
|
|
82
|
+
|
|
83
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
84
|
+
solution = client.solve(recaptcha_v2(
|
|
85
|
+
"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high",
|
|
86
|
+
"6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd",
|
|
87
|
+
))
|
|
88
|
+
print(solution["gRecaptchaResponse"])
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. Manual Task Lifecycle
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from capmonster import CapMonster, turnstile
|
|
95
|
+
|
|
96
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
97
|
+
task_id = client.create_task(turnstile("https://example.com/", "0x4AAAAAAA..."))
|
|
98
|
+
result = client.get_task_result(task_id)
|
|
99
|
+
if result["status"] == "ready":
|
|
100
|
+
print("Solution:", result["solution"])
|
|
101
|
+
else:
|
|
102
|
+
print("Task is still processing...")
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
You can also pass a raw `dict`. `type` is required. Custom captchas (DataDome, TenDI, and the others listed below) also require `class`.
|
|
106
|
+
|
|
107
|
+
### 4. Developer software id
|
|
108
|
+
|
|
109
|
+
`create_task` sends `softId` only when it is set:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from capmonster import DEFAULT_SOFT_ID, CapMonster
|
|
113
|
+
|
|
114
|
+
print(DEFAULT_SOFT_ID) # ""
|
|
115
|
+
|
|
116
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"], soft_id=12345) as client:
|
|
117
|
+
...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
TODO: replace `DEFAULT_SOFT_ID` in `src/capmonster/client.py` once CapMonster assigns a numeric id.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Task Types
|
|
125
|
+
|
|
126
|
+
| Captcha | `type` | `class` | Helper |
|
|
127
|
+
| :--- | :--- | :--- | :--- |
|
|
128
|
+
| reCAPTCHA v2 | `RecaptchaV2Task` | | `recaptcha_v2` |
|
|
129
|
+
| reCAPTCHA v2 Enterprise | `RecaptchaV2EnterpriseTask` | | `recaptcha_v2_enterprise` |
|
|
130
|
+
| reCAPTCHA v3 | `RecaptchaV3TaskProxyless` | | `recaptcha_v3` |
|
|
131
|
+
| reCAPTCHA v3 Enterprise | `RecaptchaV3EnterpriseTask` | | `recaptcha_v3_enterprise` |
|
|
132
|
+
| Cloudflare Turnstile / Challenge / Waiting Room | `TurnstileTask` | | `turnstile` |
|
|
133
|
+
| GeeTest v3 / v4 | `GeeTestTask` | | `geetest` |
|
|
134
|
+
| ImageToText | `ImageToTextTask` | | `image_to_text` |
|
|
135
|
+
| ComplexImage (click, grid, recognition) | `ComplexImageTask` | `recaptcha`, `hcaptcha`, `funcaptcha`, `recognition` | `complex_image` |
|
|
136
|
+
| DataDome | `CustomTask` | `DataDome` | `datadome` |
|
|
137
|
+
| TenDI (Tencent) | `CustomTask` | `TenDI` | `tendi` |
|
|
138
|
+
| Amazon AWS WAF | `AmazonTask` | | `amazon` |
|
|
139
|
+
| Binance | `BinanceTask` | | `binance` |
|
|
140
|
+
| FunCaptcha | `FunCaptchaTask` | | `funcaptcha` |
|
|
141
|
+
| hCaptcha | `HCaptchaTask` | | `hcaptcha` |
|
|
142
|
+
| Basilisk | `CustomTask` | `Basilisk` | `basilisk` |
|
|
143
|
+
| Imperva (Incapsula) | `CustomTask` | `Imperva` | `imperva` |
|
|
144
|
+
| Prosopo | `ProsopoTask` | | `prosopo` |
|
|
145
|
+
| Yidun | `YidunTask` | | `yidun` |
|
|
146
|
+
| MTCaptcha | `MTCaptchaTask` | | `mtcaptcha` |
|
|
147
|
+
| Altcha | `CustomTask` | `altcha` | `altcha` |
|
|
148
|
+
| Friendly Captcha | `CustomTask` | `friendly` | `friendly_captcha` |
|
|
149
|
+
| Temu | `CustomTask` | `Temu` | `temu` |
|
|
150
|
+
| Castle | `CustomTask` | `Castle` | `castle` |
|
|
151
|
+
| TSPD | `CustomTask` | `tspd` | `tspd` |
|
|
152
|
+
| Hunt | `CustomTask` | `HUNT` | `hunt` |
|
|
153
|
+
| Alibaba | `CustomTask` | `alibaba` | `alibaba` |
|
|
154
|
+
|
|
155
|
+
Legacy aliases `NoCaptchaTask`, `NoCaptchaTaskProxyless`, `RecaptchaV2TaskProxyless`, and `HCaptchaTaskProxyless` are accepted on the `type` field. Current docs use `RecaptchaV2Task` with proxy fields omitted when CapMonster's own proxies are enough.
|
|
156
|
+
|
|
157
|
+
TenDI is the Tencent captcha documented by CapMonster. It is not a Tenable product.
|
|
158
|
+
|
|
159
|
+
Parameter reference: <https://docs.capmonster.cloud/docs/captchas/>
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Error Handling
|
|
164
|
+
|
|
165
|
+
When the API returns an error, the client raises `CapMonsterError`:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from capmonster import CapMonster, CapMonsterError
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
with CapMonster("invalid_key") as client:
|
|
172
|
+
client.get_balance()
|
|
173
|
+
except CapMonsterError as err:
|
|
174
|
+
print(f"CapMonster error #{err.error_id} [{err.error_code}]: {err.message}")
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Common error codes (full list: <https://docs.capmonster.cloud/docs/api/api-errors/>):
|
|
178
|
+
|
|
179
|
+
- `ERROR_KEY_DOES_NOT_EXIST` — Account key does not exist or is malformed.
|
|
180
|
+
- `ERROR_ZERO_BALANCE` — Account has no funds. Returned by `create_task`, not by `get_balance`.
|
|
181
|
+
- `ERROR_CAPTCHA_UNSOLVABLE` — The captcha could not be solved. Unsolved tasks are not charged.
|
|
182
|
+
- `CAPTCHA_NOT_READY` — Still solving. `get_task_result` maps this to `status: "processing"`.
|
|
183
|
+
- `ERROR_TASK_NOT_SUPPORTED` / `ERROR_NO_SUCH_METHOD` — Unknown `type`.
|
|
184
|
+
- `ERROR_INVALID_TASK` / `ERROR_TASK_ABSENT` — Task payload is missing or invalid.
|
|
185
|
+
- `ERROR_TOO_MUCH_REQUESTS` — Poll `get_task_result` no more than once every 2 seconds. The default interval is 3 seconds.
|
|
186
|
+
- `TIMEOUT` — `wait_for_result()` exceeded the configured timeout.
|
|
187
|
+
|
|
188
|
+
`CAPMONSTER_ERRORS` maps every documented code to a short description. The API `errorDescription` is used when CapMonster sends one.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Live Tests
|
|
193
|
+
|
|
194
|
+
Unit tests mock HTTP and always run. The live suite calls the real API and runs only when `CAPMONSTER_API_KEY` is set. It checks balance, an invalid key, and `ERROR_ZERO_BALANCE` on `create_task`.
|
|
195
|
+
|
|
196
|
+
`create_task` is sent only when the account balance is exactly `0`. A funded key skips that assertion so the suite does not spend credit.
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
cd capmonster/python
|
|
200
|
+
uv sync
|
|
201
|
+
uv run pytest -m "not live"
|
|
202
|
+
CAPMONSTER_API_KEY=your_key uv run pytest -m live
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Do not commit API keys.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## License
|
|
210
|
+
|
|
211
|
+
[ISC](LICENSE) © api-kit contributors
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# capmonster-client
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/capmonster-client/)
|
|
4
|
+
[](https://pypi.org/project/capmonster-client/)
|
|
5
|
+
[](https://opensource.org/licenses/ISC)
|
|
6
|
+
|
|
7
|
+
Typed Python client for the [CapMonster Cloud API](https://docs.capmonster.cloud). Supports reCAPTCHA v2/v3/Enterprise, Cloudflare Turnstile (including Challenge and Waiting Room), GeeTest, ImageToText, ComplexImage, DataDome, Amazon AWS WAF, TenDI (Tencent), Binance, and the other task types documented by CapMonster Cloud. Built on [HTTPX](https://www.python-httpx.org).
|
|
8
|
+
|
|
9
|
+
Official API documentation: <https://docs.capmonster.cloud>
|
|
10
|
+
|
|
11
|
+
The import package is `capmonster`. The distribution name is `capmonster-client` so it does not collide with other projects on PyPI.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- 🧩 **Documented task types** — Helpers for reCAPTCHA v2/v3/Enterprise, Turnstile, GeeTest, ImageToText, ComplexImage, DataDome, Amazon WAF, TenDI, Binance, FunCaptcha, hCaptcha, Basilisk, Imperva, Prosopo, Yidun, MTCaptcha, Altcha, Friendly Captcha, Temu, Castle, TSPD, Hunt, and Alibaba.
|
|
18
|
+
- ⏳ **Automated polling** — `wait_for_result()` and `solve()` poll until the solution is ready. `CAPTCHA_NOT_READY` stays in the processing state.
|
|
19
|
+
- 💰 **Balance tracking** — `get_balance()` reads the account balance and does not spend credit.
|
|
20
|
+
- 🏷️ **Developer id** — `softId` is omitted until you set it. CapMonster's developer program is still pending, so `DEFAULT_SOFT_ID` is empty.
|
|
21
|
+
- 🐍 **Modern Python** — Type annotations, context manager support (`with CapMonster(...) as client:`).
|
|
22
|
+
- 🚨 **Structured errors** — `CapMonsterError` carries `error_id` and `error_code` for every documented API error.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install capmonster-client
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Requires Python 3.10 or higher.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start (Safe Check)
|
|
37
|
+
|
|
38
|
+
The quick check only inspects your account balance. It does not submit tasks or spend credits.
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import os
|
|
42
|
+
from capmonster import CapMonster
|
|
43
|
+
|
|
44
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
45
|
+
balance = client.get_balance()
|
|
46
|
+
print(f"Balance: {balance['balance']}")
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Usage Guide
|
|
52
|
+
|
|
53
|
+
### 1. High-Level Solve (Recommended)
|
|
54
|
+
|
|
55
|
+
`client.solve()` submits the task and waits until the solution is ready:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import os
|
|
59
|
+
from capmonster import CapMonster, turnstile
|
|
60
|
+
|
|
61
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
62
|
+
solution = client.solve(turnstile("https://example.com/", "0x4AAAAAAA..."))
|
|
63
|
+
print("Turnstile token:", solution["token"])
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Solving reCAPTCHA v2
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from capmonster import CapMonster, recaptcha_v2
|
|
70
|
+
|
|
71
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
72
|
+
solution = client.solve(recaptcha_v2(
|
|
73
|
+
"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high",
|
|
74
|
+
"6Lcg7CMUAAAAANphynKgn9YAgA4tQ2KI_iqRyTwd",
|
|
75
|
+
))
|
|
76
|
+
print(solution["gRecaptchaResponse"])
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 3. Manual Task Lifecycle
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from capmonster import CapMonster, turnstile
|
|
83
|
+
|
|
84
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"]) as client:
|
|
85
|
+
task_id = client.create_task(turnstile("https://example.com/", "0x4AAAAAAA..."))
|
|
86
|
+
result = client.get_task_result(task_id)
|
|
87
|
+
if result["status"] == "ready":
|
|
88
|
+
print("Solution:", result["solution"])
|
|
89
|
+
else:
|
|
90
|
+
print("Task is still processing...")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
You can also pass a raw `dict`. `type` is required. Custom captchas (DataDome, TenDI, and the others listed below) also require `class`.
|
|
94
|
+
|
|
95
|
+
### 4. Developer software id
|
|
96
|
+
|
|
97
|
+
`create_task` sends `softId` only when it is set:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from capmonster import DEFAULT_SOFT_ID, CapMonster
|
|
101
|
+
|
|
102
|
+
print(DEFAULT_SOFT_ID) # ""
|
|
103
|
+
|
|
104
|
+
with CapMonster(os.environ["CAPMONSTER_API_KEY"], soft_id=12345) as client:
|
|
105
|
+
...
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
TODO: replace `DEFAULT_SOFT_ID` in `src/capmonster/client.py` once CapMonster assigns a numeric id.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Task Types
|
|
113
|
+
|
|
114
|
+
| Captcha | `type` | `class` | Helper |
|
|
115
|
+
| :--- | :--- | :--- | :--- |
|
|
116
|
+
| reCAPTCHA v2 | `RecaptchaV2Task` | | `recaptcha_v2` |
|
|
117
|
+
| reCAPTCHA v2 Enterprise | `RecaptchaV2EnterpriseTask` | | `recaptcha_v2_enterprise` |
|
|
118
|
+
| reCAPTCHA v3 | `RecaptchaV3TaskProxyless` | | `recaptcha_v3` |
|
|
119
|
+
| reCAPTCHA v3 Enterprise | `RecaptchaV3EnterpriseTask` | | `recaptcha_v3_enterprise` |
|
|
120
|
+
| Cloudflare Turnstile / Challenge / Waiting Room | `TurnstileTask` | | `turnstile` |
|
|
121
|
+
| GeeTest v3 / v4 | `GeeTestTask` | | `geetest` |
|
|
122
|
+
| ImageToText | `ImageToTextTask` | | `image_to_text` |
|
|
123
|
+
| ComplexImage (click, grid, recognition) | `ComplexImageTask` | `recaptcha`, `hcaptcha`, `funcaptcha`, `recognition` | `complex_image` |
|
|
124
|
+
| DataDome | `CustomTask` | `DataDome` | `datadome` |
|
|
125
|
+
| TenDI (Tencent) | `CustomTask` | `TenDI` | `tendi` |
|
|
126
|
+
| Amazon AWS WAF | `AmazonTask` | | `amazon` |
|
|
127
|
+
| Binance | `BinanceTask` | | `binance` |
|
|
128
|
+
| FunCaptcha | `FunCaptchaTask` | | `funcaptcha` |
|
|
129
|
+
| hCaptcha | `HCaptchaTask` | | `hcaptcha` |
|
|
130
|
+
| Basilisk | `CustomTask` | `Basilisk` | `basilisk` |
|
|
131
|
+
| Imperva (Incapsula) | `CustomTask` | `Imperva` | `imperva` |
|
|
132
|
+
| Prosopo | `ProsopoTask` | | `prosopo` |
|
|
133
|
+
| Yidun | `YidunTask` | | `yidun` |
|
|
134
|
+
| MTCaptcha | `MTCaptchaTask` | | `mtcaptcha` |
|
|
135
|
+
| Altcha | `CustomTask` | `altcha` | `altcha` |
|
|
136
|
+
| Friendly Captcha | `CustomTask` | `friendly` | `friendly_captcha` |
|
|
137
|
+
| Temu | `CustomTask` | `Temu` | `temu` |
|
|
138
|
+
| Castle | `CustomTask` | `Castle` | `castle` |
|
|
139
|
+
| TSPD | `CustomTask` | `tspd` | `tspd` |
|
|
140
|
+
| Hunt | `CustomTask` | `HUNT` | `hunt` |
|
|
141
|
+
| Alibaba | `CustomTask` | `alibaba` | `alibaba` |
|
|
142
|
+
|
|
143
|
+
Legacy aliases `NoCaptchaTask`, `NoCaptchaTaskProxyless`, `RecaptchaV2TaskProxyless`, and `HCaptchaTaskProxyless` are accepted on the `type` field. Current docs use `RecaptchaV2Task` with proxy fields omitted when CapMonster's own proxies are enough.
|
|
144
|
+
|
|
145
|
+
TenDI is the Tencent captcha documented by CapMonster. It is not a Tenable product.
|
|
146
|
+
|
|
147
|
+
Parameter reference: <https://docs.capmonster.cloud/docs/captchas/>
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Error Handling
|
|
152
|
+
|
|
153
|
+
When the API returns an error, the client raises `CapMonsterError`:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from capmonster import CapMonster, CapMonsterError
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
with CapMonster("invalid_key") as client:
|
|
160
|
+
client.get_balance()
|
|
161
|
+
except CapMonsterError as err:
|
|
162
|
+
print(f"CapMonster error #{err.error_id} [{err.error_code}]: {err.message}")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Common error codes (full list: <https://docs.capmonster.cloud/docs/api/api-errors/>):
|
|
166
|
+
|
|
167
|
+
- `ERROR_KEY_DOES_NOT_EXIST` — Account key does not exist or is malformed.
|
|
168
|
+
- `ERROR_ZERO_BALANCE` — Account has no funds. Returned by `create_task`, not by `get_balance`.
|
|
169
|
+
- `ERROR_CAPTCHA_UNSOLVABLE` — The captcha could not be solved. Unsolved tasks are not charged.
|
|
170
|
+
- `CAPTCHA_NOT_READY` — Still solving. `get_task_result` maps this to `status: "processing"`.
|
|
171
|
+
- `ERROR_TASK_NOT_SUPPORTED` / `ERROR_NO_SUCH_METHOD` — Unknown `type`.
|
|
172
|
+
- `ERROR_INVALID_TASK` / `ERROR_TASK_ABSENT` — Task payload is missing or invalid.
|
|
173
|
+
- `ERROR_TOO_MUCH_REQUESTS` — Poll `get_task_result` no more than once every 2 seconds. The default interval is 3 seconds.
|
|
174
|
+
- `TIMEOUT` — `wait_for_result()` exceeded the configured timeout.
|
|
175
|
+
|
|
176
|
+
`CAPMONSTER_ERRORS` maps every documented code to a short description. The API `errorDescription` is used when CapMonster sends one.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Live Tests
|
|
181
|
+
|
|
182
|
+
Unit tests mock HTTP and always run. The live suite calls the real API and runs only when `CAPMONSTER_API_KEY` is set. It checks balance, an invalid key, and `ERROR_ZERO_BALANCE` on `create_task`.
|
|
183
|
+
|
|
184
|
+
`create_task` is sent only when the account balance is exactly `0`. A funded key skips that assertion so the suite does not spend credit.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
cd capmonster/python
|
|
188
|
+
uv sync
|
|
189
|
+
uv run pytest -m "not live"
|
|
190
|
+
CAPMONSTER_API_KEY=your_key uv run pytest -m live
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Do not commit API keys.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
[ISC](LICENSE) © api-kit contributors
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Safe verification script: checks account balance without submitting tasks."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from capmonster import CapMonster
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
client_key = os.environ.get("CAPMONSTER_API_KEY")
|
|
10
|
+
if not client_key:
|
|
11
|
+
raise SystemExit("Please set CAPMONSTER_API_KEY environment variable")
|
|
12
|
+
|
|
13
|
+
with CapMonster(client_key) as client:
|
|
14
|
+
balance = client.get_balance()
|
|
15
|
+
print(f"Account balance: {balance}")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
if __name__ == "__main__":
|
|
19
|
+
main()
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "capmonster-client"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python client for the CapMonster Cloud captcha recognition API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "ISC"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"httpx>=0.27",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Repository = "https://github.com/TysikGG/api-kit"
|
|
18
|
+
Documentation = "https://docs.capmonster.cloud"
|
|
19
|
+
|
|
20
|
+
[dependency-groups]
|
|
21
|
+
dev = [
|
|
22
|
+
"pytest>=8",
|
|
23
|
+
"pytest-httpx>=0.30",
|
|
24
|
+
"ruff>=0.8",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[tool.hatch.build.targets.wheel]
|
|
28
|
+
packages = ["src/capmonster"]
|
|
29
|
+
|
|
30
|
+
[tool.pytest.ini_options]
|
|
31
|
+
markers = [
|
|
32
|
+
"live: calls the real CapMonster Cloud API and needs CAPMONSTER_API_KEY",
|
|
33
|
+
]
|
|
34
|
+
testpaths = ["tests"]
|
|
35
|
+
|
|
36
|
+
[tool.ruff]
|
|
37
|
+
target-version = "py310"
|
|
38
|
+
line-length = 100
|
|
39
|
+
src = ["src", "tests", "examples"]
|
|
40
|
+
|
|
41
|
+
[tool.ruff.lint]
|
|
42
|
+
select = ["E", "F", "I", "UP"]
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""CapMonster Cloud recognition API client."""
|
|
2
|
+
|
|
3
|
+
from .client import DEFAULT_SOFT_ID, CapMonster
|
|
4
|
+
from .errors import CAPMONSTER_ERRORS, CapMonsterError
|
|
5
|
+
from .tasks import (
|
|
6
|
+
alibaba,
|
|
7
|
+
altcha,
|
|
8
|
+
amazon,
|
|
9
|
+
basilisk,
|
|
10
|
+
binance,
|
|
11
|
+
castle,
|
|
12
|
+
complex_image,
|
|
13
|
+
datadome,
|
|
14
|
+
friendly_captcha,
|
|
15
|
+
funcaptcha,
|
|
16
|
+
geetest,
|
|
17
|
+
hcaptcha,
|
|
18
|
+
hunt,
|
|
19
|
+
image_to_text,
|
|
20
|
+
imperva,
|
|
21
|
+
mtcaptcha,
|
|
22
|
+
prosopo,
|
|
23
|
+
recaptcha_v2,
|
|
24
|
+
recaptcha_v2_enterprise,
|
|
25
|
+
recaptcha_v3,
|
|
26
|
+
recaptcha_v3_enterprise,
|
|
27
|
+
temu,
|
|
28
|
+
tendi,
|
|
29
|
+
tspd,
|
|
30
|
+
turnstile,
|
|
31
|
+
yidun,
|
|
32
|
+
)
|
|
33
|
+
from .types import (
|
|
34
|
+
TASK_CLASSES,
|
|
35
|
+
TASK_TYPES,
|
|
36
|
+
CapMonsterBalance,
|
|
37
|
+
RawApiResponse,
|
|
38
|
+
TaskResult,
|
|
39
|
+
TaskStatus,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
__all__ = [
|
|
43
|
+
"CAPMONSTER_ERRORS",
|
|
44
|
+
"DEFAULT_SOFT_ID",
|
|
45
|
+
"TASK_CLASSES",
|
|
46
|
+
"TASK_TYPES",
|
|
47
|
+
"CapMonster",
|
|
48
|
+
"CapMonsterBalance",
|
|
49
|
+
"CapMonsterError",
|
|
50
|
+
"RawApiResponse",
|
|
51
|
+
"TaskResult",
|
|
52
|
+
"TaskStatus",
|
|
53
|
+
"alibaba",
|
|
54
|
+
"altcha",
|
|
55
|
+
"amazon",
|
|
56
|
+
"basilisk",
|
|
57
|
+
"binance",
|
|
58
|
+
"castle",
|
|
59
|
+
"complex_image",
|
|
60
|
+
"datadome",
|
|
61
|
+
"friendly_captcha",
|
|
62
|
+
"funcaptcha",
|
|
63
|
+
"geetest",
|
|
64
|
+
"hcaptcha",
|
|
65
|
+
"hunt",
|
|
66
|
+
"image_to_text",
|
|
67
|
+
"imperva",
|
|
68
|
+
"mtcaptcha",
|
|
69
|
+
"prosopo",
|
|
70
|
+
"recaptcha_v2",
|
|
71
|
+
"recaptcha_v2_enterprise",
|
|
72
|
+
"recaptcha_v3",
|
|
73
|
+
"recaptcha_v3_enterprise",
|
|
74
|
+
"temu",
|
|
75
|
+
"tendi",
|
|
76
|
+
"tspd",
|
|
77
|
+
"turnstile",
|
|
78
|
+
"yidun",
|
|
79
|
+
]
|