solvecaptcha 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.
- solvecaptcha-0.1.0/.gitignore +46 -0
- solvecaptcha-0.1.0/LICENSE +15 -0
- solvecaptcha-0.1.0/PKG-INFO +227 -0
- solvecaptcha-0.1.0/README.md +215 -0
- solvecaptcha-0.1.0/examples/quickstart.py +21 -0
- solvecaptcha-0.1.0/pyproject.toml +42 -0
- solvecaptcha-0.1.0/src/solvecaptcha/__init__.py +13 -0
- solvecaptcha-0.1.0/src/solvecaptcha/client.py +510 -0
- solvecaptcha-0.1.0/src/solvecaptcha/errors.py +33 -0
- solvecaptcha-0.1.0/src/solvecaptcha/types.py +20 -0
- solvecaptcha-0.1.0/tests/test_client.py +118 -0
- solvecaptcha-0.1.0/tests/test_live.py +19 -0
- solvecaptcha-0.1.0/uv.lock +295 -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,227 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: solvecaptcha
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the SolveCaptcha human and AI captcha solving API
|
|
5
|
+
Project-URL: Repository, https://github.com/TysikGG/api-kit
|
|
6
|
+
Project-URL: Documentation, https://solvecaptcha.com/captcha-solver-api
|
|
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
|
+
# solvecaptcha
|
|
14
|
+
|
|
15
|
+
[](https://pypi.org/project/solvecaptcha/)
|
|
16
|
+
[](LICENSE)
|
|
17
|
+
[](https://pypi.org/project/solvecaptcha/)
|
|
18
|
+
|
|
19
|
+
Modern, fully typed Python client library for the [SolveCaptcha](https://solvecaptcha.com/captcha-solver-api) recognition API.
|
|
20
|
+
|
|
21
|
+
Official API documentation: <https://solvecaptcha.com/captcha-solver-api>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
- ⚡ **Multi-Captcha Support** — Cloudflare Turnstile, Google reCAPTCHA v2 / v3, Arkose FunCaptcha, GeeTest v3, normal image captchas, and text questions.
|
|
28
|
+
- 🔄 **Built-in Auto Polling** — High-level methods like `solve_turnstile()` and `solve_recaptcha_v2()` automatically poll until resolved.
|
|
29
|
+
- 🐍 **Modern Pythonic Design** — Type annotations, dataclasses, context manager support (`with SolveCaptchaClient(...) as client:`), and custom exceptions.
|
|
30
|
+
- 🛠️ **Asynchronous Task Queue** — Low-level `create_task()` and `get_task_result()` for custom background queue workers.
|
|
31
|
+
- ⚖️ **Accuracy Reports** — `report_good()` and `report_bad()` for solving quality feedback and automated credit refunds.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install solvecaptcha
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Requires Python 3.10 or higher.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Quick Start (Safe Check)
|
|
46
|
+
|
|
47
|
+
The quick check only queries your account balance. It does not create tasks or consume credits.
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
import os
|
|
51
|
+
from solvecaptcha import SolveCaptchaClient
|
|
52
|
+
|
|
53
|
+
client = SolveCaptchaClient(api_key=os.environ["SOLVECAPTCHA_API_KEY"])
|
|
54
|
+
|
|
55
|
+
balance = client.get_balance()
|
|
56
|
+
print(f"Current SolveCaptcha balance: ${balance:.4f} USD")
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Usage Guide
|
|
62
|
+
|
|
63
|
+
### 1. Solving Cloudflare Turnstile
|
|
64
|
+
|
|
65
|
+
Solve Cloudflare Turnstile challenges and retrieve the verification token:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from solvecaptcha import SolveCaptchaClient
|
|
69
|
+
|
|
70
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
71
|
+
token = client.solve_turnstile(
|
|
72
|
+
sitekey="0x4AAAAAAADnPIDROrmt1Wwj",
|
|
73
|
+
pageurl="https://example.com/protected",
|
|
74
|
+
action="login", # optional
|
|
75
|
+
)
|
|
76
|
+
print("Turnstile token:", token)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 2. Solving Google reCAPTCHA v2 & v3
|
|
80
|
+
|
|
81
|
+
Solve checkbox or invisible reCAPTCHA v2, or score-based reCAPTCHA v3:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
85
|
+
# reCAPTCHA v2
|
|
86
|
+
token_v2 = client.solve_recaptcha_v2(
|
|
87
|
+
googlekey="6Le-wvkSAAAAAPBMRTvw0Q4CeHg-tUnSQVwyYcxQ",
|
|
88
|
+
pageurl="https://example.com/protected",
|
|
89
|
+
invisible=0,
|
|
90
|
+
)
|
|
91
|
+
print("reCAPTCHA v2 token:", token_v2)
|
|
92
|
+
|
|
93
|
+
# reCAPTCHA v3
|
|
94
|
+
token_v3 = client.solve_recaptcha_v3(
|
|
95
|
+
googlekey="6LdyC2cUAAAAABlzY2Hg-tUnSQVwyYcxQ",
|
|
96
|
+
pageurl="https://example.com/checkout",
|
|
97
|
+
action="checkout",
|
|
98
|
+
min_score=0.7,
|
|
99
|
+
)
|
|
100
|
+
print("reCAPTCHA v3 token:", token_v3)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Solving Normal Image CAPTCHA
|
|
104
|
+
|
|
105
|
+
Solve distorted image captchas by passing a base64-encoded string:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import base64
|
|
109
|
+
from solvecaptcha import SolveCaptchaClient
|
|
110
|
+
|
|
111
|
+
with open("captcha.png", "rb") as f:
|
|
112
|
+
b64_image = base64.b64encode(f.read()).decode("utf-8")
|
|
113
|
+
|
|
114
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
115
|
+
solution_text = client.solve_image(
|
|
116
|
+
body=b64_image,
|
|
117
|
+
numeric=1, # numbers only
|
|
118
|
+
min_len=4,
|
|
119
|
+
max_len=6,
|
|
120
|
+
)
|
|
121
|
+
print("Solved captcha text:", solution_text)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 4. Low-Level Task Flow
|
|
125
|
+
|
|
126
|
+
For asynchronous background tasks or task queues:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
import time
|
|
130
|
+
from solvecaptcha import SolveCaptchaClient
|
|
131
|
+
|
|
132
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
133
|
+
# 1. Create task
|
|
134
|
+
task_id = client.create_task({
|
|
135
|
+
"method": "turnstile",
|
|
136
|
+
"sitekey": "0x4AAAAAAADnPIDROrmt1Wwj",
|
|
137
|
+
"pageurl": "https://example.com",
|
|
138
|
+
})
|
|
139
|
+
print(f"Task submitted: {task_id}")
|
|
140
|
+
|
|
141
|
+
# 2. Poll manually or wait
|
|
142
|
+
token = None
|
|
143
|
+
for _ in range(30):
|
|
144
|
+
time.sleep(5)
|
|
145
|
+
token = client.get_task_result(task_id)
|
|
146
|
+
if token:
|
|
147
|
+
break
|
|
148
|
+
|
|
149
|
+
if token:
|
|
150
|
+
print("Solved:", token)
|
|
151
|
+
client.report_good(task_id)
|
|
152
|
+
else:
|
|
153
|
+
print("Failed to resolve in time.")
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## API Reference
|
|
159
|
+
|
|
160
|
+
### `SolveCaptchaClient`
|
|
161
|
+
|
|
162
|
+
#### Constructor
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
SolveCaptchaClient(
|
|
166
|
+
api_key: str,
|
|
167
|
+
base_url: str = "https://solvecaptcha.com",
|
|
168
|
+
timeout: float = 30.0,
|
|
169
|
+
default_polling_timeout: float = 120.0,
|
|
170
|
+
default_polling_interval: float = 5.0,
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
| Parameter | Type | Default | Description |
|
|
175
|
+
| :--- | :--- | :--- | :--- |
|
|
176
|
+
| `api_key` | `str` | **Required** | Your SolveCaptcha API key. |
|
|
177
|
+
| `base_url` | `str` | `"https://solvecaptcha.com"` | Custom API base URL. |
|
|
178
|
+
| `timeout` | `float` | `30.0` | HTTP request timeout in seconds. |
|
|
179
|
+
| `default_polling_timeout` | `float` | `120.0` | Max seconds to wait for resolution. |
|
|
180
|
+
| `default_polling_interval` | `float` | `5.0` | Seconds between status checks. |
|
|
181
|
+
|
|
182
|
+
#### Methods
|
|
183
|
+
|
|
184
|
+
- **`get_balance() -> float`** — Returns current balance in USD.
|
|
185
|
+
- **`solve_turnstile(sitekey, pageurl, action=None, data=None) -> str`** — Solves Cloudflare Turnstile.
|
|
186
|
+
- **`solve_recaptcha_v2(googlekey, pageurl, invisible=0, data_s=None, enterprise=0) -> str`** — Solves reCAPTCHA v2.
|
|
187
|
+
- **`solve_recaptcha_v3(googlekey, pageurl, action=None, min_score=None) -> str`** — Solves reCAPTCHA v3.
|
|
188
|
+
- **`solve_funcaptcha(publickey, pageurl, surl=None, data=None) -> str`** — Solves Arkose FunCaptcha.
|
|
189
|
+
- **`solve_geetest(gt, challenge, pageurl, api_server=None) -> GeeTestResult`** — Solves GeeTest v3.
|
|
190
|
+
- **`solve_image(body, phrase=0, regsense=0, numeric=0, calc=0, min_len=None, max_len=None, language=None, textinstructions=None) -> str`** — Solves base64 image.
|
|
191
|
+
- **`solve_text(text, language=None) -> str`** — Solves text question captcha.
|
|
192
|
+
- **`create_task(params: dict) -> str`** — Sends raw task payload to `/in.php` and returns task ID.
|
|
193
|
+
- **`get_task_result(task_id: str) -> str | None`** — Checks task status, returns token or `None` if not ready.
|
|
194
|
+
- **`wait_for_result(task_id: str, timeout_sec=None, interval_sec=None) -> str`** — Polls until solved.
|
|
195
|
+
- **`report_good(task_id: str) -> bool`** — Marks solution as correct.
|
|
196
|
+
- **`report_bad(task_id: str) -> bool`** — Marks solution as incorrect to receive a credit refund.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Error Handling
|
|
201
|
+
|
|
202
|
+
When an API error occurs, `SolveCaptchaError` is raised:
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
from solvecaptcha import SolveCaptchaClient, SolveCaptchaError
|
|
206
|
+
|
|
207
|
+
try:
|
|
208
|
+
with SolveCaptchaClient(api_key="invalid_key") as client:
|
|
209
|
+
client.get_balance()
|
|
210
|
+
except SolveCaptchaError as exc:
|
|
211
|
+
print(f"Error Code: {exc.code}")
|
|
212
|
+
print(f"Message: {exc.message}")
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Common error codes:
|
|
216
|
+
- `ERROR_WRONG_USER_KEY` — Provided API key is incorrect.
|
|
217
|
+
- `ERROR_KEY_DOES_NOT_EXIST` — Invalid API key.
|
|
218
|
+
- `ERROR_ZERO_BALANCE` — Insufficient funds on account.
|
|
219
|
+
- `ERROR_NO_SLOT_AVAILABLE` — Solving queue currently congested.
|
|
220
|
+
- `CAPCHA_NOT_READY` — Resolution in progress.
|
|
221
|
+
- `TIMEOUT` — Maximum polling wait duration exceeded.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
ISC
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# solvecaptcha
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/solvecaptcha/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://pypi.org/project/solvecaptcha/)
|
|
6
|
+
|
|
7
|
+
Modern, fully typed Python client library for the [SolveCaptcha](https://solvecaptcha.com/captcha-solver-api) recognition API.
|
|
8
|
+
|
|
9
|
+
Official API documentation: <https://solvecaptcha.com/captcha-solver-api>
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- ⚡ **Multi-Captcha Support** — Cloudflare Turnstile, Google reCAPTCHA v2 / v3, Arkose FunCaptcha, GeeTest v3, normal image captchas, and text questions.
|
|
16
|
+
- 🔄 **Built-in Auto Polling** — High-level methods like `solve_turnstile()` and `solve_recaptcha_v2()` automatically poll until resolved.
|
|
17
|
+
- 🐍 **Modern Pythonic Design** — Type annotations, dataclasses, context manager support (`with SolveCaptchaClient(...) as client:`), and custom exceptions.
|
|
18
|
+
- 🛠️ **Asynchronous Task Queue** — Low-level `create_task()` and `get_task_result()` for custom background queue workers.
|
|
19
|
+
- ⚖️ **Accuracy Reports** — `report_good()` and `report_bad()` for solving quality feedback and automated credit refunds.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install solvecaptcha
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Requires Python 3.10 or higher.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick Start (Safe Check)
|
|
34
|
+
|
|
35
|
+
The quick check only queries your account balance. It does not create tasks or consume credits.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import os
|
|
39
|
+
from solvecaptcha import SolveCaptchaClient
|
|
40
|
+
|
|
41
|
+
client = SolveCaptchaClient(api_key=os.environ["SOLVECAPTCHA_API_KEY"])
|
|
42
|
+
|
|
43
|
+
balance = client.get_balance()
|
|
44
|
+
print(f"Current SolveCaptcha balance: ${balance:.4f} USD")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Usage Guide
|
|
50
|
+
|
|
51
|
+
### 1. Solving Cloudflare Turnstile
|
|
52
|
+
|
|
53
|
+
Solve Cloudflare Turnstile challenges and retrieve the verification token:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from solvecaptcha import SolveCaptchaClient
|
|
57
|
+
|
|
58
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
59
|
+
token = client.solve_turnstile(
|
|
60
|
+
sitekey="0x4AAAAAAADnPIDROrmt1Wwj",
|
|
61
|
+
pageurl="https://example.com/protected",
|
|
62
|
+
action="login", # optional
|
|
63
|
+
)
|
|
64
|
+
print("Turnstile token:", token)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 2. Solving Google reCAPTCHA v2 & v3
|
|
68
|
+
|
|
69
|
+
Solve checkbox or invisible reCAPTCHA v2, or score-based reCAPTCHA v3:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
73
|
+
# reCAPTCHA v2
|
|
74
|
+
token_v2 = client.solve_recaptcha_v2(
|
|
75
|
+
googlekey="6Le-wvkSAAAAAPBMRTvw0Q4CeHg-tUnSQVwyYcxQ",
|
|
76
|
+
pageurl="https://example.com/protected",
|
|
77
|
+
invisible=0,
|
|
78
|
+
)
|
|
79
|
+
print("reCAPTCHA v2 token:", token_v2)
|
|
80
|
+
|
|
81
|
+
# reCAPTCHA v3
|
|
82
|
+
token_v3 = client.solve_recaptcha_v3(
|
|
83
|
+
googlekey="6LdyC2cUAAAAABlzY2Hg-tUnSQVwyYcxQ",
|
|
84
|
+
pageurl="https://example.com/checkout",
|
|
85
|
+
action="checkout",
|
|
86
|
+
min_score=0.7,
|
|
87
|
+
)
|
|
88
|
+
print("reCAPTCHA v3 token:", token_v3)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. Solving Normal Image CAPTCHA
|
|
92
|
+
|
|
93
|
+
Solve distorted image captchas by passing a base64-encoded string:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
import base64
|
|
97
|
+
from solvecaptcha import SolveCaptchaClient
|
|
98
|
+
|
|
99
|
+
with open("captcha.png", "rb") as f:
|
|
100
|
+
b64_image = base64.b64encode(f.read()).decode("utf-8")
|
|
101
|
+
|
|
102
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
103
|
+
solution_text = client.solve_image(
|
|
104
|
+
body=b64_image,
|
|
105
|
+
numeric=1, # numbers only
|
|
106
|
+
min_len=4,
|
|
107
|
+
max_len=6,
|
|
108
|
+
)
|
|
109
|
+
print("Solved captcha text:", solution_text)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 4. Low-Level Task Flow
|
|
113
|
+
|
|
114
|
+
For asynchronous background tasks or task queues:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
import time
|
|
118
|
+
from solvecaptcha import SolveCaptchaClient
|
|
119
|
+
|
|
120
|
+
with SolveCaptchaClient(api_key="your_api_key") as client:
|
|
121
|
+
# 1. Create task
|
|
122
|
+
task_id = client.create_task({
|
|
123
|
+
"method": "turnstile",
|
|
124
|
+
"sitekey": "0x4AAAAAAADnPIDROrmt1Wwj",
|
|
125
|
+
"pageurl": "https://example.com",
|
|
126
|
+
})
|
|
127
|
+
print(f"Task submitted: {task_id}")
|
|
128
|
+
|
|
129
|
+
# 2. Poll manually or wait
|
|
130
|
+
token = None
|
|
131
|
+
for _ in range(30):
|
|
132
|
+
time.sleep(5)
|
|
133
|
+
token = client.get_task_result(task_id)
|
|
134
|
+
if token:
|
|
135
|
+
break
|
|
136
|
+
|
|
137
|
+
if token:
|
|
138
|
+
print("Solved:", token)
|
|
139
|
+
client.report_good(task_id)
|
|
140
|
+
else:
|
|
141
|
+
print("Failed to resolve in time.")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## API Reference
|
|
147
|
+
|
|
148
|
+
### `SolveCaptchaClient`
|
|
149
|
+
|
|
150
|
+
#### Constructor
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
SolveCaptchaClient(
|
|
154
|
+
api_key: str,
|
|
155
|
+
base_url: str = "https://solvecaptcha.com",
|
|
156
|
+
timeout: float = 30.0,
|
|
157
|
+
default_polling_timeout: float = 120.0,
|
|
158
|
+
default_polling_interval: float = 5.0,
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| Parameter | Type | Default | Description |
|
|
163
|
+
| :--- | :--- | :--- | :--- |
|
|
164
|
+
| `api_key` | `str` | **Required** | Your SolveCaptcha API key. |
|
|
165
|
+
| `base_url` | `str` | `"https://solvecaptcha.com"` | Custom API base URL. |
|
|
166
|
+
| `timeout` | `float` | `30.0` | HTTP request timeout in seconds. |
|
|
167
|
+
| `default_polling_timeout` | `float` | `120.0` | Max seconds to wait for resolution. |
|
|
168
|
+
| `default_polling_interval` | `float` | `5.0` | Seconds between status checks. |
|
|
169
|
+
|
|
170
|
+
#### Methods
|
|
171
|
+
|
|
172
|
+
- **`get_balance() -> float`** — Returns current balance in USD.
|
|
173
|
+
- **`solve_turnstile(sitekey, pageurl, action=None, data=None) -> str`** — Solves Cloudflare Turnstile.
|
|
174
|
+
- **`solve_recaptcha_v2(googlekey, pageurl, invisible=0, data_s=None, enterprise=0) -> str`** — Solves reCAPTCHA v2.
|
|
175
|
+
- **`solve_recaptcha_v3(googlekey, pageurl, action=None, min_score=None) -> str`** — Solves reCAPTCHA v3.
|
|
176
|
+
- **`solve_funcaptcha(publickey, pageurl, surl=None, data=None) -> str`** — Solves Arkose FunCaptcha.
|
|
177
|
+
- **`solve_geetest(gt, challenge, pageurl, api_server=None) -> GeeTestResult`** — Solves GeeTest v3.
|
|
178
|
+
- **`solve_image(body, phrase=0, regsense=0, numeric=0, calc=0, min_len=None, max_len=None, language=None, textinstructions=None) -> str`** — Solves base64 image.
|
|
179
|
+
- **`solve_text(text, language=None) -> str`** — Solves text question captcha.
|
|
180
|
+
- **`create_task(params: dict) -> str`** — Sends raw task payload to `/in.php` and returns task ID.
|
|
181
|
+
- **`get_task_result(task_id: str) -> str | None`** — Checks task status, returns token or `None` if not ready.
|
|
182
|
+
- **`wait_for_result(task_id: str, timeout_sec=None, interval_sec=None) -> str`** — Polls until solved.
|
|
183
|
+
- **`report_good(task_id: str) -> bool`** — Marks solution as correct.
|
|
184
|
+
- **`report_bad(task_id: str) -> bool`** — Marks solution as incorrect to receive a credit refund.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Error Handling
|
|
189
|
+
|
|
190
|
+
When an API error occurs, `SolveCaptchaError` is raised:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
from solvecaptcha import SolveCaptchaClient, SolveCaptchaError
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
with SolveCaptchaClient(api_key="invalid_key") as client:
|
|
197
|
+
client.get_balance()
|
|
198
|
+
except SolveCaptchaError as exc:
|
|
199
|
+
print(f"Error Code: {exc.code}")
|
|
200
|
+
print(f"Message: {exc.message}")
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Common error codes:
|
|
204
|
+
- `ERROR_WRONG_USER_KEY` — Provided API key is incorrect.
|
|
205
|
+
- `ERROR_KEY_DOES_NOT_EXIST` — Invalid API key.
|
|
206
|
+
- `ERROR_ZERO_BALANCE` — Insufficient funds on account.
|
|
207
|
+
- `ERROR_NO_SLOT_AVAILABLE` — Solving queue currently congested.
|
|
208
|
+
- `CAPCHA_NOT_READY` — Resolution in progress.
|
|
209
|
+
- `TIMEOUT` — Maximum polling wait duration exceeded.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
ISC
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Quickstart example for the SolveCaptcha Python client."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from solvecaptcha import SolveCaptchaClient
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main() -> None:
|
|
10
|
+
api_key = os.environ.get("SOLVECAPTCHA_API_KEY")
|
|
11
|
+
if not api_key:
|
|
12
|
+
print("Please set the SOLVECAPTCHA_API_KEY environment variable", file=sys.stderr)
|
|
13
|
+
sys.exit(1)
|
|
14
|
+
|
|
15
|
+
with SolveCaptchaClient(api_key=api_key) as client:
|
|
16
|
+
balance = client.get_balance()
|
|
17
|
+
print(f"SolveCaptcha Balance: ${balance:.4f}")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if __name__ == "__main__":
|
|
21
|
+
main()
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "solvecaptcha"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python client for the SolveCaptcha human and AI captcha solving 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://solvecaptcha.com/captcha-solver-api"
|
|
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/solvecaptcha"]
|
|
29
|
+
|
|
30
|
+
[tool.pytest.ini_options]
|
|
31
|
+
markers = [
|
|
32
|
+
"live: calls the real SolveCaptcha API and needs SOLVECAPTCHA_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,13 @@
|
|
|
1
|
+
"""SolveCaptcha Python Client."""
|
|
2
|
+
|
|
3
|
+
from .client import DEFAULT_SOFT_ID, SolveCaptchaClient
|
|
4
|
+
from .errors import SolveCaptchaError
|
|
5
|
+
from .types import CaptchaTask, GeeTestResult
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"DEFAULT_SOFT_ID",
|
|
9
|
+
"CaptchaTask",
|
|
10
|
+
"GeeTestResult",
|
|
11
|
+
"SolveCaptchaClient",
|
|
12
|
+
"SolveCaptchaError",
|
|
13
|
+
]
|