python3-capsolver 1.0.1__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {python3_capsolver-1.0.1/src/python3_capsolver.egg-info → python3_capsolver-1.1.0}/PKG-INFO +3 -2
  2. python3_capsolver-1.1.0/src/python3_capsolver/__version__.py +1 -0
  3. python3_capsolver-1.1.0/src/python3_capsolver/control.py +431 -0
  4. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/aio_captcha_instrument.py +15 -13
  5. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/base.py +4 -6
  6. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/captcha_instrument.py +75 -2
  7. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/const.py +0 -6
  8. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/enum.py +2 -0
  9. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/sio_captcha_instrument.py +8 -8
  10. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/image_to_text.py +6 -38
  11. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/vision_engine.py +4 -35
  12. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0/src/python3_capsolver.egg-info}/PKG-INFO +3 -2
  13. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_image_to_text.py +3 -2
  14. python3_capsolver-1.0.1/src/python3_capsolver/__version__.py +0 -1
  15. python3_capsolver-1.0.1/src/python3_capsolver/control.py +0 -68
  16. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/LICENSE +0 -0
  17. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/MANIFEST.in +0 -0
  18. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/README.md +0 -0
  19. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/pyproject.toml +0 -0
  20. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/setup.cfg +0 -0
  21. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/__init__.py +0 -0
  22. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/aws_waf.py +0 -0
  23. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/cloudflare.py +0 -0
  24. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/__init__.py +0 -0
  25. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/context_instr.py +0 -0
  26. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/serializer.py +0 -0
  27. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/core/utils.py +0 -0
  28. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/datadome_slider.py +0 -0
  29. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/friendly_captcha.py +0 -0
  30. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/gee_test.py +0 -0
  31. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/mt_captcha.py +0 -0
  32. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/recaptcha.py +0 -0
  33. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver/yandex.py +0 -0
  34. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver.egg-info/SOURCES.txt +0 -0
  35. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver.egg-info/dependency_links.txt +0 -0
  36. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver.egg-info/requires.txt +0 -0
  37. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/src/python3_capsolver.egg-info/top_level.txt +0 -0
  38. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_aws_waf.py +0 -0
  39. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_cloudflare.py +0 -0
  40. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_control.py +0 -0
  41. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_core.py +0 -0
  42. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_datadome.py +0 -0
  43. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_friendly.py +0 -0
  44. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_gee_test.py +0 -0
  45. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_instrument.py +0 -0
  46. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_mt_captcha.py +0 -0
  47. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_recaptcha.py +0 -0
  48. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_vision_engine.py +0 -0
  49. {python3_capsolver-1.0.1 → python3_capsolver-1.1.0}/tests/test_yandex.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: python3-capsolver
3
- Version: 1.0.1
3
+ Version: 1.1.0
4
4
  Summary: Python 3.8+ Capsolver library with AIO module.
5
5
  Author-email: AndreiDrang <python-captcha@pm.me>
6
6
  License: MIT License
@@ -32,6 +32,7 @@ Requires-Dist: requests>=2.21.0
32
32
  Requires-Dist: aiohttp>=3.9.2
33
33
  Requires-Dist: msgspec<0.20,>=0.18
34
34
  Requires-Dist: tenacity<10,>=8
35
+ Dynamic: license-file
35
36
 
36
37
  # python3-capsolver
37
38
 
