captcha-solver-api 1.0.2__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.2 → captcha_solver_api-1.0.4}/PKG-INFO +84 -7
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/README.md +79 -6
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api/__init__.py +8 -8
- captcha_solver_api-1.0.4/captcha_solver_api/_version.py +1 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api/async_client.py +75 -19
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api/client.py +68 -16
- captcha_solver_api-1.0.4/captcha_solver_api/exceptions.py +61 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api/tasks.py +227 -4
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/PKG-INFO +84 -7
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/requires.txt +4 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/pyproject.toml +35 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/tests/test_polling.py +29 -27
- captcha_solver_api-1.0.2/captcha_solver_api/_version.py +0 -1
- captcha_solver_api-1.0.2/captcha_solver_api/exceptions.py +0 -41
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/LICENSE.md +0 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api/py.typed +0 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/SOURCES.txt +0 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/dependency_links.txt +0 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/top_level.txt +0 -0
- {captcha_solver_api-1.0.2 → captcha_solver_api-1.0.4}/setup.cfg +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
|
|
@@ -32,11 +32,27 @@ Requires-Dist: pytest>=7; extra == "dev"
|
|
|
32
32
|
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
33
33
|
Requires-Dist: pytest-mock>=3; extra == "dev"
|
|
34
34
|
Requires-Dist: python-dotenv>=1.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
36
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
37
|
+
Requires-Dist: types-requests>=2.28; extra == "dev"
|
|
38
|
+
Requires-Dist: pytest-cov>=4; extra == "dev"
|
|
35
39
|
Dynamic: license-file
|
|
36
40
|
|
|
37
41
|
# Captcha Solver Python SDK
|
|
38
42
|
|
|
39
|
-

