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.
Files changed (20) hide show
  1. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/PKG-INFO +27 -1
  2. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/README.md +26 -0
  3. captcha_solver_api-1.0.4/captcha_solver_api/_version.py +1 -0
  4. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/async_client.py +65 -14
  5. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/client.py +58 -11
  6. captcha_solver_api-1.0.4/captcha_solver_api/exceptions.py +61 -0
  7. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/tasks.py +216 -0
  8. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/PKG-INFO +27 -1
  9. captcha_solver_api-1.0.3/captcha_solver_api/_version.py +0 -1
  10. captcha_solver_api-1.0.3/captcha_solver_api/exceptions.py +0 -33
  11. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/LICENSE.md +0 -0
  12. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/__init__.py +0 -0
  13. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api/py.typed +0 -0
  14. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/SOURCES.txt +0 -0
  15. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/dependency_links.txt +0 -0
  16. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/requires.txt +0 -0
  17. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/captcha_solver_api.egg-info/top_level.txt +0 -0
  18. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/pyproject.toml +0 -0
  19. {captcha_solver_api-1.0.3 → captcha_solver_api-1.0.4}/setup.cfg +0 -0
  20. {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
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
- result = await client.solve(task)
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 max seconds `solve()` waits for a solution before
54
- raising `CaptchaTimeoutError`. Can be overridden per call.
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`; ready responses also contain a
175
- solution dictionary.
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: Maximum polling time for this call, in seconds. Overrides
230
- the client's default timeout.
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 dictionary once the task status becomes `"ready"`.
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: No solution was ready before the deadline.
238
- NetworkError: A request failed at the transport level.
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
- Main client for interacting with the Captcha Solver API.
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
- client = CaptchaClient("YOUR_API_KEY")
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 max seconds `solve()` waits for a solution before
43
- raising `CaptchaTimeoutError`. Can be overridden per call.
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: Overrides the client's default polling timeout for this call
209
- only (useful for captcha types that reliably take longer, e.g.
210
- classic reCAPTCHA v2), in seconds.
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: No solution was ready before the deadline.
220
- NetworkError: A request failed at the transport level.
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
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."""