@@ -0,0 +1 @@
1
+ __version__ = "1.1.0"
@@ -0,0 +1,431 @@
1
+ from typing import Dict
2
+
3
+ from .core.base import CaptchaParams
4
+ from .core.enum import CaptchaTypeEnm, EndpointPostfixEnm
5
+ from .core.aio_captcha_instrument import AIOCaptchaInstrument
6
+ from .core.sio_captcha_instrument import SIOCaptchaInstrument
7
+
8
+ __all__ = ("Control",)
9
+
10
+
11
+ class Control(CaptchaParams):
12
+ """
13
+ The class is used to work with Capsolver control methods.
14
+
15
+ Args:
16
+ api_key: Capsolver API key
17
+
18
+ Notes:
19
+ https://docs.capsolver.com/en/guide/api-getbalance/
20
+
21
+ https://docs.capsolver.com/en/guide/api-gettaskresult/
22
+
23
+ https://docs.capsolver.com/en/guide/api-createtask/
24
+
25
+ https://docs.capsolver.com/en/guide/api-getToken/
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ api_key: str,
31
+ ):
32
+ super().__init__(api_key=api_key, captcha_type=CaptchaTypeEnm.Control)
33
+
34
+ def get_balance(self) -> dict:
35
+ """
36
+ Synchronous method to view the balance
37
+
38
+ Examples:
39
+ >>> from python3_capsolver.control import Control
40
+ >>> Control(api_key="CAI-1324...").get_balance()
41
+ {'balance': 48.6361, 'errorId': 0, 'packages': []}
42
+
43
+ Returns:
44
+ Dict with full server response
45
+
46
+ Notes:
47
+ Check class docstring for more info
48
+ """
49
+ self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
50
+ return self._captcha_handling_instrument.send_post_request(
51
+ session=self._captcha_handling_instrument.session,
52
+ url_postfix=EndpointPostfixEnm.GET_BALANCE,
53
+ payload={"clientKey": self.create_task_payload.clientKey},
54
+ )
55
+
56
+ async def aio_get_balance(self) -> dict:
57
+ """
58
+ Asynchronous method to view the balance
59
+
60
+ Examples:
61
+ >>> import asyncio
62
+ >>> from python3_capsolver.control import Control
63
+ >>> asyncio.run(Control(api_key="CAI-1324...").aio_get_balance())
64
+ {'balance': 48.6361, 'errorId': 0, 'packages': []}
65
+
66
+ Returns:
67
+ Dict with full server response
68
+
69
+ Notes:
70
+ Check class docstring for more info
71
+ """
72
+ return await AIOCaptchaInstrument.send_post_request(
73
+ url_postfix=EndpointPostfixEnm.GET_BALANCE,
74
+ payload={"clientKey": self.create_task_payload.clientKey},
75
+ )
76
+
77
+ def create_task(self, task_payload: Dict) -> dict:
78
+ """
79
+ Synchronous method to send custom ``createTask`` request.
80
+
81
+ This is the custom analog for prepared captcha solving classes.
82
+ With this method u can create task with custom type and get
83
+ response with task solution or task ID (depends on task type).
84
+ The main difference with ``captcha_handler`` methods
85
+ - there is no retries logic and other sugar.
86
+
87
+ Args:
88
+ task_payload: Some additional parameters that will be used in creating the task
89
+ and will be passed to the payload under ``task`` key.
90
+ Like ``websiteURL``, ``image``, ``proxyPassword``, ``websiteKey`` and etc.
91
+ more info in service docs
92
+
93
+ Examples:
94
+ >>> from python3_capsolver.control import Control
95
+ >>> Control(api_key="CAI-1324...").get_task_result(
96
+ ... task_payload={
97
+ ... "type": "VisionEngine",
98
+ ... "image": "base64_image_body",
99
+ ... "question": "click on the object",
100
+ ... "module": "space_detection",
101
+ ... }
102
+ ... )
103
+ {
104
+ "errorId": 0,
105
+ "errorCode":"None",
106
+ "errorDescription":"None",
107
+ "taskId": "db0a3153-xxxx",
108
+ "status":"ready",
109
+ "solution": {
110
+ "userAgent": "xxx",
111
+ "gRecaptchaResponse": "03AGdBq25SxXT-pmSeBXjzScW-xxxx"
112
+ },
113
+ }
114
+
115
+ Returns:
116
+ Dict with full server response
117
+
118
+ Notes:
119
+ https://docs.capsolver.com/en/guide/api-createtask/
120
+ """
121
+ self.task_params.update(task_payload)
122
+ self.create_task_payload.task = self.task_params
123
+ self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
124
+ return self._captcha_handling_instrument.send_post_request(
125
+ session=self._captcha_handling_instrument.session,
126
+ url_postfix=EndpointPostfixEnm.CREATE_TASK,
127
+ payload=self.create_task_payload.to_dict(),
128
+ )
129
+
130
+ async def aio_create_task(self, task_payload: Dict) -> dict:
131
+ """
132
+ Asynchronous method to send custom ``createTask`` request.
133
+
134
+ This is the custom analog for prepared captcha solving classes.
135
+ With this method u can create task with custom type and get
136
+ response with task solution or task ID (depends on task type).
137
+ The main difference with ``captcha_handler`` methods
138
+ - there is no retries logic and other sugar.
139
+
140
+ Args:
141
+ task_payload: Some additional parameters that will be used in creating the task
142
+ and will be passed to the payload under ``task`` key.
143
+ Like ``websiteURL``, ``image``, ``proxyPassword``, ``websiteKey`` and etc.
144
+ more info in service docs
145
+
146
+ Examples:
147
+ >>> import asyncio
148
+ >>> from python3_capsolver.control import Control
149
+ >>> asyncio.run(Control(api_key="CAI-1324...")
150
+ ... .aio_create_task(
151
+ ... task_payload={
152
+ ... "type": "VisionEngine",
153
+ ... "image": "base64_image_body",
154
+ ... "question": "click on the unique object",
155
+ ... "module": "space_detection",
156
+ ... }
157
+ ... ))
158
+ {
159
+ "errorId": 0,
160
+ "errorCode":"None",
161
+ "errorDescription":"None",
162
+ "taskId": "db0a3153-xxxx",
163
+ "status":"ready",
164
+ "solution": {
165
+ "userAgent": "xxx",
166
+ "gRecaptchaResponse": "03AGdBq25SxXT-pmSeBXjzScW-xxxx"
167
+ },
168
+ }
169
+
170
+ Returns:
171
+ Dict with full server response
172
+
173
+ Notes:
174
+ https://docs.capsolver.com/en/guide/api-createtask/
175
+ """
176
+ self.task_params.update(task_payload)
177
+ self.create_task_payload.task = self.task_params
178
+ return await AIOCaptchaInstrument.send_post_request(
179
+ url_postfix=EndpointPostfixEnm.CREATE_TASK,
180
+ payload=self.create_task_payload.to_dict(),
181
+ )
182
+
183
+ def get_task_result(self, task_id: str) -> dict:
184
+ """
185
+ Synchronous method to send ``getTaskResult`` request
186
+
187
+ Args:
188
+ task_id: Task ID
189
+
190
+ Examples:
191
+ >>> from python3_capsolver.control import Control
192
+ >>> Control(api_key="CAI-1324...").get_task_result(task_id="db0a3153-xxxx")
193
+ {
194
+ "errorId": 0,
195
+ "errorCode":"None",
196
+ "errorDescription":"None",
197
+ "taskId": "db0a3153-xxxx",
198
+ "status":"ready",
199
+ "solution": {
200
+ "userAgent": "xxx",
201
+ "gRecaptchaResponse": "03AGdBq25SxXT-pmSeBXjzScW-xxxx"
202
+ },
203
+ }
204
+
205
+ Returns:
206
+ Dict with full server response
207
+
208
+ Notes:
209
+ https://docs.capsolver.com/en/guide/api-gettaskresult/
210
+ """
211
+ self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
212
+ return self._captcha_handling_instrument.send_post_request(
213
+ session=self._captcha_handling_instrument.session,
214
+ url_postfix=EndpointPostfixEnm.GET_TASK_RESULT,
215
+ payload={"clientKey": self.create_task_payload.clientKey, "taskId": task_id},
216
+ )
217
+
218
+ async def aio_get_task_result(self, task_id: str) -> dict:
219
+ """
220
+ Synchronous method to send ``getTaskResult`` request
221
+
222
+ Args:
223
+ task_id: Task ID
224
+
225
+ Examples:
226
+ >>> import asyncio
227
+ >>> from python3_capsolver.control import Control
228
+ >>> asyncio.run(Control(api_key="CAI-1324...")
229
+ ... .aio_get_task_result(task_id="db0a3153-xxxx"))
230
+ {
231
+ "errorId": 0,
232
+ "errorCode":"None",
233
+ "errorDescription":"None",
234
+ "taskId": "db0a3153-xxxx",
235
+ "status":"ready",
236
+ "solution": {
237
+ "userAgent": "xxx",
238
+ "gRecaptchaResponse": "03AGdBq25SxXT-pmSeBXjzScW-xxxx"
239
+ },
240
+ }
241
+
242
+ Returns:
243
+ Dict with full server response
244
+
245
+ Notes:
246
+ https://docs.capsolver.com/en/guide/api-gettaskresult/
247
+ """
248
+ return await AIOCaptchaInstrument.send_post_request(
249
+ url_postfix=EndpointPostfixEnm.GET_TASK_RESULT,
250
+ payload={"clientKey": self.create_task_payload.clientKey, "taskId": task_id},
251
+ )
252
+
253
+ def get_token(self, task_payload: Dict) -> dict:
254
+ """
255
+ Synchronous method to send custom ``getToken`` request.
256
+
257
+ Args:
258
+ task_payload: Some additional parameters that will be used in creating the task
259
+ and will be passed to the payload under ``task`` key.
260
+ Like ``websiteURL``, ``image``, ``proxyPassword``, ``websiteKey`` and etc.
261
+ more info in service docs
262
+
263
+ Examples:
264
+ >>> from python3_capsolver.control import Control
265
+ >>> Control(api_key="CAI-1324...").get_token(
266
+ ... task_payload={
267
+ ... "type": "ReCaptchaV3TaskProxyLess",
268
+ ... "websiteURL": "https://demo.com/",
269
+ ... "websiteKey": "6LcpsXsnAAAbbAcxxxx"
270
+ ... }
271
+ ... )
272
+ {
273
+ "errorId": 0,
274
+ "errorCode":"None",
275
+ "errorDescription":"None",
276
+ "taskId": "db0a3153-xxxx",
277
+ "status":"ready",
278
+ "solution": {
279
+ "gRecaptchaResponse": "03AGdBq25SxXT-pmSeBXjzScW-xxxx"
280
+ },
281
+ }
282
+
283
+ Returns:
284
+ Dict with full server response
285
+
286
+ Notes:
287
+ https://docs.capsolver.com/en/guide/api-getToken/
288
+ """
289
+ self.task_params.update(task_payload)
290
+ self.create_task_payload.task = self.task_params
291
+ self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
292
+ return self._captcha_handling_instrument.send_post_request(
293
+ session=self._captcha_handling_instrument.session,
294
+ url_postfix=EndpointPostfixEnm.GET_TOKEN,
295
+ payload=self.create_task_payload.to_dict(),
296
+ )
297
+
298
+ async def aio_get_token(self, task_payload: Dict) -> dict:
299
+ """
300
+ Asynchronous method to send custom ``getToken`` request.
301
+
302
+ Args:
303
+ task_payload: Some additional parameters that will be used in creating the task
304
+ and will be passed to the payload under ``task`` key.
305
+ Like ``websiteURL``, ``image``, ``proxyPassword``, ``websiteKey`` and etc.
306
+ more info in service docs
307
+
308
+ Examples:
309
+ >>> import asyncio
310
+ >>> from python3_capsolver.control import Control
311
+ >>> asyncio.run(Control(api_key="CAI-1324...")
312
+ ... .aio_get_token(
313
+ ... task_payload={
314
+ ... "type": "ReCaptchaV3TaskProxyLess",
315
+ ... "websiteURL": "https://demo.com/",
316
+ ... "websiteKey": "6LcpsXsnAAAbbAcxxxx"
317
+ ... }
318
+ ... ))
319
+ {
320
+ "errorId": 0,
321
+ "errorCode":"None",
322
+ "errorDescription":"None",
323
+ "taskId": "db0a3153-xxxx",
324
+ "status":"ready",
325
+ "solution": {
326
+ "gRecaptchaResponse": "03AGdBq25SxXT-pmSeBXjzScW-xxxx"
327
+ },
328
+ }
329
+
330
+ Returns:
331
+ Dict with full server response
332
+
333
+ Notes:
334
+ https://docs.capsolver.com/en/guide/api-getToken/
335
+ """
336
+ self.task_params.update(task_payload)
337
+ self.create_task_payload.task = self.task_params
338
+ return await AIOCaptchaInstrument.send_post_request(
339
+ url_postfix=EndpointPostfixEnm.GET_TOKEN,
340
+ payload=self.create_task_payload.to_dict(),
341
+ )
342
+
343
+ def feedback_task(self, task_id: str, result_payload: Dict) -> dict:
344
+ """
345
+ Synchronous method to send custom ``feedbackTask`` request.
346
+
347
+ Args:
348
+ task_id: Task ID to report
349
+ result_payload: Some additional parameters that will be used in creating the task
350
+ and will be passed to the payload under ``result`` key.
351
+ Like ``invalid``, ``code``, ``message`` and etc.
352
+ more info in service docs
353
+
354
+ Examples:
355
+ >>> from python3_capsolver.control import Control
356
+ >>> Control(api_key="CAI-1324...").feedback_task(
357
+ ... task_id="db0a3153-xxxx",
358
+ ... result_payload={
359
+ ... "invalid": True,
360
+ ... "code": 1001,
361
+ ... "message": "invalid token"
362
+ ... }
363
+ ... )
364
+ {
365
+ "errorId": 0,
366
+ "errorCode":"None",
367
+ "errorDescription":"None",
368
+ "message": "okay"
369
+ }
370
+
371
+ Returns:
372
+ Dict with full server response
373
+
374
+ Notes:
375
+ https://docs.capsolver.com/en/guide/api-feedback/
376
+ """
377
+ self.task_params.update(result_payload)
378
+ dict_payload = self.create_task_payload.to_dict()
379
+ dict_payload.update({"result": self.task_params, "taskId": task_id})
380
+
381
+ self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
382
+ return self._captcha_handling_instrument.send_post_request(
383
+ session=self._captcha_handling_instrument.session,
384
+ url_postfix=EndpointPostfixEnm.GET_TOKEN,
385
+ payload=dict_payload,
386
+ )
387
+
388
+ async def aio_feedback_task(self, task_id: str, result_payload: Dict) -> dict:
389
+ """
390
+ Asynchronous method to send custom ``feedbackTask`` request.
391
+
392
+ Args:
393
+ task_id: Task ID to report
394
+ result_payload: Some additional parameters that will be used in creating the task
395
+ and will be passed to the payload under ``result`` key.
396
+ Like ``invalid``, ``code``, ``message`` and etc.
397
+ more info in service docs
398
+
399
+ Examples:
400
+ >>> import asyncio
401
+ >>> from python3_capsolver.control import Control
402
+ >>> asyncio.run(Control(api_key="CAI-1324...")
403
+ ... .aio_feedback_task(
404
+ ... task_id="db0a3153-xxxx",
405
+ ... result_payload={
406
+ ... "invalid": True,
407
+ ... "code": 1001,
408
+ ... "message": "invalid token"
409
+ ... }
410
+ ... ))
411
+ {
412
+ "errorId": 0,
413
+ "errorCode":"None",
414
+ "errorDescription":"None",
415
+ "message": "okay"
416
+ }
417
+
418
+ Returns:
419
+ Dict with full server response
420
+
421
+ Notes:
422
+ https://docs.capsolver.com/en/guide/api-feedback/
423
+ """
424
+ self.task_params.update(result_payload)
425
+ dict_payload = self.create_task_payload.to_dict()
426
+ dict_payload.update({"result": self.task_params, "taskId": task_id})
427
+
428
+ return await AIOCaptchaInstrument.send_post_request(
429
+ url_postfix=EndpointPostfixEnm.GET_TOKEN,
430
+ payload=dict_payload,
431
+ )
@@ -6,15 +6,15 @@ from urllib import parse
6
6
  import aiohttp
7
7
 
8
8
  from .enum import ResponseStatusEnm, EndpointPostfixEnm
9
- from .const import REQUEST_URL, VALID_STATUS_CODES, GET_BALANCE_POSTFIX
9
+ from .const import REQUEST_URL, VALID_STATUS_CODES
10
10
  from .utils import attempts_generator
11
11
  from .serializer import CaptchaResponseSer
12
- from .captcha_instrument import CaptchaInstrument
12
+ from .captcha_instrument import CaptchaInstrumentBase
13
13
 
14
14
  __all__ = ("AIOCaptchaInstrument",)
15
15
 
16
16
 
17
- class AIOCaptchaInstrument(CaptchaInstrument):
17
+ class AIOCaptchaInstrument(CaptchaInstrumentBase):
18
18
  """