|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
[](https://pypi.org/project/captcha-solver-api/)
|
|
46
|
+
[](https://pypi.org/project/captcha-solver-api/)
|
|
47
|
+
[](https://pepy.tech/project/captcha-solver-api)
|
|
48
|
+
[](https://github.com/captcha-solver-api/python-sdk/actions/workflows/tests.yml)
|
|
49
|
+
[](https://github.com/captcha-solver-api/python-sdk/actions/workflows/tests.yml)
|
|
50
|
+
[](https://github.com/captcha-solver-api/python-sdk/blob/main/captcha_solver_api/py.typed)
|
|
51
|
+
[](https://github.com/captcha-solver-api/python-sdk/blob/main/LICENSE.md)
|
|
52
|
+
[](https://github.com/astral-sh/ruff)
|
|
53
|
+
[](https://mypy-lang.org/)
|
|
54
|
+
[](https://github.com/captcha-solver-api/python-sdk/releases)
|
|
55
|
+
[](https://github.com/captcha-solver-api/javascript-sdk)
|
|
40
56
|
|
|
41
57
|
Official Python SDK for the Captcha Solver API. Solve reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest, Yandex SmartCaptcha, Tencent, and image/click captchas with a single method call -- sync or async.
|
|
42
58
|
|
|
@@ -45,8 +61,10 @@ Full API reference (all endpoints, error codes, captcha-type details): **https:/
|
|
|
45
61
|
## Table of Contents
|
|
46
62
|
|
|
47
63
|
- [Installation](#installation)
|
|
64
|
+
- [Editor documentation](#editor-documentation)
|
|
48
65
|
- [Configuration](#configuration)
|
|
49
66
|
- [Quick Start](#quick-start)
|
|
67
|
+
- [Build Faster with AI](#build-faster-with-ai)
|
|
50
68
|
- [Supported CAPTCHA Types](#supported-captcha-types)
|
|
51
69
|
- [Client Reference](#client-reference)
|
|
52
70
|
- [CaptchaClient(...)](#captchaclient)
|
|
@@ -74,6 +92,7 @@ Full API reference (all endpoints, error codes, captcha-type details): **https:/
|
|
|
74
92
|
- [Running the examples](#running-the-examples)
|
|
75
93
|
- [Requirements](#requirements)
|
|
76
94
|
- [API Documentation](#api-documentation)
|
|
95
|
+
- [Useful Links](#useful-links)
|
|
77
96
|
- [License](#license)
|
|
78
97
|
|
|
79
98
|
## Installation
|
|
@@ -88,6 +107,31 @@ Or install the latest version from GitHub:
|
|
|
88
107
|
pip install git+https://github.com/captcha-solver-api/python-sdk.git
|
|
89
108
|
```
|
|
90
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
|
+
|
|
91
135
|
## Configuration
|
|
92
136
|
|
|
93
137
|
The client always takes the API key as an explicit argument -- it does not read
|
|
@@ -124,6 +168,23 @@ result = client.solve(task)
|
|
|
124
168
|
print(result["gRecaptchaResponse"])
|
|
125
169
|
```
|
|
126
170
|
|
|
171
|
+
## Build Faster with AI
|
|
172
|
+
|
|
173
|
+
Use our [`llms.txt`](https://captcha-solver.com/llms.txt) as context when asking an
|
|
174
|
+
AI assistant to build or update your integration. It contains the current API
|
|
175
|
+
format, supported task parameters, SDK installation instructions, solution
|
|
176
|
+
fields, and error codes in one file.
|
|
177
|
+
|
|
178
|
+
Copy this prompt and add a description of the page and CAPTCHA you need to
|
|
179
|
+
handle:
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
Read https://captcha-solver.com/llms.txt and use the Captcha Solver Python SDK.
|
|
183
|
+
Write a complete integration for this task: [describe your task here].
|
|
184
|
+
Use the documented task parameters and show how to apply the returned solution
|
|
185
|
+
on the target page.
|
|
186
|
+
```
|
|
187
|
+
|
|
127
188
|
## Supported CAPTCHA Types
|
|
128
189
|
|
|
129
190
|
| Type | Proxyless | With Proxy |
|
|
@@ -353,12 +414,13 @@ that the target page expects in `cf-turnstile-response`.
|
|
|
353
414
|
| `action` | no | Value of the widget's `data-action` attribute, if set. |
|
|
354
415
|
| `data` | no | Custom payload from the widget's `data-cdata` attribute, if set. |
|
|
355
416
|
| `pagedata` | no | Value of the `chlPageData` parameter, needed for some Cloudflare challenge pages beyond the basic widget. |
|
|
356
|
-
| `userAgent` | no | User-Agent
|
|
417
|
+
| `userAgent` | no | Current browser User-Agent. Pass it for Cloudflare Challenge pages; it is not needed for a standalone widget. |
|
|
357
418
|
|
|
358
419
|
**Response:** `token` -- submit as `cf-turnstile-response`. For Cloudflare
|
|
359
|
-
Challenge pages,
|
|
360
|
-
|
|
361
|
-
|
|
420
|
+
Challenge pages, pass `action`, `data`, `pagedata`, and the current browser
|
|
421
|
+
`userAgent` in the task. The solution also contains `userAgent`; switch the
|
|
422
|
+
browser or HTTP client to this returned value before invoking the callback with
|
|
423
|
+
the token. The API field is spelled `pagedata`, all lowercase.
|
|
362
424
|
|
|
363
425
|
```python
|
|
364
426
|
from captcha_solver_api import CaptchaClient
|
|
@@ -366,10 +428,15 @@ from captcha_solver_api.tasks import TurnstileTaskProxyless
|
|
|
366
428
|
client = CaptchaClient("your_api_key")
|
|
367
429
|
task = TurnstileTaskProxyless(
|
|
368
430
|
websiteURL="https://example.com/login",
|
|
369
|
-
websiteKey="YOUR_WEBSITE_KEY"
|
|
431
|
+
websiteKey="YOUR_WEBSITE_KEY",
|
|
432
|
+
action="managed",
|
|
433
|
+
data="INTERCEPTED_CDATA",
|
|
434
|
+
pagedata="INTERCEPTED_CHL_PAGE_DATA",
|
|
435
|
+
userAgent="CURRENT_BROWSER_USER_AGENT",
|
|
370
436
|
)
|
|
371
437
|
result = client.solve(task)
|
|
372
438
|
print(result["token"])
|
|
439
|
+
print(result.get("userAgent"))
|
|
373
440
|
```
|
|
374
441
|
|
|
375
442
|
With proxy, use `TurnstileTask` (same proxy fields as reCAPTCHA v2).
|
|
@@ -733,6 +800,16 @@ page and session parameters.
|
|
|
733
800
|
|
|
734
801
|
Full API reference: https://captcha-solver.com/en/docs/captcha-types
|
|
735
802
|
|
|
803
|
+
## Useful Links
|
|
804
|
+
|
|
805
|
+
- [JavaScript SDK](https://github.com/captcha-solver-api/javascript-sdk)
|
|
806
|
+
- [Python examples](https://github.com/captcha-solver-api/python-examples)
|
|
807
|
+
- [Selenium Python examples](https://github.com/captcha-solver-api/captcha-solver-selenium-python-examples)
|
|
808
|
+
- [JavaScript examples](https://github.com/captcha-solver-api/javascript-examples)
|
|
809
|
+
- [Tencent CAPTCHA automation examples](https://github.com/captcha-solver-api/How-to-Automate-Tencent-CAPTCHA)
|
|
810
|
+
- [Cloudflare Turnstile Puppeteer Demo](https://github.com/captcha-solver-api/cloudflare-turnstile-puppeteer-demo) — a working browser automation example for Cloudflare Turnstile.
|
|
811
|
+
- [How to Automate Tencent CAPTCHA](https://captcha-solver.com/en/blog/how-to-automate-tencent-captcha) — a step-by-step guide with Python and JavaScript SDK examples.
|
|
812
|
+
|
|
736
813
|
## License
|
|
737
814
|
|
|
738
815
|
This project is licensed under the MIT License. See [LICENSE.md](https://github.com/captcha-solver-api/python-sdk/blob/main/LICENSE.md) for details.
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# Captcha Solver Python SDK
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/captcha-solver-api/)
|
|
6
|
+
[](https://pypi.org/project/captcha-solver-api/)
|
|
7
|
+
[](https://pepy.tech/project/captcha-solver-api)
|
|
8
|
+
[](https://github.com/captcha-solver-api/python-sdk/actions/workflows/tests.yml)
|
|
9
|
+
[](https://github.com/captcha-solver-api/python-sdk/actions/workflows/tests.yml)
|
|
10
|
+
[](https://github.com/captcha-solver-api/python-sdk/blob/main/captcha_solver_api/py.typed)
|
|
11
|
+
[](https://github.com/captcha-solver-api/python-sdk/blob/main/LICENSE.md)
|
|
12
|
+
[](https://github.com/astral-sh/ruff)
|
|
13
|
+
[](https://mypy-lang.org/)
|
|
14
|
+
[](https://github.com/captcha-solver-api/python-sdk/releases)
|
|
15
|
+
[](https://github.com/captcha-solver-api/javascript-sdk)
|
|
4
16
|
|
|
5
17
|
Official Python SDK for the Captcha Solver API. Solve reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest, Yandex SmartCaptcha, Tencent, and image/click captchas with a single method call -- sync or async.
|
|
6
18
|
|
|
@@ -9,8 +21,10 @@ Full API reference (all endpoints, error codes, captcha-type details): **https:/
|
|
|
9
21
|
## Table of Contents
|
|
10
22
|
|
|
11
23
|
- [Installation](#installation)
|
|
24
|
+
- [Editor documentation](#editor-documentation)
|
|
12
25
|
- [Configuration](#configuration)
|
|
13
26
|
- [Quick Start](#quick-start)
|
|
27
|
+
- [Build Faster with AI](#build-faster-with-ai)
|
|
14
28
|
- [Supported CAPTCHA Types](#supported-captcha-types)
|
|
15
29
|
- [Client Reference](#client-reference)
|
|
16
30
|
- [CaptchaClient(...)](#captchaclient)
|
|
@@ -38,6 +52,7 @@ Full API reference (all endpoints, error codes, captcha-type details): **https:/
|
|
|
38
52
|
- [Running the examples](#running-the-examples)
|
|
39
53
|
- [Requirements](#requirements)
|
|
40
54
|
- [API Documentation](#api-documentation)
|
|
55
|
+
- [Useful Links](#useful-links)
|
|
41
56
|
- [License](#license)
|
|
42
57
|
|
|
43
58
|
## Installation
|
|
@@ -52,6 +67,31 @@ Or install the latest version from GitHub:
|
|
|
52
67
|
pip install git+https://github.com/captcha-solver-api/python-sdk.git
|
|
53
68
|
```
|
|
54
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
|
+
|
|
55
95
|
## Configuration
|
|
56
96
|
|
|
57
97
|
The client always takes the API key as an explicit argument -- it does not read
|
|
@@ -88,6 +128,23 @@ result = client.solve(task)
|
|
|
88
128
|
print(result["gRecaptchaResponse"])
|
|
89
129
|
```
|
|
90
130
|
|
|
131
|
+
## Build Faster with AI
|
|
132
|
+
|
|
133
|
+
Use our [`llms.txt`](https://captcha-solver.com/llms.txt) as context when asking an
|
|
134
|
+
AI assistant to build or update your integration. It contains the current API
|
|
135
|
+
format, supported task parameters, SDK installation instructions, solution
|
|
136
|
+
fields, and error codes in one file.
|
|
137
|
+
|
|
138
|
+
Copy this prompt and add a description of the page and CAPTCHA you need to
|
|
139
|
+
handle:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
Read https://captcha-solver.com/llms.txt and use the Captcha Solver Python SDK.
|
|
143
|
+
Write a complete integration for this task: [describe your task here].
|
|
144
|
+
Use the documented task parameters and show how to apply the returned solution
|
|
145
|
+
on the target page.
|
|
146
|
+
```
|
|
147
|
+
|
|
91
148
|
## Supported CAPTCHA Types
|
|
92
149
|
|
|
93
150
|
| Type | Proxyless | With Proxy |
|
|
@@ -317,12 +374,13 @@ that the target page expects in `cf-turnstile-response`.
|
|
|
317
374
|
| `action` | no | Value of the widget's `data-action` attribute, if set. |
|
|
318
375
|
| `data` | no | Custom payload from the widget's `data-cdata` attribute, if set. |
|
|
319
376
|
| `pagedata` | no | Value of the `chlPageData` parameter, needed for some Cloudflare challenge pages beyond the basic widget. |
|
|
320
|
-
| `userAgent` | no | User-Agent
|
|
377
|
+
| `userAgent` | no | Current browser User-Agent. Pass it for Cloudflare Challenge pages; it is not needed for a standalone widget. |
|
|
321
378
|
|
|
322
379
|
**Response:** `token` -- submit as `cf-turnstile-response`. For Cloudflare
|
|
323
|
-
Challenge pages,
|
|
324
|
-
|
|
325
|
-
|
|
380
|
+
Challenge pages, pass `action`, `data`, `pagedata`, and the current browser
|
|
381
|
+
`userAgent` in the task. The solution also contains `userAgent`; switch the
|
|
382
|
+
browser or HTTP client to this returned value before invoking the callback with
|
|
383
|
+
the token. The API field is spelled `pagedata`, all lowercase.
|
|
326
384
|
|
|
327
385
|
```python
|
|
328
386
|
from captcha_solver_api import CaptchaClient
|
|
@@ -330,10 +388,15 @@ from captcha_solver_api.tasks import TurnstileTaskProxyless
|
|
|
330
388
|
client = CaptchaClient("your_api_key")
|
|
331
389
|
task = TurnstileTaskProxyless(
|
|
332
390
|
websiteURL="https://example.com/login",
|
|
333
|
-
websiteKey="YOUR_WEBSITE_KEY"
|
|
391
|
+
websiteKey="YOUR_WEBSITE_KEY",
|
|
392
|
+
action="managed",
|
|
393
|
+
data="INTERCEPTED_CDATA",
|
|
394
|
+
pagedata="INTERCEPTED_CHL_PAGE_DATA",
|
|
395
|
+
userAgent="CURRENT_BROWSER_USER_AGENT",
|
|
334
396
|
)
|
|
335
397
|
result = client.solve(task)
|
|
336
398
|
print(result["token"])
|
|
399
|
+
print(result.get("userAgent"))
|
|
337
400
|
```
|
|
338
401
|
|
|
339
402
|
With proxy, use `TurnstileTask` (same proxy fields as reCAPTCHA v2).
|
|
@@ -697,6 +760,16 @@ page and session parameters.
|
|
|
697
760
|
|
|
698
761
|
Full API reference: https://captcha-solver.com/en/docs/captcha-types
|
|
699
762
|
|
|
763
|
+
## Useful Links
|
|
764
|
+
|
|
765
|
+
- [JavaScript SDK](https://github.com/captcha-solver-api/javascript-sdk)
|
|
766
|
+
- [Python examples](https://github.com/captcha-solver-api/python-examples)
|
|
767
|
+
- [Selenium Python examples](https://github.com/captcha-solver-api/captcha-solver-selenium-python-examples)
|
|
768
|
+
- [JavaScript examples](https://github.com/captcha-solver-api/javascript-examples)
|
|
769
|
+
- [Tencent CAPTCHA automation examples](https://github.com/captcha-solver-api/How-to-Automate-Tencent-CAPTCHA)
|
|
770
|
+
- [Cloudflare Turnstile Puppeteer Demo](https://github.com/captcha-solver-api/cloudflare-turnstile-puppeteer-demo) — a working browser automation example for Cloudflare Turnstile.
|
|
771
|
+
- [How to Automate Tencent CAPTCHA](https://captcha-solver.com/en/blog/how-to-automate-tencent-captcha) — a step-by-step guide with Python and JavaScript SDK examples.
|
|
772
|
+
|
|
700
773
|
## License
|
|
701
774
|
|
|
702
775
|
This project is licensed under the MIT License. See [LICENSE.md](https://github.com/captcha-solver-api/python-sdk/blob/main/LICENSE.md) for details.
|
|
@@ -13,26 +13,26 @@ Example:
|
|
|
13
13
|
result = client.solve(task)
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
from .
|
|
16
|
+
from ._version import __version__
|
|
17
17
|
from .async_client import AsyncCaptchaClient
|
|
18
|
+
from .client import CaptchaClient
|
|
18
19
|
from .exceptions import (
|
|
19
|
-
CaptchaError,
|
|
20
20
|
ApiError,
|
|
21
|
-
|
|
21
|
+
CaptchaError,
|
|
22
22
|
CaptchaTimeoutError,
|
|
23
|
+
NetworkError,
|
|
23
24
|
TimeoutError,
|
|
24
25
|
ValidationError,
|
|
25
26
|
)
|
|
26
27
|
|
|
27
|
-
from ._version import __version__
|
|
28
|
-
|
|
29
28
|
__all__ = [
|
|
30
|
-
"
|
|
29
|
+
"ApiError",
|
|
31
30
|
"AsyncCaptchaClient",
|
|
31
|
+
"CaptchaClient",
|
|
32
32
|
"CaptchaError",
|
|
33
|
-
"ApiError",
|
|
34
|
-
"NetworkError",
|
|
35
33
|
"CaptchaTimeoutError",
|
|
34
|
+
"NetworkError",
|
|
36
35
|
"TimeoutError",
|
|
37
36
|
"ValidationError",
|
|
37
|
+
"__version__",
|
|
38
38
|
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.4"
|
|
@@ -15,26 +15,46 @@ import httpx
|
|
|
15
15
|
from ._version import __version__
|
|
16
16
|
from .exceptions import (
|
|
17
17
|
ApiError,
|
|
18
|
-
NetworkError,
|
|
19
18
|
CaptchaTimeoutError,
|
|
19
|
+
NetworkError,
|
|
20
20
|
ValidationError,
|
|
21
21
|
)
|
|
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.
|
|
@@ -87,7 +110,7 @@ class AsyncCaptchaClient:
|
|
|
87
110
|
(`async with AsyncCaptchaClient(...) as c:`) to have it closed automatically."""
|
|
88
111
|
await self._client.aclose()
|
|
89
112
|
|
|
90
|
-
async def __aenter__(self) ->
|
|
113
|
+
async def __aenter__(self) -> AsyncCaptchaClient:
|
|
91
114
|
return self
|
|
92
115
|
|
|
93
116
|
async def __aexit__(self, *exc_info: Any) -> None:
|
|
@@ -113,6 +136,8 @@ class AsyncCaptchaClient:
|
|
|
113
136
|
except ValueError as exc:
|
|
114
137
|
raise NetworkError(f"Non-JSON response from API: {response.text[:200]!r}") from exc
|
|
115
138
|
|
|
139
|
+
if not isinstance(data, dict):
|
|
140
|
+
raise NetworkError(f"Unexpected API response shape: {type(data).__name__}")
|
|
116
141
|
return data
|
|
117
142
|
|
|
118
143
|
def _ensure_success(self, data: Dict[str, Any]) -> None:
|
|
@@ -143,6 +168,9 @@ class AsyncCaptchaClient:
|
|
|
143
168
|
ApiError: The API rejected the task or its parameters.
|
|
144
169
|
NetworkError: The request failed at the transport level.
|
|
145
170
|
CaptchaTimeoutError: The HTTP request timed out.
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
task_id = await client.create_task(task, language_pool="en")
|
|
146
174
|
"""
|
|
147
175
|
payload: Dict[str, Any] = {
|
|
148
176
|
"clientKey": self.client_key,
|
|
@@ -154,7 +182,7 @@ class AsyncCaptchaClient:
|
|
|
154
182
|
|
|
155
183
|
data = await self._request("createTask", payload)
|
|
156
184
|
self._ensure_success(data)
|
|
157
|
-
return data["taskId"]
|
|
185
|
+
return int(data["taskId"])
|
|
158
186
|
|
|
159
187
|
async def get_task_result(self, task_id: int) -> Dict[str, Any]:
|
|
160
188
|
"""Fetch the current status of a previously submitted task.
|
|
@@ -169,13 +197,20 @@ class AsyncCaptchaClient:
|
|
|
169
197
|
task_id: The ID returned by `create_task()`.
|
|
170
198
|
|
|
171
199
|
Returns:
|
|
172
|
-
The raw API response with `status
|
|
173
|
-
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`.
|
|
174
204
|
|
|
175
205
|
Raises:
|
|
176
206
|
ApiError: The API reports an error for the task.
|
|
177
207
|
NetworkError: The request failed at the transport level.
|
|
178
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"]
|
|
179
214
|
"""
|
|
180
215
|
payload = {
|
|
181
216
|
"clientKey": self.client_key,
|
|
@@ -199,11 +234,14 @@ class AsyncCaptchaClient:
|
|
|
199
234
|
ApiError: The API key is invalid or the account cannot be resolved.
|
|
200
235
|
NetworkError: The request failed at the transport level.
|
|
201
236
|
CaptchaTimeoutError: The HTTP request timed out.
|
|
237
|
+
|
|
238
|
+
Example:
|
|
239
|
+
balance = await client.get_balance()
|
|
202
240
|
"""
|
|
203
241
|
payload = {"clientKey": self.client_key}
|
|
204
242
|
data = await self._request("getBalance", payload)
|
|
205
243
|
self._ensure_success(data)
|
|
206
|
-
return data["balance"]
|
|
244
|
+
return float(data["balance"])
|
|
207
245
|
|
|
208
246
|
async def solve(
|
|
209
247
|
self,
|
|
@@ -224,16 +262,31 @@ class AsyncCaptchaClient:
|
|
|
224
262
|
task: A task object from `captcha_solver_api.tasks`.
|
|
225
263
|
language_pool: Optional worker pool selector. Falls back to the
|
|
226
264
|
client's configured pool.
|
|
227
|
-
timeout:
|
|
228
|
-
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.
|
|
229
269
|
|
|
230
270
|
Returns:
|
|
231
|
-
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.
|
|
232
274
|
|
|
233
275
|
Raises:
|
|
234
276
|
ApiError: The API rejected the task or reported a solving error.
|
|
235
|
-
CaptchaTimeoutError:
|
|
236
|
-
|
|
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"]
|
|
237
290
|
"""
|
|
238
291
|
|
|
239
292
|
task_id = await self.create_task(task, language_pool=language_pool)
|
|
@@ -248,6 +301,9 @@ class AsyncCaptchaClient:
|
|
|
248
301
|
result = await self.get_task_result(task_id)
|
|
249
302
|
|
|
250
303
|
if result.get("status") == "ready":
|
|
251
|
-
|
|
304
|
+
solution = result["solution"]
|
|
305
|
+
if not isinstance(solution, dict):
|
|
306
|
+
raise NetworkError("API returned a ready task without a solution object")
|
|
307
|
+
return solution
|
|
252
308
|
|
|
253
309
|
raise CaptchaTimeoutError("Task solving timed out.")
|