captcha-solver-api 1.0.3__tar.gz → 1.0.4__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.
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/PKG-INFO +27 -1
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/README.md +26 -0
- captcha_solver_api-1.0.4/captcha_solver_api/_version.py +1 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/async_client.py +65 -14
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/client.py +58 -11
- captcha_solver_api-1.0.4/captcha_solver_api/exceptions.py +61 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/tasks.py +216 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/PKG-INFO +27 -1
- captcha_solver_api-1.0.3/captcha_solver_api/_version.py +0 -1
- captcha_solver_api-1.0.3/captcha_solver_api/exceptions.py +0 -33
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/LICENSE.md +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/__init__.py +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/py.typed +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/SOURCES.txt +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/dependency_links.txt +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/requires.txt +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/top_level.txt +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/pyproject.toml +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/setup.cfg +0 -0
- {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/tests/test_polling.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: captcha-solver-api
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Official Python SDK for solving reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest v3/v4, Yandex SmartCaptcha, Tencent, and image/click captchas via the Captcha Solver API
|
|
5
5
|
Author: Captcha Solver Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -61,6 +61,7 @@ Full API reference (all endpoints, error codes, captcha-type details): **https:/
|
|
|
61
61
|
## Table of Contents
|
|
62
62
|
|
|
63
63
|
- [Installation](#installation)
|
|
64
|
+
- [Editor documentation](#editor-documentation)
|
|
64
65
|
- [Configuration](#configuration)
|
|
65
66
|
- [Quick Start](#quick-start)
|
|
66
67
|
- [Build Faster with AI](#build-faster-with-ai)
|
|
@@ -106,6 +107,31 @@ Or install the latest version from GitHub:
|
|
|
106
107
|
pip install git+https://github.com/captcha-solver-api/python-sdk.git
|
|
107
108
|
```
|
|
108
109
|
|
|
110
|
+
## Editor documentation
|
|
111
|
+
|
|
112
|
+
The SDK includes Python docstrings (the equivalent of JSDoc), type annotations,
|
|
113
|
+
and a `py.typed` marker in the installed package. With Python language support
|
|
114
|
+
enabled in your editor, hover over `CaptchaClient`, `AsyncCaptchaClient`, their
|
|
115
|
+
methods, or a task class such as `RecaptchaV2TaskProxyless` to read the documentation.
|
|
116
|
+
Signature help shows argument names, types, and defaults while you type a call.
|
|
117
|
+
|
|
118
|
+
Docstrings describe parameters, solution fields, exceptions, and usage examples.
|
|
119
|
+
Task examples assume an existing synchronous `client`; with `AsyncCaptchaClient`,
|
|
120
|
+
use `solution = await client.solve(task)` instead. Async snippets run inside an
|
|
121
|
+
`async def` function. In VS Code, select the Python interpreter where the SDK is
|
|
122
|
+
installed and enable the Python and Pylance extensions. In PyCharm, use Quick
|
|
123
|
+
Documentation. The exact presentation depends on the editor.
|
|
124
|
+
|
|
125
|
+
You can also read the same documentation without an editor:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from captcha_solver_api import CaptchaClient
|
|
129
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
130
|
+
|
|
131
|
+
help(CaptchaClient.solve)
|
|
132
|
+
help(RecaptchaV2TaskProxyless)
|
|
133
|
+
```
|
|
134
|
+
|
|
109
135
|
## Configuration
|
|
110
136
|
|
|
111
137
|
The client always takes the API key as an explicit argument -- it does not read
|
|
@@ -21,6 +21,7 @@ Full API reference (all endpoints, error codes, captcha-type details): **https:/
|
|
|
21
21
|
## Table of Contents
|
|
22
22
|
|
|
23
23
|
- [Installation](#installation)
|
|
24
|
+
- [Editor documentation](#editor-documentation)
|
|
24
25
|
- [Configuration](#configuration)
|
|
25
26
|
- [Quick Start](#quick-start)
|
|
26
27
|
- [Build Faster with AI](#build-faster-with-ai)
|
|
@@ -66,6 +67,31 @@ Or install the latest version from GitHub:
|
|
|
66
67
|
pip install git+https://github.com/captcha-solver-api/python-sdk.git
|
|
67
68
|
```
|
|
68
69
|
|
|
70
|
+
## Editor documentation
|
|
71
|
+
|
|
72
|
+
The SDK includes Python docstrings (the equivalent of JSDoc), type annotations,
|
|
73
|
+
and a `py.typed` marker in the installed package. With Python language support
|
|
74
|
+
enabled in your editor, hover over `CaptchaClient`, `AsyncCaptchaClient`, their
|
|
75
|
+
methods, or a task class such as `RecaptchaV2TaskProxyless` to read the documentation.
|
|
76
|
+
Signature help shows argument names, types, and defaults while you type a call.
|
|
77
|
+
|
|
78
|
+
Docstrings describe parameters, solution fields, exceptions, and usage examples.
|
|
79
|
+
Task examples assume an existing synchronous `client`; with `AsyncCaptchaClient`,
|
|
80
|
+
use `solution = await client.solve(task)` instead. Async snippets run inside an
|
|
81
|
+
`async def` function. In VS Code, select the Python interpreter where the SDK is
|
|
82
|
+
installed and enable the Python and Pylance extensions. In PyCharm, use Quick
|
|
83
|
+
Documentation. The exact presentation depends on the editor.
|
|
84
|
+
|
|
85
|
+
You can also read the same documentation without an editor:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from captcha_solver_api import CaptchaClient
|
|
89
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
90
|
+
|
|
91
|
+
help(CaptchaClient.solve)
|
|
92
|
+
help(RecaptchaV2TaskProxyless)
|
|
93
|
+
```
|
|
94
|
+
|
|
69
95
|
## Configuration
|
|
70
96
|
|
|
71
97
|
The client always takes the API key as an explicit argument -- it does not read
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.4"
|
|
@@ -22,19 +22,39 @@ from .exceptions import (
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class AsyncCaptchaClient:
|
|
25
|
-
"""
|
|
26
|
-
Async client for interacting with the Captcha Solver API.
|
|
25
|
+
"""Asynchronous client for submitting tasks and awaiting CAPTCHA solutions.
|
|
27
26
|
|
|
28
27
|
Holds a single, reused `httpx.AsyncClient` connection pool for the
|
|
29
28
|
lifetime of the instance (created once, not per request), so repeated
|
|
30
29
|
calls -- especially the `getTaskResult` polling inside `solve()` --
|
|
31
30
|
reuse the same keep-alive connection instead of paying a fresh TCP/TLS
|
|
32
31
|
handshake every time. Close it with `aclose()` when you're done, or use
|
|
33
|
-
it as an async context manager
|
|
32
|
+
it as an async context manager.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
client_key: Your Captcha Solver API key. Must not be empty.
|
|
36
|
+
base_url: API base URL. Defaults to `https://api.captcha-solver.com`.
|
|
37
|
+
timeout: Default polling timeout in seconds, starting after task creation.
|
|
38
|
+
Defaults to 120. Each HTTP request has a separate 30-second timeout.
|
|
39
|
+
polling_interval: Seconds before the first poll and between polls.
|
|
40
|
+
Defaults to 10. Waiting does not block the event loop.
|
|
41
|
+
language_pool: Default worker pool, e.g. `"en"` or `"ru"`. `None` uses
|
|
42
|
+
the account default. Can be overridden in `solve()` or `create_task()`.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
ValidationError: `client_key` is empty.
|
|
34
46
|
|
|
35
47
|
Example:
|
|
48
|
+
from captcha_solver_api import AsyncCaptchaClient
|
|
49
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
50
|
+
|
|
51
|
+
task = RecaptchaV2TaskProxyless(
|
|
52
|
+
websiteURL="https://example.com",
|
|
53
|
+
websiteKey="SITE_KEY",
|
|
54
|
+
)
|
|
36
55
|
async with AsyncCaptchaClient("YOUR_API_KEY") as client:
|
|
37
|
-
|
|
56
|
+
solution = await client.solve(task)
|
|
57
|
+
token = solution["gRecaptchaResponse"]
|
|
38
58
|
"""
|
|
39
59
|
|
|
40
60
|
def __init__(
|
|
@@ -45,13 +65,16 @@ class AsyncCaptchaClient:
|
|
|
45
65
|
polling_interval: int = 10,
|
|
46
66
|
language_pool: Optional[str] = None,
|
|
47
67
|
) -> None:
|
|
48
|
-
"""
|
|
68
|
+
"""Create an async client with a reusable HTTP connection pool.
|
|
69
|
+
|
|
49
70
|
Args:
|
|
50
71
|
client_key: Your Captcha Solver API key.
|
|
51
72
|
base_url: API base URL. Override only for self-hosted or staging
|
|
52
73
|
deployments.
|
|
53
|
-
timeout: Default
|
|
54
|
-
|
|
74
|
+
timeout: Default polling timeout in seconds, starting after task
|
|
75
|
+
creation. Defaults to 120 and can be overridden per `solve()` call.
|
|
76
|
+
Each HTTP request has a separate 30-second timeout, so this is
|
|
77
|
+
not a strict deadline for the entire call.
|
|
55
78
|
polling_interval: Seconds to wait before the first `getTaskResult`
|
|
56
79
|
poll and between subsequent polls inside `solve()`. Defaults
|
|
57
80
|
to 10 seconds.
|
|
@@ -145,6 +168,9 @@ class AsyncCaptchaClient:
|
|
|
145
168
|
ApiError: The API rejected the task or its parameters.
|
|
146
169
|
NetworkError: The request failed at the transport level.
|
|
147
170
|
CaptchaTimeoutError: The HTTP request timed out.
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
task_id = await client.create_task(task, language_pool="en")
|
|
148
174
|
"""
|
|
149
175
|
payload: Dict[str, Any] = {
|
|
150
176
|
"clientKey": self.client_key,
|
|
@@ -171,13 +197,20 @@ class AsyncCaptchaClient:
|
|
|
171
197
|
task_id: The ID returned by `create_task()`.
|
|
172
198
|
|
|
173
199
|
Returns:
|
|
174
|
-
The raw API response with `status
|
|
175
|
-
solution
|
|
200
|
+
The raw API response with `status` (`"processing"` or `"ready"`).
|
|
201
|
+
Ready responses also contain a `solution` dict, e.g.
|
|
202
|
+
`{"gRecaptchaResponse": "..."}` for reCAPTCHA or `{"text": "..."}`
|
|
203
|
+
for `ImageToTextTask`.
|
|
176
204
|
|
|
177
205
|
Raises:
|
|
178
206
|
ApiError: The API reports an error for the task.
|
|
179
207
|
NetworkError: The request failed at the transport level.
|
|
180
208
|
CaptchaTimeoutError: The HTTP request timed out.
|
|
209
|
+
|
|
210
|
+
Example:
|
|
211
|
+
result = await client.get_task_result(task_id)
|
|
212
|
+
if result["status"] == "ready":
|
|
213
|
+
solution = result["solution"]
|
|
181
214
|
"""
|
|
182
215
|
payload = {
|
|
183
216
|
"clientKey": self.client_key,
|
|
@@ -201,6 +234,9 @@ class AsyncCaptchaClient:
|
|
|
201
234
|
ApiError: The API key is invalid or the account cannot be resolved.
|
|
202
235
|
NetworkError: The request failed at the transport level.
|
|
203
236
|
CaptchaTimeoutError: The HTTP request timed out.
|
|
237
|
+
|
|
238
|
+
Example:
|
|
239
|
+
balance = await client.get_balance()
|
|
204
240
|
"""
|
|
205
241
|
payload = {"clientKey": self.client_key}
|
|
206
242
|
data = await self._request("getBalance", payload)
|
|
@@ -226,16 +262,31 @@ class AsyncCaptchaClient:
|
|
|
226
262
|
task: A task object from `captcha_solver_api.tasks`.
|
|
227
263
|
language_pool: Optional worker pool selector. Falls back to the
|
|
228
264
|
client's configured pool.
|
|
229
|
-
timeout:
|
|
230
|
-
the client's default
|
|
265
|
+
timeout: Polling timeout in seconds, starting after task creation.
|
|
266
|
+
`None` uses the client's default (120 unless configured otherwise).
|
|
267
|
+
Each HTTP request has a separate 30-second timeout, so this is
|
|
268
|
+
not a strict deadline for the entire call.
|
|
231
269
|
|
|
232
270
|
Returns:
|
|
233
|
-
The solution
|
|
271
|
+
The `solution` dict once `status` is `"ready"`. Its shape depends on
|
|
272
|
+
the task type -- see the per-type docstrings in `captcha_solver_api.tasks`
|
|
273
|
+
or the README's method reference.
|
|
234
274
|
|
|
235
275
|
Raises:
|
|
236
276
|
ApiError: The API rejected the task or reported a solving error.
|
|
237
|
-
CaptchaTimeoutError:
|
|
238
|
-
|
|
277
|
+
CaptchaTimeoutError: Polling exceeded its deadline or an HTTP request
|
|
278
|
+
timed out.
|
|
279
|
+
NetworkError: A request failed or the API returned an invalid response.
|
|
280
|
+
|
|
281
|
+
Example:
|
|
282
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
283
|
+
|
|
284
|
+
task = RecaptchaV2TaskProxyless(
|
|
285
|
+
websiteURL="https://example.com",
|
|
286
|
+
websiteKey="SITE_KEY",
|
|
287
|
+
)
|
|
288
|
+
solution = await client.solve(task, timeout=180)
|
|
289
|
+
token = solution["gRecaptchaResponse"]
|
|
239
290
|
"""
|
|
240
291
|
|
|
241
292
|
task_id = await self.create_task(task, language_pool=language_pool)
|
|
@@ -19,11 +19,32 @@ from .exceptions import (
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class CaptchaClient:
|
|
22
|
-
"""
|
|
23
|
-
|
|
22
|
+
"""Synchronous client for submitting tasks and waiting for CAPTCHA solutions.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
client_key: Your Captcha Solver API key. Must not be empty.
|
|
26
|
+
base_url: API base URL. Defaults to `https://api.captcha-solver.com`.
|
|
27
|
+
timeout: Default polling timeout in seconds, starting after task creation.
|
|
28
|
+
Defaults to 120. Each HTTP request has a separate 30-second timeout.
|
|
29
|
+
polling_interval: Seconds before the first poll and between polls.
|
|
30
|
+
Defaults to 10.
|
|
31
|
+
language_pool: Default worker pool, e.g. `"en"` or `"ru"`. `None` uses
|
|
32
|
+
the account default. Can be overridden in `solve()` or `create_task()`.
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ValidationError: `client_key` is empty.
|
|
24
36
|
|
|
25
37
|
Example:
|
|
26
|
-
|
|
38
|
+
from captcha_solver_api import CaptchaClient
|
|
39
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
40
|
+
|
|
41
|
+
task = RecaptchaV2TaskProxyless(
|
|
42
|
+
websiteURL="https://example.com",
|
|
43
|
+
websiteKey="SITE_KEY",
|
|
44
|
+
)
|
|
45
|
+
with CaptchaClient("YOUR_API_KEY") as client:
|
|
46
|
+
solution = client.solve(task)
|
|
47
|
+
token = solution["gRecaptchaResponse"]
|
|
27
48
|
"""
|
|
28
49
|
|
|
29
50
|
def __init__(
|
|
@@ -34,13 +55,16 @@ class CaptchaClient:
|
|
|
34
55
|
polling_interval: int = 10,
|
|
35
56
|
language_pool: Optional[str] = None,
|
|
36
57
|
) -> None:
|
|
37
|
-
"""
|
|
58
|
+
"""Create a client with a reusable HTTP connection pool.
|
|
59
|
+
|
|
38
60
|
Args:
|
|
39
61
|
client_key: Your Captcha Solver API key.
|
|
40
62
|
base_url: API base URL. Override only for self-hosted or staging
|
|
41
63
|
deployments.
|
|
42
|
-
timeout: Default
|
|
43
|
-
|
|
64
|
+
timeout: Default polling timeout in seconds, starting after task
|
|
65
|
+
creation. Defaults to 120 and can be overridden per `solve()` call.
|
|
66
|
+
Each HTTP request has a separate 30-second timeout, so this is
|
|
67
|
+
not a strict deadline for the entire call.
|
|
44
68
|
polling_interval: Seconds to wait before the first `getTaskResult`
|
|
45
69
|
poll and between subsequent polls inside `solve()`. Defaults
|
|
46
70
|
to 10 seconds.
|
|
@@ -132,6 +156,9 @@ class CaptchaClient:
|
|
|
132
156
|
ApiError: The API rejected the task (bad key, bad parameters, etc).
|
|
133
157
|
NetworkError: The request failed at the transport level.
|
|
134
158
|
CaptchaTimeoutError: The HTTP request itself timed out (not the solve).
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
task_id = client.create_task(task, language_pool="en")
|
|
135
162
|
"""
|
|
136
163
|
payload: Dict[str, Any] = {
|
|
137
164
|
"clientKey": self.client_key,
|
|
@@ -164,6 +191,11 @@ class CaptchaClient:
|
|
|
164
191
|
ApiError: The API reports an error for this task (e.g. it expired).
|
|
165
192
|
NetworkError: The request failed at the transport level.
|
|
166
193
|
CaptchaTimeoutError: The HTTP request timed out.
|
|
194
|
+
|
|
195
|
+
Example:
|
|
196
|
+
result = client.get_task_result(task_id)
|
|
197
|
+
if result["status"] == "ready":
|
|
198
|
+
solution = result["solution"]
|
|
167
199
|
"""
|
|
168
200
|
payload = {
|
|
169
201
|
"clientKey": self.client_key,
|
|
@@ -185,6 +217,9 @@ class CaptchaClient:
|
|
|
185
217
|
ApiError: The API key is invalid or the account can't be resolved.
|
|
186
218
|
NetworkError: The request failed at the transport level.
|
|
187
219
|
CaptchaTimeoutError: The HTTP request timed out.
|
|
220
|
+
|
|
221
|
+
Example:
|
|
222
|
+
balance = client.get_balance()
|
|
188
223
|
"""
|
|
189
224
|
payload = {"clientKey": self.client_key}
|
|
190
225
|
data = self._request("getBalance", payload)
|
|
@@ -205,9 +240,10 @@ class CaptchaClient:
|
|
|
205
240
|
task: One of the task objects from `captcha_solver_api.tasks`.
|
|
206
241
|
language_pool: Worker pool selector, e.g. `"en"` or `"ru"`. Falls back
|
|
207
242
|
to the client's `language_pool` (set at construction) when omitted.
|
|
208
|
-
timeout:
|
|
209
|
-
|
|
210
|
-
|
|
243
|
+
timeout: Polling timeout in seconds, starting after task creation.
|
|
244
|
+
`None` uses the client's default (120 unless configured otherwise).
|
|
245
|
+
Each HTTP request has a separate 30-second timeout, so this is
|
|
246
|
+
not a strict deadline for the entire call.
|
|
211
247
|
|
|
212
248
|
Returns:
|
|
213
249
|
The `solution` dict once `status` is `"ready"`. Its shape depends on
|
|
@@ -216,8 +252,19 @@ class CaptchaClient:
|
|
|
216
252
|
|
|
217
253
|
Raises:
|
|
218
254
|
ApiError: The API rejected the task or reported an error while solving.
|
|
219
|
-
CaptchaTimeoutError:
|
|
220
|
-
|
|
255
|
+
CaptchaTimeoutError: Polling exceeded its deadline or an HTTP request
|
|
256
|
+
timed out.
|
|
257
|
+
NetworkError: A request failed or the API returned an invalid response.
|
|
258
|
+
|
|
259
|
+
Example:
|
|
260
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
261
|
+
|
|
262
|
+
task = RecaptchaV2TaskProxyless(
|
|
263
|
+
websiteURL="https://example.com",
|
|
264
|
+
websiteKey="SITE_KEY",
|
|
265
|
+
)
|
|
266
|
+
solution = client.solve(task, timeout=180)
|
|
267
|
+
token = solution["gRecaptchaResponse"]
|
|
221
268
|
"""
|
|
222
269
|
|
|
223
270
|
task_id = self.create_task(task, language_pool=language_pool)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom exceptions used by the Captcha Solver SDK.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CaptchaError(Exception):
|
|
7
|
+
"""Base exception for all SDK errors.
|
|
8
|
+
|
|
9
|
+
Catch this to handle `ApiError`, `NetworkError`, `CaptchaTimeoutError`, and
|
|
10
|
+
`ValidationError` together.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class NetworkError(CaptchaError):
|
|
15
|
+
"""An HTTP request failed or the API returned an invalid response.
|
|
16
|
+
|
|
17
|
+
Includes HTTP error statuses, non-JSON responses, unexpected response
|
|
18
|
+
shapes, and ready tasks whose solution is not a dictionary.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CaptchaTimeoutError(CaptchaError):
|
|
23
|
+
"""An HTTP request timed out or the task's polling deadline was reached.
|
|
24
|
+
|
|
25
|
+
`solve(timeout=...)` overrides the polling timeout; each HTTP request uses
|
|
26
|
+
a separate 30-second timeout. `TimeoutError` is a deprecated alias of this
|
|
27
|
+
class; prefer `CaptchaTimeoutError` to avoid shadowing Python's built-in.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# Deprecated alias kept for backward compatibility. It shadows the built-in
|
|
32
|
+
# ``TimeoutError`` when imported by name, so prefer ``CaptchaTimeoutError``.
|
|
33
|
+
TimeoutError = CaptchaTimeoutError
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ApiError(CaptchaError):
|
|
37
|
+
"""The API returned a nonzero `errorId`.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
error_code: Machine-readable API `errorCode`.
|
|
41
|
+
error_description: Human-readable API `errorDescription`.
|
|
42
|
+
|
|
43
|
+
Attributes:
|
|
44
|
+
error_code: Error code to use when deciding how to handle the failure.
|
|
45
|
+
error_description: Explanation supplied by the API.
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
try:
|
|
49
|
+
solution = client.solve(task)
|
|
50
|
+
except ApiError as exc:
|
|
51
|
+
print(exc.error_code, exc.error_description)
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, error_code: str, error_description: str) -> None:
|
|
55
|
+
self.error_code = error_code
|
|
56
|
+
self.error_description = error_description
|
|
57
|
+
super().__init__(f"{error_code}: {error_description}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ValidationError(CaptchaError):
|
|
61
|
+
"""Raised for client-side argument problems caught before any request is sent."""
|
|
@@ -86,6 +86,19 @@ class RecaptchaV2TaskProxyless(BaseTask):
|
|
|
86
86
|
|
|
87
87
|
Returns (`solution` from `solve()`):
|
|
88
88
|
`gRecaptchaResponse` -- the token to submit as `g-recaptcha-response`.
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
92
|
+
|
|
93
|
+
task = RecaptchaV2TaskProxyless(
|
|
94
|
+
websiteURL="https://example.com",
|
|
95
|
+
websiteKey="SITE_KEY",
|
|
96
|
+
)
|
|
97
|
+
solution = client.solve(task)
|
|
98
|
+
answer = solution["gRecaptchaResponse"]
|
|
99
|
+
|
|
100
|
+
Note:
|
|
101
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
89
102
|
"""
|
|
90
103
|
|
|
91
104
|
type = "RecaptchaV2TaskProxyless"
|
|
@@ -132,6 +145,22 @@ class RecaptchaV2Task(BaseTask, ProxyMixin):
|
|
|
132
145
|
|
|
133
146
|
Returns (`solution` from `solve()`):
|
|
134
147
|
`gRecaptchaResponse` -- the token to submit as `g-recaptcha-response`.
|
|
148
|
+
|
|
149
|
+
Example:
|
|
150
|
+
from captcha_solver_api.tasks import RecaptchaV2Task
|
|
151
|
+
|
|
152
|
+
task = RecaptchaV2Task(
|
|
153
|
+
websiteURL="https://example.com",
|
|
154
|
+
websiteKey="SITE_KEY",
|
|
155
|
+
proxyType="http",
|
|
156
|
+
proxyAddress="proxy.example.com",
|
|
157
|
+
proxyPort=8080,
|
|
158
|
+
)
|
|
159
|
+
solution = client.solve(task)
|
|
160
|
+
answer = solution["gRecaptchaResponse"]
|
|
161
|
+
|
|
162
|
+
Note:
|
|
163
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
135
164
|
"""
|
|
136
165
|
|
|
137
166
|
type = "RecaptchaV2Task"
|
|
@@ -180,6 +209,19 @@ class RecaptchaV2EnterpriseTaskProxyless(BaseTask):
|
|
|
180
209
|
|
|
181
210
|
Returns (`solution` from `solve()`):
|
|
182
211
|
`gRecaptchaResponse` -- the token to submit as `g-recaptcha-response`.
|
|
212
|
+
|
|
213
|
+
Example:
|
|
214
|
+
from captcha_solver_api.tasks import RecaptchaV2EnterpriseTaskProxyless
|
|
215
|
+
|
|
216
|
+
task = RecaptchaV2EnterpriseTaskProxyless(
|
|
217
|
+
websiteURL="https://example.com",
|
|
218
|
+
websiteKey="SITE_KEY",
|
|
219
|
+
)
|
|
220
|
+
solution = client.solve(task)
|
|
221
|
+
answer = solution["gRecaptchaResponse"]
|
|
222
|
+
|
|
223
|
+
Note:
|
|
224
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
183
225
|
"""
|
|
184
226
|
|
|
185
227
|
type = "RecaptchaV2EnterpriseTaskProxyless"
|
|
@@ -223,6 +265,22 @@ class RecaptchaV2EnterpriseTask(BaseTask, ProxyMixin):
|
|
|
223
265
|
|
|
224
266
|
Returns (`solution` from `solve()`):
|
|
225
267
|
`gRecaptchaResponse` -- the token to submit as `g-recaptcha-response`.
|
|
268
|
+
|
|
269
|
+
Example:
|
|
270
|
+
from captcha_solver_api.tasks import RecaptchaV2EnterpriseTask
|
|
271
|
+
|
|
272
|
+
task = RecaptchaV2EnterpriseTask(
|
|
273
|
+
websiteURL="https://example.com",
|
|
274
|
+
websiteKey="SITE_KEY",
|
|
275
|
+
proxyType="http",
|
|
276
|
+
proxyAddress="proxy.example.com",
|
|
277
|
+
proxyPort=8080,
|
|
278
|
+
)
|
|
279
|
+
solution = client.solve(task)
|
|
280
|
+
answer = solution["gRecaptchaResponse"]
|
|
281
|
+
|
|
282
|
+
Note:
|
|
283
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
226
284
|
"""
|
|
227
285
|
|
|
228
286
|
type = "RecaptchaV2EnterpriseTask"
|
|
@@ -270,6 +328,21 @@ class RecaptchaV3TaskProxyless(BaseTask):
|
|
|
270
328
|
|
|
271
329
|
Returns (`solution` from `solve()`):
|
|
272
330
|
`gRecaptchaResponse` -- the token to submit as `g-recaptcha-response`.
|
|
331
|
+
|
|
332
|
+
Example:
|
|
333
|
+
from captcha_solver_api.tasks import RecaptchaV3TaskProxyless
|
|
334
|
+
|
|
335
|
+
task = RecaptchaV3TaskProxyless(
|
|
336
|
+
websiteURL="https://example.com",
|
|
337
|
+
websiteKey="SITE_KEY",
|
|
338
|
+
minScore=0.3,
|
|
339
|
+
pageAction="login",
|
|
340
|
+
)
|
|
341
|
+
solution = client.solve(task)
|
|
342
|
+
answer = solution["gRecaptchaResponse"]
|
|
343
|
+
|
|
344
|
+
Note:
|
|
345
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
273
346
|
"""
|
|
274
347
|
|
|
275
348
|
type = "RecaptchaV3TaskProxyless"
|
|
@@ -311,6 +384,19 @@ class TurnstileTaskProxyless(BaseTask):
|
|
|
311
384
|
`token` -- the value to submit as `cf-turnstile-response`.
|
|
312
385
|
`userAgent` -- for Cloudflare Challenge pages, switch the browser or HTTP
|
|
313
386
|
client to this returned User-Agent before invoking the callback.
|
|
387
|
+
|
|
388
|
+
Example:
|
|
389
|
+
from captcha_solver_api.tasks import TurnstileTaskProxyless
|
|
390
|
+
|
|
391
|
+
task = TurnstileTaskProxyless(
|
|
392
|
+
websiteURL="https://example.com",
|
|
393
|
+
websiteKey="SITE_KEY",
|
|
394
|
+
)
|
|
395
|
+
solution = client.solve(task)
|
|
396
|
+
answer = solution["token"]
|
|
397
|
+
|
|
398
|
+
Note:
|
|
399
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
314
400
|
"""
|
|
315
401
|
|
|
316
402
|
type = "TurnstileTaskProxyless"
|
|
@@ -356,6 +442,22 @@ class TurnstileTask(BaseTask, ProxyMixin):
|
|
|
356
442
|
`token` -- the value to submit as `cf-turnstile-response`.
|
|
357
443
|
`userAgent` -- for Cloudflare Challenge pages, switch the browser or HTTP
|
|
358
444
|
client to this returned User-Agent before invoking the callback.
|
|
445
|
+
|
|
446
|
+
Example:
|
|
447
|
+
from captcha_solver_api.tasks import TurnstileTask
|
|
448
|
+
|
|
449
|
+
task = TurnstileTask(
|
|
450
|
+
websiteURL="https://example.com",
|
|
451
|
+
websiteKey="SITE_KEY",
|
|
452
|
+
proxyType="http",
|
|
453
|
+
proxyAddress="proxy.example.com",
|
|
454
|
+
proxyPort=8080,
|
|
455
|
+
)
|
|
456
|
+
solution = client.solve(task)
|
|
457
|
+
answer = solution["token"]
|
|
458
|
+
|
|
459
|
+
Note:
|
|
460
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
359
461
|
"""
|
|
360
462
|
|
|
361
463
|
type = "TurnstileTask"
|
|
@@ -407,6 +509,18 @@ class ImageToTextTask(BaseTask):
|
|
|
407
509
|
|
|
408
510
|
Returns (`solution` from `solve()`):
|
|
409
511
|
`text` -- the recognized text/answer.
|
|
512
|
+
|
|
513
|
+
Example:
|
|
514
|
+
from captcha_solver_api.tasks import ImageToTextTask
|
|
515
|
+
|
|
516
|
+
task = ImageToTextTask(
|
|
517
|
+
body="BASE64_IMAGE",
|
|
518
|
+
)
|
|
519
|
+
solution = client.solve(task)
|
|
520
|
+
answer = solution["text"]
|
|
521
|
+
|
|
522
|
+
Note:
|
|
523
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
410
524
|
"""
|
|
411
525
|
|
|
412
526
|
type = "ImageToTextTask"
|
|
@@ -455,6 +569,20 @@ class GeeTestTaskProxyless(BaseTask):
|
|
|
455
569
|
Returns (`solution` from `solve()`):
|
|
456
570
|
v3: `challenge`, `validate`, `seccode`.
|
|
457
571
|
v4: `captcha_id`, `lot_number`, `pass_token`, `gen_time`, `captcha_output`.
|
|
572
|
+
|
|
573
|
+
Example:
|
|
574
|
+
from captcha_solver_api.tasks import GeeTestTaskProxyless
|
|
575
|
+
|
|
576
|
+
task = GeeTestTaskProxyless(
|
|
577
|
+
websiteURL="https://example.com",
|
|
578
|
+
version=4,
|
|
579
|
+
initParameters={"captcha_id": "CAPTCHA_ID"},
|
|
580
|
+
)
|
|
581
|
+
solution = client.solve(task)
|
|
582
|
+
answer = solution["captcha_output"]
|
|
583
|
+
|
|
584
|
+
Note:
|
|
585
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
458
586
|
"""
|
|
459
587
|
|
|
460
588
|
type = "GeeTestTaskProxyless"
|
|
@@ -505,6 +633,23 @@ class GeeTestTask(BaseTask, ProxyMixin):
|
|
|
505
633
|
Returns (`solution` from `solve()`):
|
|
506
634
|
v3: `challenge`, `validate`, `seccode`.
|
|
507
635
|
v4: `captcha_id`, `lot_number`, `pass_token`, `gen_time`, `captcha_output`.
|
|
636
|
+
|
|
637
|
+
Example:
|
|
638
|
+
from captcha_solver_api.tasks import GeeTestTask
|
|
639
|
+
|
|
640
|
+
task = GeeTestTask(
|
|
641
|
+
websiteURL="https://example.com",
|
|
642
|
+
version=4,
|
|
643
|
+
initParameters={"captcha_id": "CAPTCHA_ID"},
|
|
644
|
+
proxyType="http",
|
|
645
|
+
proxyAddress="proxy.example.com",
|
|
646
|
+
proxyPort=8080,
|
|
647
|
+
)
|
|
648
|
+
solution = client.solve(task)
|
|
649
|
+
answer = solution["captcha_output"]
|
|
650
|
+
|
|
651
|
+
Note:
|
|
652
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
508
653
|
"""
|
|
509
654
|
|
|
510
655
|
type = "GeeTestTask"
|
|
@@ -551,6 +696,19 @@ class YandexSmartCaptchaTaskProxyless(BaseTask):
|
|
|
551
696
|
|
|
552
697
|
Returns (`solution` from `solve()`):
|
|
553
698
|
`token` -- the value to submit as the SmartCaptcha response token.
|
|
699
|
+
|
|
700
|
+
Example:
|
|
701
|
+
from captcha_solver_api.tasks import YandexSmartCaptchaTaskProxyless
|
|
702
|
+
|
|
703
|
+
task = YandexSmartCaptchaTaskProxyless(
|
|
704
|
+
websiteURL="https://example.com",
|
|
705
|
+
websiteKey="SITE_KEY",
|
|
706
|
+
)
|
|
707
|
+
solution = client.solve(task)
|
|
708
|
+
answer = solution["token"]
|
|
709
|
+
|
|
710
|
+
Note:
|
|
711
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
554
712
|
"""
|
|
555
713
|
|
|
556
714
|
type = "YandexSmartCaptchaTaskProxyless"
|
|
@@ -584,6 +742,22 @@ class YandexSmartCaptchaTask(BaseTask, ProxyMixin):
|
|
|
584
742
|
|
|
585
743
|
Returns (`solution` from `solve()`):
|
|
586
744
|
`token` -- the value to submit as the SmartCaptcha response token.
|
|
745
|
+
|
|
746
|
+
Example:
|
|
747
|
+
from captcha_solver_api.tasks import YandexSmartCaptchaTask
|
|
748
|
+
|
|
749
|
+
task = YandexSmartCaptchaTask(
|
|
750
|
+
websiteURL="https://example.com",
|
|
751
|
+
websiteKey="SITE_KEY",
|
|
752
|
+
proxyType="http",
|
|
753
|
+
proxyAddress="proxy.example.com",
|
|
754
|
+
proxyPort=8080,
|
|
755
|
+
)
|
|
756
|
+
solution = client.solve(task)
|
|
757
|
+
answer = solution["token"]
|
|
758
|
+
|
|
759
|
+
Note:
|
|
760
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
587
761
|
"""
|
|
588
762
|
|
|
589
763
|
type = "YandexSmartCaptchaTask"
|
|
@@ -626,6 +800,19 @@ class CoordinatesTask(BaseTask):
|
|
|
626
800
|
Returns (`solution` from `solve()`):
|
|
627
801
|
`coordinates` -- a list of `{"x": int, "y": int}` pixel positions to click,
|
|
628
802
|
in order.
|
|
803
|
+
|
|
804
|
+
Example:
|
|
805
|
+
from captcha_solver_api.tasks import CoordinatesTask
|
|
806
|
+
|
|
807
|
+
task = CoordinatesTask(
|
|
808
|
+
body="BASE64_IMAGE",
|
|
809
|
+
comment="Click on the green apple",
|
|
810
|
+
)
|
|
811
|
+
solution = client.solve(task)
|
|
812
|
+
answer = solution["coordinates"]
|
|
813
|
+
|
|
814
|
+
Note:
|
|
815
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
629
816
|
"""
|
|
630
817
|
|
|
631
818
|
type = "CoordinatesTask"
|
|
@@ -657,6 +844,19 @@ class TencentTaskProxyless(BaseTask):
|
|
|
657
844
|
Returns (`solution` from `solve()`):
|
|
658
845
|
`appid`, `ret`, `ticket`, `randstr` -- pass these to the page's Tencent
|
|
659
846
|
captcha callback.
|
|
847
|
+
|
|
848
|
+
Example:
|
|
849
|
+
from captcha_solver_api.tasks import TencentTaskProxyless
|
|
850
|
+
|
|
851
|
+
task = TencentTaskProxyless(
|
|
852
|
+
websiteURL="https://example.com",
|
|
853
|
+
appId="APP_ID",
|
|
854
|
+
)
|
|
855
|
+
solution = client.solve(task)
|
|
856
|
+
answer = solution["ticket"]
|
|
857
|
+
|
|
858
|
+
Note:
|
|
859
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
660
860
|
"""
|
|
661
861
|
|
|
662
862
|
type = "TencentTaskProxyless"
|
|
@@ -689,6 +889,22 @@ class TencentTask(BaseTask, ProxyMixin):
|
|
|
689
889
|
Returns (`solution` from `solve()`):
|
|
690
890
|
`appid`, `ret`, `ticket`, `randstr` -- pass these to the page's Tencent
|
|
691
891
|
captcha callback.
|
|
892
|
+
|
|
893
|
+
Example:
|
|
894
|
+
from captcha_solver_api.tasks import TencentTask
|
|
895
|
+
|
|
896
|
+
task = TencentTask(
|
|
897
|
+
websiteURL="https://example.com",
|
|
898
|
+
appId="APP_ID",
|
|
899
|
+
proxyType="http",
|
|
900
|
+
proxyAddress="proxy.example.com",
|
|
901
|
+
proxyPort=8080,
|
|
902
|
+
)
|
|
903
|
+
solution = client.solve(task)
|
|
904
|
+
answer = solution["ticket"]
|
|
905
|
+
|
|
906
|
+
Note:
|
|
907
|
+
Optional arguments default to `None` and are omitted from the request.
|
|
692
908
|
"""
|
|
693
909
|
|
|
694
910
|
type = "TencentTask"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: captcha-solver-api
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Official Python SDK for solving reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest v3/v4, Yandex SmartCaptcha, Tencent, and image/click captchas via the Captcha Solver API
|
|
5
5
|
Author: Captcha Solver Team
|
|
6
6
|
License-Expression: MIT
|
|
@@ -61,6 +61,7 @@ Full API reference (all endpoints, error codes, captcha-type details): **https:/
|
|
|
61
61
|
## Table of Contents
|
|
62
62
|
|
|
63
63
|
- [Installation](#installation)
|
|
64
|
+
- [Editor documentation](#editor-documentation)
|
|
64
65
|
- [Configuration](#configuration)
|
|
65
66
|
- [Quick Start](#quick-start)
|
|
66
67
|
- [Build Faster with AI](#build-faster-with-ai)
|
|
@@ -106,6 +107,31 @@ Or install the latest version from GitHub:
|
|
|
106
107
|
pip install git+https://github.com/captcha-solver-api/python-sdk.git
|
|
107
108
|
```
|
|
108
109
|
|
|
110
|
+
## Editor documentation
|
|
111
|
+
|
|
112
|
+
The SDK includes Python docstrings (the equivalent of JSDoc), type annotations,
|
|
113
|
+
and a `py.typed` marker in the installed package. With Python language support
|
|
114
|
+
enabled in your editor, hover over `CaptchaClient`, `AsyncCaptchaClient`, their
|
|
115
|
+
methods, or a task class such as `RecaptchaV2TaskProxyless` to read the documentation.
|
|
116
|
+
Signature help shows argument names, types, and defaults while you type a call.
|
|
117
|
+
|
|
118
|
+
Docstrings describe parameters, solution fields, exceptions, and usage examples.
|
|
119
|
+
Task examples assume an existing synchronous `client`; with `AsyncCaptchaClient`,
|
|
120
|
+
use `solution = await client.solve(task)` instead. Async snippets run inside an
|
|
121
|
+
`async def` function. In VS Code, select the Python interpreter where the SDK is
|
|
122
|
+
installed and enable the Python and Pylance extensions. In PyCharm, use Quick
|
|
123
|
+
Documentation. The exact presentation depends on the editor.
|
|
124
|
+
|
|
125
|
+
You can also read the same documentation without an editor:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from captcha_solver_api import CaptchaClient
|
|
129
|
+
from captcha_solver_api.tasks import RecaptchaV2TaskProxyless
|
|
130
|
+
|
|
131
|
+
help(CaptchaClient.solve)
|
|
132
|
+
help(RecaptchaV2TaskProxyless)
|
|
133
|
+
```
|
|
134
|
+
|
|
109
135
|
## Configuration
|
|
110
136
|
|
|
111
137
|
The client always takes the API key as an explicit argument -- it does not read
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.0.3"
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Custom exceptions used by the Captcha Solver SDK.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class CaptchaError(Exception):
|
|
7
|
-
"""Base exception for all SDK errors."""
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class NetworkError(CaptchaError):
|
|
11
|
-
"""Raised when a network request fails."""
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class CaptchaTimeoutError(CaptchaError):
|
|
15
|
-
"""Raised when the operation exceeds the configured timeout."""
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# Deprecated alias kept for backward compatibility. It shadows the built-in
|
|
19
|
-
# ``TimeoutError`` when imported by name, so prefer ``CaptchaTimeoutError``.
|
|
20
|
-
TimeoutError = CaptchaTimeoutError
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class ApiError(CaptchaError):
|
|
24
|
-
"""Raised when the API returns an error."""
|
|
25
|
-
|
|
26
|
-
def __init__(self, error_code: str, error_description: str) -> None:
|
|
27
|
-
self.error_code = error_code
|
|
28
|
-
self.error_description = error_description
|
|
29
|
-
super().__init__(f"{error_code}: {error_description}")
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class ValidationError(CaptchaError):
|
|
33
|
-
"""Raised for client-side argument problems caught before any request is sent."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/requires.txt
RENAMED
|
File without changes
|
{captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|