19
19
  Instrument for working with async captcha
20
20
  """
@@ -29,9 +29,9 @@ class AIOCaptchaInstrument(CaptchaInstrument):
29
29
  self.created_task_data = CaptchaResponseSer(**await self.__create_task())
30
30
 
31
31
  # if task created and already ready - return result
32
- if self.created_task_data.errorId == 0 and self.created_task_data.status == ResponseStatusEnm.Processing.value:
32
+ if self.created_task_data.errorId == 0:
33
33
  return (await self.__get_result()).to_dict()
34
- elif self.created_task_data.errorId != 0:
34
+ else:
35
35
  self.created_task_data.status = ResponseStatusEnm.Failed
36
36
 
37
37
  return self.created_task_data.to_dict()
@@ -84,22 +84,24 @@ class AIOCaptchaInstrument(CaptchaInstrument):
84
84
  # if captcha just created or in processing now - wait
85
85
  await asyncio.sleep(self.captcha_params.sleep_time)
86
86
 
87
- # default response if server is silent
88
- self.result.errorId = 1
89
- self.result.errorCode = self.CAPTCHA_UNSOLVABLE
90
- self.result.errorDescription = "Captcha not recognized"
91
- self.result.taskId = self.created_task_data.taskId
92
- self.result.status = ResponseStatusEnm.Failed
87
+ # default response if server is silent
88
+ self.result.errorId = 1
89
+ self.result.errorCode = self.CAPTCHA_UNSOLVABLE
90
+ self.result.errorDescription = self.CAPTCHA_UNSOLVABLE_DESCRIPTION
91
+ self.result.taskId = self.created_task_data.taskId
92
+ self.result.status = ResponseStatusEnm.Failed
93
93
 
94
94
  @staticmethod
95
- async def send_post_request(payload: Optional[dict] = None, url_postfix: str = GET_BALANCE_POSTFIX) -> dict:
95
+ async def send_post_request(
96
+ payload: Optional[dict] = None, url_postfix: EndpointPostfixEnm = EndpointPostfixEnm.GET_BALANCE
97
+ ) -> dict:
96
98
  """
