python3-capsolver 0.9.1__py3-none-any.whl → 1.0.0a0__py3-none-any.whl

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 (34) hide show
  1. python3_capsolver/__init__.py +1 -0
  2. python3_capsolver/__version__.py +1 -1
  3. python3_capsolver/aws_waf.py +122 -95
  4. python3_capsolver/cloudflare.py +77 -96
  5. python3_capsolver/control.py +31 -29
  6. python3_capsolver/core/aio_captcha_instrument.py +109 -0
  7. python3_capsolver/core/base.py +52 -198
  8. python3_capsolver/core/captcha_instrument.py +145 -0
  9. python3_capsolver/core/const.py +27 -0
  10. python3_capsolver/core/context_instr.py +25 -0
  11. python3_capsolver/core/enum.py +21 -76
  12. python3_capsolver/core/serializer.py +36 -130
  13. python3_capsolver/core/sio_captcha_instrument.py +116 -0
  14. python3_capsolver/core/{config.py → utils.py} +1 -10
  15. python3_capsolver/datadome_slider.py +34 -84
  16. python3_capsolver/friendly_captcha.py +69 -0
  17. python3_capsolver/gee_test.py +58 -90
  18. python3_capsolver/image_to_text.py +86 -116
  19. python3_capsolver/mt_captcha.py +32 -108
  20. python3_capsolver/recaptcha.py +65 -129
  21. python3_capsolver/vision_engine.py +102 -0
  22. python3_capsolver/yandex.py +53 -0
  23. python3_capsolver-1.0.0a0.dist-info/LICENSE +21 -0
  24. {python3_capsolver-0.9.1.dist-info → python3_capsolver-1.0.0a0.dist-info}/METADATA +26 -51
  25. python3_capsolver-1.0.0a0.dist-info/RECORD +28 -0
  26. {python3_capsolver-0.9.1.dist-info → python3_capsolver-1.0.0a0.dist-info}/WHEEL +1 -1
  27. python3_capsolver/akamai.py +0 -192
  28. python3_capsolver/binance.py +0 -112
  29. python3_capsolver/cyber_si_ara.py +0 -128
  30. python3_capsolver/fun_captcha.py +0 -251
  31. python3_capsolver/hcaptcha.py +0 -197
  32. python3_capsolver/imperva.py +0 -120
  33. python3_capsolver-0.9.1.dist-info/RECORD +0 -25
  34. {python3_capsolver-0.9.1.dist-info → python3_capsolver-1.0.0a0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1 @@
1
+ from python3_capsolver.__version__ import __version__ # noqa
@@ -1 +1 @@
1
- __version__ = "0.9.1"
1
+ __version__ = "1.0.0a"
@@ -1,111 +1,138 @@
1
1
  from typing import Union
2
2
 
3
- from python3_capsolver.core.base import BaseCaptcha
4
- from python3_capsolver.core.enum import AntiAwsWafTaskTypeEnm
5
- from python3_capsolver.core.serializer import CaptchaResponseSer, WebsiteDataOptionsSer
3
+ from .core.base import CaptchaParams
4
+ from .core.enum import CaptchaTypeEnm
6
5
 
6
+ __all__ = ("AwsWaf",)
7
7
 
8
- class AwsWaf(BaseCaptcha):
8
+
9
+ class AwsWaf(CaptchaParams):
9
10
  """
10
- The class is used to work with Capsolver AwsWaf methods.
11
+ The class is used to work with Capsolver AwsWaf methods:
12
+ - AntiAwsWafTask
13
+ - AntiAwsWafTaskProxyLess
14
+ - AwsWafClassification
11
15
 
12
16
  Args:
13
17
  api_key: Capsolver API key
14
18
  captcha_type: Captcha type name, like ``AntiAwsWafTask`` and etc.
15
- websiteURL: Address of a webpage with AwsWaf
16
-
17
- Examples:
18
- >>> AwsWaf(api_key="CAI-BA9XXXXXXXXXXXXX2702E010",
19
- ... captcha_type='AntiAwsWafTaskProxyLess',
20
- ... websiteURL="https://efw47fpad9.execute-api.us-east-1.amazonaws.com/latest",
21
- ... ).captcha_handler()
22
- CaptchaResponseSer(errorId=0,
23
- errorCode=None,
24
- errorDescription=None,
25
- taskId='73bdcd28-6c77-4414-8....',
26
- status=<ResponseStatusEnm.Ready: 'ready'>,
27
- solution={'cookie': '44795sds...'}
28
- )
29
-
30
- >>> AwsWaf(api_key="CAI-BA9XXXXXXXXXXXXX2702E010",
31
- ... captcha_type=AntiAwsWafTaskTypeEnm.AntiAwsWafTaskProxyLess,
32
- ... websiteURL="https://efw47fpad9.execute-api.us-east-1.amazonaws.com/latest",
33
- ... ).captcha_handler()
34
- CaptchaResponseSer(errorId=0,
35
- errorCode=None,
36
- errorDescription=None,
37
- taskId='73bdcd28-6c77-4414-8....',
38
- status=<ResponseStatusEnm.Ready: 'ready'>,
39
- solution={'cookie': '44795sds...'}
40
- )
19
+ kwargs: additional params for client, like captcha waiting time
20
+ available keys:
21
+ - sleep_time: int - captcha solution waintig time in sec
22
+ - request_url: str - API address for sending requests,
23
+ else official will be used
41
24
 
42
- >>> AwsWaf(api_key="CAI-BA9XXXXXXXXXXXXX2702E010",
43
- ... captcha_type=AntiAwsWafTaskTypeEnm.AntiAwsWafTask,
44
- ... websiteURL="https://efw47fpad9.execute-api.us-east-1.amazonaws.com/latest",
45
- ... proxy="socks5:192.191.100.10:4780:user:pwd",
46
- ... awsKey="some key"
47
- ... ).captcha_handler()
48
- CaptchaResponseSer(errorId=0,
49
- errorCode=None,
50
- errorDescription=None,
51
- taskId="87f149f4-1c....",
52
- status=<ResponseStatusEnm.Ready: 'ready'>,
53
- solution={'cookie': '44795sds...'}
54
- )
55
25
 
56
- >>> await AwsWaf(api_key="CAI-BA9650D2B9C2786B21120D512702E010",
57
- ... captcha_type=AntiAwsWafTaskTypeEnm.AntiAwsWafTaskProxyLess,
58
- ... websiteURL="https://efw47fpad9.execute-api.us-east-1.amazonaws.com/latest",
59
- ... ).aio_captcha_handler()
60
- CaptchaResponseSer(errorId=0,
61
- errorCode=None,
62
- errorDescription=None,
63
- taskId='73bdcd28-6c77-4414-8....',
64
- status=<ResponseStatusEnm.Ready: 'ready'>,
65
- solution={'cookie': '44795sds...'}
66
- )
67
-
68
- Returns:
69
- CaptchaResponseSer model with full server response
26
+ Examples:
27
+ >>> from python3_capsolver.aws_waf import AwsWaf
28
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
29
+ >>> image = FileInstrument().file_processing(captcha_file="waf_captcha.png")
30
+ >>> AwsWaf(api_key="CAP-XXXXX",
31
+ ... captcha_type=CaptchaTypeEnm.AwsWafClassification
32
+ ... ).captcha_handler(task_payload={
33
+ ... "images": [image],
34
+ ... "question": "some question",
35
+ ... "websiteURL": "https://xxxx.com",
36
+ ... })
37
+ {
38
+ "errorId":0,
39
+ "errorCode":"None",
40
+ "errorDescription":"None",
41
+ "taskId":"db0a3153-621d-4f5e-8554-a1c032597ee7",
42
+ "status":"ready",
43
+ "solution":{
44
+ //carcity point
45
+ "box": [
46
+ 116.7,
47
+ 164.1
48
+ ],
49
+ // grid type, objects means the image index that matches the question
50
+ "objects": [0, 1, 3, 4, 6],
51
+ //if question include `bifurcatedzoo`
52
+ "distance": 500
53
+ }
54
+ }
55
+
56
+
57
+ >>> import asyncio
58
+ >>> from python3_capsolver.aws_waf import AwsWaf
59
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
60
+ >>> image = FileInstrument().file_processing(captcha_file="waf_captcha.png")
61
+ >>> asyncio.run(AwsWaf(api_key="CAP-XXXXX",
62
+ ... captcha_type=CaptchaTypeEnm.AwsWafClassification
63
+ ... ).aio_captcha_handler(task_payload={
64
+ ... "images": [image],
65
+ ... "question": "some question",
66
+ ... "websiteURL": "https://xxxx.com",
67
+ ... }))
68
+ {
69
+ "errorId":0,
70
+ "errorCode":"None",
71
+ "errorDescription":"None",
72
+ "taskId":"db0a3153-621d-4f5e-8554-a1c032597ee7",
73
+ "status":"ready",
74
+ "solution":{
75
+ //carcity point
76
+ "box": [
77
+ 116.7,
78
+ 164.1
79
+ ],
80
+ // grid type, objects means the image index that matches the question
81
+ "objects": [0, 1, 3, 4, 6],
82
+ //if question include `bifurcatedzoo`
83
+ "distance": 500
84
+ }
85
+ }
86
+
87
+ >>> from python3_capsolver.aws_waf import AwsWaf
88
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
89
+ >>> image = FileInstrument().file_processing(captcha_file="waf_captcha.png")
90
+ >>> AwsWaf(api_key="CAP-XXXXX",
91
+ ... captcha_type=CaptchaTypeEnm.AntiAwsWafTaskProxyLess
92
+ ... ).captcha_handler(task_payload={
93
+ ... "websiteURL": "https://xxxxxx/latest",
94
+ ... "awsKey": "AQIDAHjcYu/GjX+QlghicBg......shMIKvZswZemrVVqA==",
95
+ ... "awsChallengeJS": "https://xxxxx/challenge.js",
96
+ ... })
97
+ {
98
+ "errorId":0,
99
+ "errorCode":"None",
100
+ "errorDescription":"None",
101
+ "taskId":"db0a3153-621d-4f5e-8554-a1c032597ee7",
102
+ "status":"ready",
103
+ "solution":{
104
+ "cookie": "223d1f60-xxxxxxxx"
105
+ }
106
+ }
107
+
108
+ >>> from python3_capsolver.aws_waf import AwsWaf
109
+ >>> from python3_capsolver.core.captcha_instrument import FileInstrument
110
+ >>> image = FileInstrument().file_processing(captcha_file="waf_captcha.png")
111
+ >>> AwsWaf(api_key="CAP-XXXXX",
112
+ ... captcha_type=CaptchaTypeEnm.AntiAwsWafTask
113
+ ... ).captcha_handler(task_payload={
114
+ ... "websiteURL": "https://xxxxxx/latest",
115
+ ... "awsKey": "AQIDAHjcYu/GjX+QlghicBg......shMIKvZswZemrVVqA==",
116
+ ... "awsChallengeJS": "https://xxxxx/challenge.js",
117
+ ... "proxy": "ip:port:user:pass"
118
+ ... })
119
+ {
120
+ "errorId":0,
121
+ "errorCode":"None",
122
+ "errorDescription":"None",
123
+ "taskId":"db0a3153-621d-4f5e-8554-a1c032597ee7",
124
+ "status":"ready",
125
+ "solution":{
126
+ "cookie": "223d1f60-xxxxxxxx"
127
+ }
128
+ }
70
129
 
71
130
  Notes:
72
- https://docs.capsolver.com/guide/captcha/awsWaf.html
73
- """
131
+ https://docs.capsolver.com/en/guide/captcha/awsWaf/
74
132
 
75
- def __init__(self, captcha_type: Union[AntiAwsWafTaskTypeEnm, str], websiteURL: str, *args, **kwargs):
76
- super().__init__(*args, **kwargs)
77
-
78
- if captcha_type in AntiAwsWafTaskTypeEnm.list():
79
- self.task_params = WebsiteDataOptionsSer(**locals()).dict()
80
- else:
81
- raise ValueError(
82
- f"""Invalid `captcha_type` parameter set for `{self.__class__.__name__}`,
83
- available - {AntiAwsWafTaskTypeEnm.list_values()}"""
84
- )
85
-
86
- for key in kwargs:
87
- self.task_params.update({key: kwargs[key]})
88
-
89
- def captcha_handler(self) -> CaptchaResponseSer:
90
- """
91
- Sync solving method
92
-
93
- Returns:
94
- CaptchaResponseSer model with full service response
95
-
96
- Notes:
97
- Check class docstring for more info
98
- """
99
- return self._processing_captcha(create_params=self.task_params)
100
-
101
- async def aio_captcha_handler(self) -> CaptchaResponseSer:
102
- """
103
- Async method for captcha solving
133
+ https://docs.capsolver.com/en/guide/recognition/AwsWafClassification/
134
+ """
104
135
 
105
- Returns:
106
- CaptchaResponseSer model with full service response
136
+ def __init__(self, api_key: str, captcha_type: Union[CaptchaTypeEnm, str], **kwargs):
107
137
 
108
- Notes:
109
- Check class docstring for more info
110
- """
111
- return await self._aio_processing_captcha(create_params=self.task_params)
138
+ super().__init__(api_key=api_key, captcha_type=captcha_type, **kwargs)
@@ -1,114 +1,95 @@
1
- from typing import Union, Optional
1
+ from typing import Union
2
2
 
3
- from python3_capsolver.core.base import BaseCaptcha
4
- from python3_capsolver.core.enum import CloudflareTypeEnm
5
- from python3_capsolver.core.serializer import CaptchaResponseSer, CloudflareTurnstileSer
3
+ from .core.base import CaptchaParams
4
+ from .core.enum import CaptchaTypeEnm
6
5
 
6
+ __all__ = ("Cloudflare",)
7
7
 
8
- class Cloudflare(BaseCaptcha):
8
+
9
+ class Cloudflare(CaptchaParams):
9
10
  """
10
- The class is used to work with Capsolver Cloudflare methods.
11
+ The class is used to work with Capsolver AntiTurnstileTaskProxyLess captcha solving method
11
12
 
12
13
  Args:
13
14
  api_key: Capsolver API key
14
- captcha_type: Captcha type name, like ``ReCaptchaV2Task`` and etc.
15
- websiteURL: Address of a webpage with Google ReCaptcha
16
- websiteKey: Recaptcha website key. <div class="g-recaptcha" data-sitekey="THAT_ONE"></div>
17
- metadata: Extra data
18
- html: You can pass in the entire html source code for the challenge directly.
19
-
15
+ captcha_type: Captcha type name, like ``AntiTurnstileTaskProxyLess`` and etc.
16
+ kwargs: additional params for client, like captcha waiting time
17
+ available keys:
18
+ - sleep_time: int - captcha solution waintig time in sec
19
+ - request_url: str - API address for sending requests,
20
+ else official will be used
20
21
 
21
22
  Examples:
22
- >>> Cloudflare(api_key="CAI-1324...",
23
- ... captcha_type=CloudflareTypeEnm.AntiCloudflareTask,
24
- ... websiteURL="https://bck.websiteurl.com/registry",
25
- ... websiteKey='0x4AAAAAAABS7vwvV6VFfMcD',
26
- ... proxy="socks5:158.120.100.23:334:user:pass"
27
- ... ).captcha_handler()
28
- CaptchaResponseSer(errorId=0,
29
- errorCode=None,
30
- errorDescription=None,
31
- taskId='73bdcd28-6c77-4414-8....',
32
- status=<ResponseStatusEnm.Ready: 'ready'>,
33
- solution={'token': '44795sds...'}
34
- )
35
-
36
- >>> Cloudflare(api_key="CAI-1324...",
37
- ... captcha_type=CloudflareTypeEnm.AntiCloudflareTask,
38
- ... websiteURL="https://bck.websiteurl.com/registry",
39
- ... proxy="socks5:158.120.100.23:334:user:pass"
40
- ... ).captcha_handler()
41
- CaptchaResponseSer(errorId=0,
42
- errorCode=None,
43
- errorDescription=None,
44
- taskId='73bdcd28-6c77-4414-8....',
45
- status=<ResponseStatusEnm.Ready: 'ready'>,
46
- solution={'token': '44795sds...'}
47
- )
48
-
49
- >>> await Cloudflare(api_key="CAI-1324...",
50
- ... captcha_type=CloudflareTypeEnm.AntiCloudflareTask,
51
- ... websiteURL="https://bck.websiteurl.com/registry",
52
- ... websiteKey='0x4AAAAAAABS7vwvV6VFfMcD',
53
- ... proxy="socks5:158.120.100.23:334:user:pass"
54
- ... ).aio_captcha_handler()
55
- CaptchaResponseSer(errorId=0,
56
- errorCode=None,
57
- errorDescription=None,
58
- taskId='73bdcd28-6c77-4414-8....',
59
- status=<ResponseStatusEnm.Ready: 'ready'>,
60
- solution={'token': '44795sds...'}
61
- )
62
-
63
- Returns:
64
- CaptchaResponseSer model with full server response
23
+ >>> from python3_capsolver.cloudflare import Cloudflare
24
+ >>> from python3_capsolver.core.enum import CaptchaTypeEnm
25
+ >>> Cloudflare(api_key="CAI-12345....",
26
+ ... captcha_type=CaptchaTypeEnm.AntiTurnstileTaskProxyLess)
27
+ ... .captcha_handler(task_payload={
28
+ ... "websiteKey": "0x4XXXXXXXXXXXXXXXXX",
29
+ ... "metadata": {
30
+ ... "action": "login",
31
+ ... "cdata": "0000-1111-2222-3333-example-cdata"
32
+ ... }
33
+ ... })
34
+ {
35
+ "errorId":0,
36
+ "errorCode":"None",
37
+ "errorDescription":"None",
38
+ "taskId":"db0a3153-621d-4f5e-8554-a1c032597ee7",
39
+ "status":"ready",
40
+ "solution":{
41
+ "token": "0.mF74FV8wEufAWxxxx",
42
+ "type": "turnstile",
43
+ "userAgent": "Mozilla/5.0 xxxx"
44
+ }
45
+ }
46
+
47
+ >>> from python3_capsolver.cloudflare import Cloudflare
48
+ >>> from python3_capsolver.core.enum import CaptchaTypeEnm
49
+ >>> Cloudflare(api_key="CAI-12345....",
50
+ ... captcha_type=CaptchaTypeEnm.AntiCloudflareTask)
51
+ ... .captcha_handler(task_payload={
52
+ ... "websiteURL": "https://www.yourwebsite.com",
53
+ ... "proxy": "ip:port:user:pass",
54
+ ... })
55
+ {
56
+ "errorId":0,
57
+ "errorCode":"None",
58
+ "errorDescription":"None",
59
+ "taskId":"db0a3153-621d-4f5e-8554-a1c032597ee7",
60
+ "status":"ready",
61
+ "solution":{
62
+ "cookies": "cf_clearance=_VPxxxx",
63
+ "headers": {
64
+ "sec-ch-ua": "\"Chromium\";v=\"130\", \"Google Chrome\";v=\"130\", \"Not?A_Brand\";v=\"99\"",
65
+ "sec-ch-ua-platform": "\"Windows\"",
66
+ "accept": "text/html,axxxx",
67
+ "User-Agent": "Mozilla/5.0xxxx",
68
+ "sec-ch-ua-mobile": "?0",
69
+ "sec-fetch-user": "?1",
70
+ "referer": "https://www.yourwebsite.com",
71
+ "Sec-Fetch-Dest": "document",
72
+ "Sec-Fetch-Mode": "navigate",
73
+ "Sec-Fetch-Site": "same-origin",
74
+ "accept-language": "en",
75
+ },
76
+ "page_url": "https://www.yourwebsite.com",
77
+ "proxy": "your proxyxxxx",
78
+ "token": "_VPCTZXP5bhinxxxx"
79
+ }
80
+ }
65
81
 
66
82
  Notes:
67
- https://docs.capsolver.com/guide/antibots/cloudflare_turnstile.html
68
- https://docs.capsolver.com/guide/antibots/cloudflare_challenge.html
83
+ https://docs.capsolver.com/en/guide/captcha/cloudflare_turnstile/
84
+
85
+ https://docs.capsolver.com/en/guide/captcha/cloudflare_challenge/
69
86
  """
70
87
 
71
88
  def __init__(
72
89
  self,
73
- captcha_type: Union[CloudflareTypeEnm, str],
74
- websiteURL: str,
75
- websiteKey: Optional[str] = None,
76
- *args,
90
+ api_key: str,
91
+ captcha_type: Union[CaptchaTypeEnm, str] = CaptchaTypeEnm.AntiTurnstileTaskProxyLess,
77
92
  **kwargs,
78
93
  ):
79
- super().__init__(*args, **kwargs)
80
-
81
- if captcha_type in CloudflareTypeEnm.list():
82
- self.task_params = CloudflareTurnstileSer(**locals()).dict(exclude_none=True)
83
- else:
84
- raise ValueError(
85
- f"""Invalid `captcha_type` parameter set for `{self.__class__.__name__}`,
86
- available - {CloudflareTypeEnm.list()}"""
87
- )
88
- for key in kwargs:
89
- self.task_params.update({key: kwargs[key]})
90
-
91
- def captcha_handler(self) -> CaptchaResponseSer:
92
- """
93
- Sync method for captcha solving
94
-
95
- Returns:
96
- CaptchaResponseSer model with full service response
97
-
98
- Notes:
99
- Check class docstring for more info
100
- """
101
- return self._processing_captcha(create_params=self.task_params)
102
-
103
- async def aio_captcha_handler(self) -> CaptchaResponseSer:
104
- """
105
- Async method for captcha solving
106
-
107
-
108
- Returns:
109
- CaptchaResponseSer model with full service response
110
94
 
111
- Notes:
112
- Check class docstring for more info
113
- """
114
- return await self._aio_processing_captcha(create_params=self.task_params)
95
+ super().__init__(api_key=api_key, captcha_type=captcha_type, **kwargs)
@@ -1,9 +1,13 @@
1
- from python3_capsolver.core.base import BaseCaptcha
2
- from python3_capsolver.core.enum import EndpointPostfixEnm
3
- from python3_capsolver.core.serializer import PostRequestSer, ControlResponseSer
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
4
6
 
7
+ __all__ = ("Control",)
5
8
 
6
- class Control(BaseCaptcha):
9
+
10
+ class Control(CaptchaParams):
7
11
  """
8
12
  The class is used to work with Capsolver control methods.
9
13
 
@@ -11,56 +15,54 @@ class Control(BaseCaptcha):
11
15
  api_key: Capsolver API key
12
16
 
13
17
  Notes:
14
- https://docs.capsolver.com/guide/api-getbalance.html
18
+ https://docs.capsolver.com/en/guide/api-getbalance/
15
19
  """
16
20
 
17
- serializer = PostRequestSer
18
-
19
21
  def __init__(
20
22
  self,
21
- *args,
22
- **kwargs,
23
+ api_key: str,
23
24
  ):
24
- super().__init__(*args, **kwargs)
25
+ super().__init__(api_key=api_key, captcha_type=CaptchaTypeEnm.Control)
25
26
 
26
- def get_balance(self) -> ControlResponseSer:
27
+ def get_balance(self) -> dict:
27
28
  """
28
29
  Synchronous method to view the balance
29
30
 
30
31
  Examples:
32
+ >>> from python3_capsolver.control import Control
31
33
  >>> Control(api_key="CAI-1324...").get_balance()
32
- ControlResponseSer(errorId=0 errorCode=None errorDescription=None balance=150.9085)
34
+ {'balance': 48.6361, 'errorId': 0, 'packages': []}
33
35
 
34
36
  Returns:
35
- ResponseSer model with full server response
37
+ Dict with full server response
36
38
 
37
39
  Notes:
38
- https://docs.capsolver.com/guide/api-getbalance.html
40
+ Check class docstring for more info
39
41
  """
40
- self._prepare_create_task_payload(serializer=self.serializer)
41
- return ControlResponseSer(
42
- **self._create_task(
43
- url_postfix=EndpointPostfixEnm.GET_BALANCE.value,
44
- )
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},
45
47
  )
46
48
 
47
- async def aio_get_balance(self) -> ControlResponseSer:
49
+ async def aio_get_balance(self) -> dict:
48
50
  """
49
51
  Asynchronous method to view the balance
50
52
 
51
53
  Examples:
52
- >>> await Control(api_key="CAI-1324...").aio_get_balance()
53
- ControlResponseSer(errorId=0 errorCode=None errorDescription=None balance=150.9085)
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': []}
54
58
 
55
59
  Returns:
56
- ResponseSer model with full server response
60
+ Dict with full server response
57
61
 
58
62
  Notes:
59
- https://docs.capsolver.com/guide/api-getbalance.html
63
+ Check class docstring for more info
60
64
  """
61
- self._prepare_create_task_payload(serializer=self.serializer)
62
- return ControlResponseSer(
63
- **await self._aio_create_task(
64
- url_postfix=EndpointPostfixEnm.GET_BALANCE.value,
65
- )
65
+ return await AIOCaptchaInstrument.send_post_request(
66
+ url_postfix=GET_BALANCE_POSTFIX,
67
+ payload={"clientKey": self.create_task_payload.clientKey},
66
68
  )
@@ -0,0 +1,109 @@
1
+ import asyncio
2
+ import logging
3
+ from typing import Optional
4
+ from urllib import parse
5
+
6
+ import aiohttp
7
+
8
+ from .enum import ResponseStatusEnm, EndpointPostfixEnm
9
+ from .const import REQUEST_URL, VALID_STATUS_CODES, GET_BALANCE_POSTFIX
10
+ from .utils import attempts_generator
11
+ from .serializer import CaptchaResponseSer
12
+ from .captcha_instrument import CaptchaInstrument
13
+
14
+ __all__ = ("AIOCaptchaInstrument",)
15
+
16
+
17
+ class AIOCaptchaInstrument(CaptchaInstrument):
18
+ """
19
+ Instrument for working with async captcha
20
+ """
21
+
22
+ def __init__(self, captcha_params: "CaptchaParams"):
23
+ super().__init__()
24
+ self.captcha_params = captcha_params
25
+ self.created_task_data = CaptchaResponseSer
26
+
27
+ async def processing_captcha(self) -> dict:
28
+ self.captcha_params.create_task_payload.task = self.captcha_params.task_params
29
+ self.created_task_data = CaptchaResponseSer(**await self.__create_task())
30
+
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:
33
+ return (await self.__get_result()).to_dict()
34
+ elif self.created_task_data.errorId != 0:
35
+ self.created_task_data.status = ResponseStatusEnm.Failed
36
+
37
+ return self.created_task_data.to_dict()
38
+
39
+ async def __create_task(self, url_postfix: str = EndpointPostfixEnm.CREATE_TASK.value) -> dict:
40
+ """
41
+ Function send the ASYNC request to service and wait for result
42
+ """
43
+ async with aiohttp.ClientSession() as session:
44
+ try:
45
+ async with session.post(
46
+ parse.urljoin(self.captcha_params.request_url, url_postfix),
47
+ json=self.captcha_params.create_task_payload.to_dict(),
48
+ ) as resp:
49
+ if resp.status in VALID_STATUS_CODES:
50
+ return await resp.json()
51
+ else:
52
+ raise ValueError(resp.reason)
53
+ except Exception as error:
54
+ logging.exception(error)
55
+ raise
56
+
57
+ async def __get_result(self, url_postfix: str = EndpointPostfixEnm.GET_TASK_RESULT.value) -> CaptchaResponseSer:
58
+ """
59
+ Function send the ASYNC request to service and wait for result
60
+ """
61
+ # initial waiting
62
+ await asyncio.sleep(self.captcha_params.sleep_time)
63
+
64
+ self.captcha_params.get_result_params.taskId = self.created_task_data.taskId
65
+ attempts = attempts_generator()
66
+ async with aiohttp.ClientSession() as session:
67
+ for _ in attempts:
68
+ try:
69
+ async with session.post(
70
+ parse.urljoin(self.captcha_params.request_url, url_postfix),
71
+ json=self.captcha_params.get_result_params.to_dict(),
72
+ ) as resp:
73
+ if resp.status in VALID_STATUS_CODES:
74
+ result_data = CaptchaResponseSer(**await resp.json())
75
+ if result_data.status in (ResponseStatusEnm.Ready, ResponseStatusEnm.Failed):
76
+ # if captcha ready\failed or have unknown status - return exist data
77
+ return result_data
78
+ else:
79
+ raise ValueError(resp.reason)
80
+ except Exception as error:
81
+ logging.exception(error)
82
+ raise
83
+
84
+ # if captcha just created or in processing now - wait
85
+ await asyncio.sleep(self.captcha_params.sleep_time)
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
93
+
94
+ @staticmethod
95
+ async def send_post_request(payload: Optional[dict] = None, url_postfix: str = GET_BALANCE_POSTFIX) -> dict:
96
+ """
97
+ Function send ASYNC request to service and wait for result
98
+ """
99
+
100
+ async with aiohttp.ClientSession() as session:
101
+ try:
102
+ async with session.post(parse.urljoin(REQUEST_URL, url_postfix), json=payload) as resp:
103
+ if resp.status == 200:
104
+ return await resp.json()
105
+ else:
106
+ raise ValueError(resp.status)
107
+ except Exception as error:
108
+ logging.exception(error)
109
+ raise