97
99
  Function send ASYNC request to service and wait for result
98
100
  """
99
101
 
100
102
  async with aiohttp.ClientSession() as session:
101
103
  try:
102
- async with session.post(parse.urljoin(REQUEST_URL, url_postfix), json=payload) as resp:
104
+ async with session.post(parse.urljoin(REQUEST_URL, url_postfix.value), json=payload) as resp:
103
105
  if resp.status == 200:
104
106
  return await resp.json()
105
107
  else:
@@ -1,12 +1,10 @@
1
1
  from typing import Any, Dict
2
2
 
3
- from python3_capsolver.core.enum import CaptchaTypeEnm
4
- from python3_capsolver.core.serializer import TaskSer
5
-
3
+ from .enum import CaptchaTypeEnm
6
4
  from .const import REQUEST_URL
7
- from .serializer import RequestCreateTaskSer, RequestGetTaskResultSer
5
+ from .serializer import TaskSer, RequestCreateTaskSer, RequestGetTaskResultSer
8
6
  from .context_instr import AIOContextManager, SIOContextManager
9
- from .captcha_instrument import CaptchaInstrument
7
+ from .captcha_instrument import CaptchaInstrumentBase
10
8
  from .aio_captcha_instrument import AIOCaptchaInstrument
11
9
  from .sio_captcha_instrument import SIOCaptchaInstrument
12
10
 
@@ -38,7 +36,7 @@ class CaptchaParams(SIOContextManager, AIOContextManager):
38
36
  # prepare `get task result` payload
39
37
  self.get_result_params = RequestGetTaskResultSer(clientKey=api_key)
40
38
  self.request_url = request_url
41
- self._captcha_handling_instrument = CaptchaInstrument()
39
+ self._captcha_handling_instrument = CaptchaInstrumentBase()
42
40
  self.sleep_time = sleep_time
43
41
 
44
42
  def captcha_handler(self, task_payload: Dict) -> Dict[str, Any]:
@@ -13,10 +13,26 @@ from .enum import SaveFormatsEnm
13
13
  from .const import RETRIES, ASYNC_RETRIES
14
14
  from .serializer import CaptchaResponseSer
15
15
 
16
- __all__ = ("CaptchaInstrument", "FileInstrument")
16
+ __all__ = ("CaptchaInstrumentBase", "FileInstrument")
17
17
 
18
18
 
19
19
  class FileInstrument:
20
+ """
21
+ This class contains usefull methods for async and async files processing to prepare them for solving
22
+
23
+ Examples:
24
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
25
+ >>> body = FileInstrument().file_processing(captcha_file="captcha_example.jpeg")
26
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUVxxxxx
27
+
28
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
29
+ >>> body = FileInstrument().file_processing(captcha_link="https://some-url/file.jpeg")
30
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUVxxxxx
31
+
32
+ Returns:
33
+ String with decoded file data
34
+ """
35
+
20
36
  @staticmethod
21
37
  def _local_file_captcha(captcha_file: str):
22
38
  """
@@ -80,6 +96,33 @@ class FileInstrument:
80
96
  file_extension: str = "png",
81
97
  **kwargs,
82
98
  ) -> str:
99
+ """
100
+ Synchronous method for captcha image processing.
101
+ - Method can read local file and return it's as base64 string.
102
+ - Method can read file URL and return it's as base64 string.
103
+ - Method can decode base64 bytes and return it's as base64 string.
104
+
105
+ Args:
106
+ captcha_link: URL link to file. Instrument will send GET request to it and read content
107
+ captcha_file: Local file path. Instrument will read it
108
+ captcha_base64: Readed file base64 data. Instrument will decode it in ``utf-8``
109
+ save_format: This arg works only with ``captcha_link`` arg.
110
+ If ``SaveFormatsEnm.CONST`` is set - file will be loaded and saved locally.
111
+ img_clearing: This arg works only with ``captcha_link`` arg.
112
+ If ``False`` - file wil not be removed downloading and saving locally.
113
+ file_path: This arg works only with ``captcha_link`` and ``SaveFormatsEnm.CONST`` args.
114
+ In this param u can set locally path for downloaded file saving.
115
+ file_extension: This arg works only with ``file_path`` args.
116
+ In this param u MUST set file format for saving.
117
+
118
+ Examples:
119
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
120
+ >>> body = FileInstrument().file_processing(captcha_file="captcha_example.jpeg")
121
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUVxxxxx
122
+
123
+ Returns:
124
+ String with decoded file data
125
+ """
83
126
  # if a local file link is passed
84
127
  if captcha_file:
85
128
  return base64.b64encode(self._local_file_captcha(captcha_file=captcha_file)).decode("utf-8")
@@ -109,6 +152,35 @@ class FileInstrument:
109
152
  file_extension: str = "png",
110
153
  **kwargs,
111
154
  ) -> str:
155
+ """
156
+ Asynchronous method for captcha image processing.
157
+ - Method can read local file and return it's as base64 string.
158
+ - Method can read file URL and return it's as base64 string.
159
+ - Method can decode base64 bytes and return it's as base64 string.
160
+
161
+ Args:
162
+ captcha_link: URL link to file. Instrument will send GET request to it and read content
163
+ captcha_file: Local file path. Instrument will read it
164
+ captcha_base64: Readed file base64 data. Instrument will decode it in ``utf-8``
165
+ save_format: This arg works only with ``captcha_link`` arg.
166
+ If ``SaveFormatsEnm.CONST`` is set - file will be loaded and saved locally.
167
+ img_clearing: This arg works only with ``captcha_link`` arg.
168
+ If ``False`` - file wil not be removed downloading and saving locally.
169
+ file_path: This arg works only with ``captcha_link`` and ``SaveFormatsEnm.CONST`` args.
170
+ In this param u can set locally path for downloaded file saving.
171
+ file_extension: This arg works only with ``file_path`` args.
172
+ In this param u MUST set file format for saving.
173
+
174
+ Examples:
175
+ >>> import asyncio
176
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
177
+ >>> body = asyncio.run(FileInstrument()
178
+ ... .aio_file_processing(captcha_file="captcha_example.jpeg"))
179
+ /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUVxxxxx
180
+
181
+ Returns:
182
+ String with decoded file data
183
+ """
112
184
  # if a local file link is passed
113
185
  if captcha_file:
114
186
  return base64.b64encode(self._local_file_captcha(captcha_file=captcha_file)).decode("utf-8")
@@ -129,8 +201,9 @@ class FileInstrument:
129
201
  raise ValueError("No valid captcha variant is set.")
130
202
 
131
203
 
132
- class CaptchaInstrument(FileInstrument):
204
+ class CaptchaInstrumentBase:
133
205
  CAPTCHA_UNSOLVABLE = "ERROR_CAPTCHA_UNSOLVABLE"
206
+ CAPTCHA_UNSOLVABLE_DESCRIPTION = "Captcha not recognized"
134
207
  """
135
208
  Basic Captcha solving class
136
209
 
@@ -7,10 +7,7 @@ __all__ = (
7
7
  "RETRIES",
8
8
  "REQUEST_URL",
9
9
  "ASYNC_RETRIES",
10
- "GET_RESULT_POSTFIX",
11
10
  "VALID_STATUS_CODES",
12
- "GET_BALANCE_POSTFIX",
13
- "CREATE_TASK_POSTFIX",
14
11
  )
15
12
 
16
13
  urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
@@ -19,9 +16,6 @@ RETRIES = Retry(total=5, backoff_factor=0.9, status_forcelist=[500, 502, 503, 50
19
16
  ASYNC_RETRIES = AsyncRetrying(wait=wait_fixed(5), stop=stop_after_attempt(5), reraise=True)
20
17
 
21
18
  REQUEST_URL = "https://api.capsolver.com"
22
- CREATE_TASK_POSTFIX = "/createTask"
23
- GET_RESULT_POSTFIX = "/getTaskResult"
24
- GET_BALANCE_POSTFIX = "/getBalance"
25
19
  VALID_STATUS_CODES = (200, 202, 400, 401, 405)
26
20
 
27
21
  APP_ID = "3E36E3CD-7EB5-4CAF-AA15-91011E652321"
@@ -26,6 +26,8 @@ class EndpointPostfixEnm(MyEnum):
26
26
  GET_BALANCE = "getBalance"
27
27
  CREATE_TASK = "createTask"
28
28
  GET_TASK_RESULT = "getTaskResult"
29
+ GET_TOKEN = "getToken"
30
+ FEEDBACK_TASK = "feedbackTask"
29
31
 
30
32
 
31
33
  class CaptchaTypeEnm(MyEnum):
@@ -7,15 +7,15 @@ import requests
7
7
  from requests.adapters import HTTPAdapter
8
8
 
9
9
  from .enum import ResponseStatusEnm, EndpointPostfixEnm
10
- from .const import RETRIES, REQUEST_URL, VALID_STATUS_CODES, GET_BALANCE_POSTFIX
10
+ from .const import RETRIES, REQUEST_URL, VALID_STATUS_CODES
11
11
  from .utils import attempts_generator
12
12
  from .serializer import CaptchaResponseSer
13
- from .captcha_instrument import CaptchaInstrument
13
+ from .captcha_instrument import CaptchaInstrumentBase
14
14
 
15
15
  __all__ = ("SIOCaptchaInstrument",)
16
16
 
17
17
 
18
- class SIOCaptchaInstrument(CaptchaInstrument):
18
+ class SIOCaptchaInstrument(CaptchaInstrumentBase):
19
19
  """
20
20
  Instrument for working with sync captcha
21
21
  """
@@ -36,9 +36,9 @@ class SIOCaptchaInstrument(CaptchaInstrument):
36
36
  self.created_task_data = CaptchaResponseSer(**self.__create_task())
37
37
 
38
38
  # if task created and ready - return result
39
- if self.created_task_data.errorId == 0 and self.created_task_data.status == ResponseStatusEnm.Processing:
39
+ if self.created_task_data.errorId == 0:
40
40
  return self.__get_result().to_dict()
41
- elif self.created_task_data.errorId != 0:
41
+ else:
42
42
  self.created_task_data.status = ResponseStatusEnm.Failed
43
43
 
44
44
  return self.created_task_data.to_dict()
@@ -92,7 +92,7 @@ class SIOCaptchaInstrument(CaptchaInstrument):
92
92
  # default response if server is silent
93
93
  self.result.errorId = 1
94
94
  self.result.errorCode = self.CAPTCHA_UNSOLVABLE
95
- self.result.errorDescription = "Captcha not recognized"
95
+ self.result.errorDescription = self.CAPTCHA_UNSOLVABLE_DESCRIPTION
96
96
  self.result.taskId = self.created_task_data.taskId
97
97
  self.result.status = ResponseStatusEnm.Failed
98
98
 
@@ -100,13 +100,13 @@ class SIOCaptchaInstrument(CaptchaInstrument):
100
100
  def send_post_request(
101
101
  payload: Optional[dict] = None,
102
102
  session: requests.Session = requests.Session(),
103
- url_postfix: str = GET_BALANCE_POSTFIX,
103
+ url_postfix: EndpointPostfixEnm = EndpointPostfixEnm.GET_BALANCE,
104
104
  ) -> dict:
105
105
  """
106
106
  Function send SYNC request to service and wait for result
107
107
  """
108
108
  try:
109
- resp = session.post(parse.urljoin(REQUEST_URL, url_postfix), json=payload)
109
+ resp = session.post(parse.urljoin(REQUEST_URL, url_postfix.value), json=payload)
110
110
  if resp.status_code == 200:
111
111
  return resp.json()
112
112
  else:
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict
1
+ from typing import Union
2
2
 
3
3
  from .core.base import CaptchaParams
4
4
  from .core.enum import CaptchaTypeEnm
@@ -12,6 +12,7 @@ class ImageToText(CaptchaParams):
12
12
 
13
13
  Args:
14
14
  api_key: Capsolver API key
15
+ captcha_type: Captcha type name, like ``ImageToTextTask`` and etc.
15
16
  kwargs: additional params for client, like captcha waiting time
16
17
  available keys:
17
18
  - sleep_time: int - captcha solution waintig time in sec
@@ -21,7 +22,6 @@ class ImageToText(CaptchaParams):
21
22
  Examples:
22
23
  >>> from python3_capsolver.image_to_text import ImageToText
23
24
  >>> from python3_capsolver.core.captcha_instrument import FileInstrument
24
-
25
25
  >>> body = FileInstrument().file_processing(captcha_file="captcha_example.jpeg")
26
26
  >>> ImageToText(api_key="CAI-12345....").captcha_handler(
27
27
  ... task_payload={"body": body, "module": "common"}
@@ -41,7 +41,6 @@ class ImageToText(CaptchaParams):
41
41
  >>> import asyncio
42
42
  >>> from python3_capsolver.image_to_text import ImageToText
43
43
  >>> from python3_capsolver.core.captcha_instrument import FileInstrument
44
-
45
44
  >>> body = FileInstrument().file_processing(captcha_file="captcha_example.jpeg")
46
45
  >>> asyncio.run(ImageToText(api_key="CAI-12345....").aio_captcha_handler(
47
46
  ... task_payload={"body": body, "module": "common"}
@@ -61,7 +60,6 @@ class ImageToText(CaptchaParams):
61
60
 
62
61
  >>> from python3_capsolver.image_to_text import ImageToText
63
62
  >>> from python3_capsolver.core.captcha_instrument import FileInstrument
64
-
65
63
  >>> body = FileInstrument().file_processing(captcha_file="captcha_example.jpeg")
66
64
  >>> ImageToText(api_key="CAI-12345....").captcha_handler(
67
65
  ... task_payload={"body": body,
@@ -84,38 +82,8 @@ class ImageToText(CaptchaParams):
84
82
  https://docs.capsolver.com/guide/recognition/ImageToTextTask.html
85
83
  """
86
84
 
87
- def __init__(self, api_key: str, **kwargs):
88
-
89
- super().__init__(api_key=api_key, captcha_type=CaptchaTypeEnm.ImageToTextTask, **kwargs)
90
-
91
- def captcha_handler(self, task_payload: Dict) -> Dict[str, Any]:
92
- """
93
- Synchronous method for captcha solving
94
-
95
- Args:
96
- task_payload: Captcha solving `task` payload, include `body`, `module` and other fields.
97
-
98
- Returns:
99
- Dict with full server response
100
-
101
- Notes:
102
- Check class docstring for more info
103
- """
104
- task_payload.pop("type", None)
105
- return super().captcha_handler(task_payload=task_payload)
106
-
107
- async def aio_captcha_handler(self, task_payload: Dict) -> Dict[str, Any]:
108
- """
109
- Asynchronous method for captcha solving
110
-
111
- Args:
112
- task_payload: Captcha solving `task` payload, include `body`, `module` and other fields.
113
-
114
- Returns:
115
- Dict with full server response
85
+ def __init__(
86
+ self, api_key: str, captcha_type: Union[CaptchaTypeEnm, str] = CaptchaTypeEnm.ImageToTextTask, **kwargs
87
+ ):
116
88
 
117
- Notes:
118
- Check class docstring for more info
119
- """
120
- task_payload.pop("type", None)
121
- return await super().aio_captcha_handler(task_payload=task_payload)
89
+ super().__init__(api_key=api_key, captcha_type=captcha_type, **kwargs)
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict
1
+ from typing import Union
2
2
 
3
3
  from .core.base import CaptchaParams
4
4
  from .core.enum import CaptchaTypeEnm
@@ -12,6 +12,7 @@ class VisionEngine(CaptchaParams):
12
12
 
13
13
  Args:
14
14
  api_key: Capsolver API key
15
+ captcha_type: Captcha type name, like ``VisionEngine`` and etc.
15
16
  kwargs: additional params for client, like captcha waiting time
16
17
  available keys:
17
18
  - sleep_time: int - captcha solution waintig time in sec
@@ -66,37 +67,5 @@ class VisionEngine(CaptchaParams):
66
67
  https://docs.capsolver.com/en/guide/recognition/VisionEngine/
67
68
  """
68
69
 
69
- def __init__(self, api_key: str, **kwargs):
70
- super().__init__(api_key=api_key, captcha_type=CaptchaTypeEnm.VisionEngine, **kwargs)
71
-
72
- def captcha_handler(self, task_payload: Dict) -> Dict[str, Any]:
73
- """
74
- Synchronous method for captcha solving
75
-
76
- Args:
77
- task_payload: Captcha solving `task` payload, include `body`, `module` and other fields.
78
-
79
- Returns:
80
- Dict with full server response
81
-
82
- Notes:
83
- Check class docstring for more info
84
- """
85
- task_payload.pop("type", None)
86
- return super().captcha_handler(task_payload=task_payload)
87
-
88
- async def aio_captcha_handler(self, task_payload: Dict) -> Dict[str, Any]:
89
- """
90
- Asynchronous method for captcha solving
91
-
92
- Args:
93
- task_payload: Captcha solving `task` payload, include `question`, `image` and other fields.
94
-
95
- Returns:
96
- Dict with full server response
97
-
98
- Notes:
99
- Check class docstring for more info
100
- """
101
- task_payload.pop("type", None)
102
- return await super().aio_captcha_handler(task_payload=task_payload)
70
+ def __init__(self, api_key: str, captcha_type: Union[CaptchaTypeEnm, str] = CaptchaTypeEnm.VisionEngine, **kwargs):
71
+ super().__init__(api_key=api_key, captcha_type=captcha_type, **kwargs)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: python3-capsolver
3
- Version: 1.0.1
3
+ Version: 1.1.0
4
4
  Summary: Python 3.8+ Capsolver library with AIO module.
5
5
  Author-email: AndreiDrang <python-captcha@pm.me>
6
6
  License: MIT License
@@ -32,6 +32,7 @@ Requires-Dist: requests>=2.21.0
32
32
  Requires-Dist: aiohttp>=3.9.2
33
33
  Requires-Dist: msgspec<0.20,>=0.18
34
34
  Requires-Dist: tenacity<10,>=8
35
+ Dynamic: license-file
35
36
 
36
37
  # python3-capsolver
37
38
 
@@ -6,8 +6,9 @@ from python3_capsolver.core.serializer import CaptchaResponseSer
6
6
 
7
7
  class TestImageToTextBase(BaseTest):
8
8
  def test_captcha_handler_exist(self):
9
- assert "captcha_handler" in ImageToText.__dict__.keys()
10
- assert "aio_captcha_handler" in ImageToText.__dict__.keys()
9
+ instance = ImageToText(api_key=self.get_random_string(36))
10
+ assert "captcha_handler" in instance.__dir__()
11
+ assert "aio_captcha_handler" in instance.__dir__()
11
12
 
12
13
 
13
14
  class TestImageToText(BaseTest):
@@ -1 +0,0 @@
1
- __version__ = "1.0.1"
@@ -1,68 +0,0 @@
1
- from .core.base import CaptchaParams
2
- from .core.enum import CaptchaTypeEnm
3
- from .core.const import GET_BALANCE_POSTFIX
4
- from .core.aio_captcha_instrument import AIOCaptchaInstrument
5
- from .core.sio_captcha_instrument import SIOCaptchaInstrument
6
-
7
- __all__ = ("Control",)
8
-
9
-
10
- class Control(CaptchaParams):
11
- """
12
- The class is used to work with Capsolver control methods.
13
-
14
- Args:
15
- api_key: Capsolver API key
16
-
17
- Notes:
18
- https://docs.capsolver.com/en/guide/api-getbalance/
19
- """
20
-
21
- def __init__(
22
- self,
23
- api_key: str,
24
- ):
25
- super().__init__(api_key=api_key, captcha_type=CaptchaTypeEnm.Control)
26
-
27
- def get_balance(self) -> dict:
28
- """
29
- Synchronous method to view the balance
30
-
31
- Examples:
32
- >>> from python3_capsolver.control import Control
33
- >>> Control(api_key="CAI-1324...").get_balance()
34
- {'balance': 48.6361, 'errorId': 0, 'packages': []}
35
-
36
- Returns:
37
- Dict with full server response
38
-
39
- Notes:
40
- Check class docstring for more info
41
- """
42
- self._captcha_handling_instrument = SIOCaptchaInstrument(captcha_params=self)
43
- return self._captcha_handling_instrument.send_post_request(
44
- session=self._captcha_handling_instrument.session,
45
- url_postfix=GET_BALANCE_POSTFIX,
46
- payload={"clientKey": self.create_task_payload.clientKey},
47
- )
48
-
49
- async def aio_get_balance(self) -> dict:
50
- """
51
- Asynchronous method to view the balance
52
-
53
- Examples:
54
- >>> import asyncio
55
- >>> from python3_capsolver.control import Control
56
- >>> asyncio.run(Control(api_key="CAI-1324...").aio_get_balance())
57
- {'balance': 48.6361, 'errorId': 0, 'packages': []}
58
-
59
- Returns:
60
- Dict with full server response
61
-
62
- Notes:
63
- Check class docstring for more info
64
- """
65
- return await AIOCaptchaInstrument.send_post_request(
66
- url_postfix=GET_BALANCE_POSTFIX,
67
- payload={"clientKey": self.create_task_payload.clientKey},
68
- )