python-rucaptcha 4.3.1__py3-none-any.whl → 5.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.
- python_rucaptcha/CapyPuzzle.py +2 -2
- python_rucaptcha/FunCaptcha.py +2 -2
- python_rucaptcha/GeeTest.py +2 -2
- python_rucaptcha/HCaptcha.py +2 -2
- python_rucaptcha/ImageCaptcha.py +2 -2
- python_rucaptcha/KeyCaptcha.py +2 -2
- python_rucaptcha/LeminCroppedCaptcha.py +2 -2
- python_rucaptcha/ReCaptcha.py +2 -2
- python_rucaptcha/RotateCaptcha.py +2 -2
- python_rucaptcha/TikTokCaptcha.py +2 -2
- python_rucaptcha/YandexSmartCaptcha.py +2 -2
- python_rucaptcha/__version__.py +1 -1
- python_rucaptcha/amazon_waf.py +128 -0
- python_rucaptcha/base.py +2 -4
- python_rucaptcha/control.py +401 -0
- python_rucaptcha/text_captcha.py +117 -0
- python_rucaptcha/turnstile.py +53 -0
- {python_rucaptcha-4.3.1.dist-info → python_rucaptcha-5.0.0a0.dist-info}/METADATA +7 -2
- python_rucaptcha-5.0.0a0.dist-info/RECORD +30 -0
- python_rucaptcha-4.3.1.dist-info/RECORD +0 -26
- {python_rucaptcha-4.3.1.dist-info → python_rucaptcha-5.0.0a0.dist-info}/WHEEL +0 -0
- {python_rucaptcha-4.3.1.dist-info → python_rucaptcha-5.0.0a0.dist-info}/top_level.txt +0 -0
python_rucaptcha/CapyPuzzle.py
CHANGED
python_rucaptcha/FunCaptcha.py
CHANGED
python_rucaptcha/GeeTest.py
CHANGED
python_rucaptcha/HCaptcha.py
CHANGED
python_rucaptcha/ImageCaptcha.py
CHANGED
|
@@ -3,8 +3,8 @@ import uuid
|
|
|
3
3
|
import base64
|
|
4
4
|
import shutil
|
|
5
5
|
|
|
6
|
-
from .base import BaseCaptcha
|
|
7
|
-
from .enums import SaveFormatsEnm, ImageCaptchaEnm
|
|
6
|
+
from python_rucaptcha.core.base import BaseCaptcha
|
|
7
|
+
from python_rucaptcha.core.enums import SaveFormatsEnm, ImageCaptchaEnm
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class BaseImageCaptcha(BaseCaptcha):
|
python_rucaptcha/KeyCaptcha.py
CHANGED
python_rucaptcha/ReCaptcha.py
CHANGED
python_rucaptcha/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "
|
|
1
|
+
__version__ = "5.0.0a"
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from python_rucaptcha.core.base import BaseCaptcha
|
|
2
|
+
from python_rucaptcha.core.enums import AmazonWAFCaptchaEnm
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AmazonWAF(BaseCaptcha):
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
rucaptcha_key: str,
|
|
9
|
+
pageurl: str,
|
|
10
|
+
sitekey: str,
|
|
11
|
+
iv: str,
|
|
12
|
+
context: str,
|
|
13
|
+
method: str = AmazonWAFCaptchaEnm.AMAZON_WAF.value,
|
|
14
|
+
*args,
|
|
15
|
+
**kwargs,
|
|
16
|
+
):
|
|
17
|
+
"""
|
|
18
|
+
The class is used to work with Amazon WAF
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
rucaptcha_key: User API key
|
|
22
|
+
pageurl: Full URL of the captcha page
|
|
23
|
+
sitekey: Key value from the page
|
|
24
|
+
iv: Value iv from the page
|
|
25
|
+
context: Value of context from page
|
|
26
|
+
method: Captcha type
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
>>> AmazonWAF(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
30
|
+
... pageurl="https://page-with-waf.com/",
|
|
31
|
+
... sitekey="some-site-key",
|
|
32
|
+
... iv="some-iv-value",
|
|
33
|
+
... context="some-context-value").captcha_handler()
|
|
34
|
+
{
|
|
35
|
+
'serverAnswer': {},
|
|
36
|
+
'captchaSolve': 'eyJ0e......jNuSFqtyP4Ho',
|
|
37
|
+
'taskId': '7111111984',
|
|
38
|
+
'error': False,
|
|
39
|
+
'errorBody': None
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
>>> AmazonWAF(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
43
|
+
... pageurl="https://page-with-waf.com/",
|
|
44
|
+
... sitekey="some-site-key",
|
|
45
|
+
... iv="some-iv-value",
|
|
46
|
+
... context="some-context-value").aio_captcha_handler()
|
|
47
|
+
{
|
|
48
|
+
'serverAnswer': {},
|
|
49
|
+
'captchaSolve': 'eyJ0e......jNuSFqtyP4Ho',
|
|
50
|
+
'taskId': '7111111984',
|
|
51
|
+
'error': False,
|
|
52
|
+
'errorBody': None
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Dict with full server response
|
|
57
|
+
|
|
58
|
+
Notes:
|
|
59
|
+
https://rucaptcha.com/api-rucaptcha#amazon-waf
|
|
60
|
+
"""
|
|
61
|
+
super().__init__(rucaptcha_key=rucaptcha_key, method=method, *args, **kwargs)
|
|
62
|
+
|
|
63
|
+
self.post_payload.update({"sitekey": sitekey, "pageurl": pageurl, "iv": iv, "context": context})
|
|
64
|
+
|
|
65
|
+
# check user params
|
|
66
|
+
if method not in AmazonWAFCaptchaEnm.list_values():
|
|
67
|
+
raise ValueError(f"Invalid method parameter set, available - {AmazonWAFCaptchaEnm.list_values()}")
|
|
68
|
+
|
|
69
|
+
def captcha_handler(self, **kwargs) -> dict:
|
|
70
|
+
"""
|
|
71
|
+
Synchronous method for captcha solving
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
>>> AmazonWAF(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
75
|
+
... pageurl="https://page-with-waf.com/",
|
|
76
|
+
... sitekey="some-site-key",
|
|
77
|
+
... iv="some-iv-value",
|
|
78
|
+
... context="some-context-value").captcha_handler()
|
|
79
|
+
{
|
|
80
|
+
'serverAnswer': {},
|
|
81
|
+
'captchaSolve': 'eyJ0e......jNuSFqtyP4Ho',
|
|
82
|
+
'taskId': '7111111984',
|
|
83
|
+
'error': False,
|
|
84
|
+
'errorBody': None
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Response to captcha as JSON string with fields:
|
|
89
|
+
captchaSolve - captcha solution,
|
|
90
|
+
taskId - finds the ID of the task to solve the captcha,
|
|
91
|
+
error - False - if everything is fine, True - if there is an error,
|
|
92
|
+
errorBody - error name
|
|
93
|
+
|
|
94
|
+
Notes:
|
|
95
|
+
Check class docstirng for more info
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
return self._processing_response(**kwargs)
|
|
99
|
+
|
|
100
|
+
async def aio_captcha_handler(self) -> dict:
|
|
101
|
+
"""
|
|
102
|
+
Asynchronous method for captcha solving
|
|
103
|
+
|
|
104
|
+
Examples:
|
|
105
|
+
>>> await AmazonWAF(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
106
|
+
... pageurl="https://page-with-waf.com/",
|
|
107
|
+
... sitekey="some-site-key",
|
|
108
|
+
... iv="some-iv-value",
|
|
109
|
+
... context="some-context-value").aio_captcha_handler()
|
|
110
|
+
{
|
|
111
|
+
'serverAnswer': {},
|
|
112
|
+
'captchaSolve': 'eyJ0e......jNuSFqtyP4Ho',
|
|
113
|
+
'taskId': '7111111984',
|
|
114
|
+
'error': False,
|
|
115
|
+
'errorBody': None
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
Response to captcha as JSON string with fields:
|
|
120
|
+
captchaSolve - captcha solution,
|
|
121
|
+
taskId - finds the ID of the task to solve the captcha,
|
|
122
|
+
error - False - if everything is fine, True - if there is an error,
|
|
123
|
+
errorBody - error name
|
|
124
|
+
|
|
125
|
+
Notes:
|
|
126
|
+
Check class docstirng for more info
|
|
127
|
+
"""
|
|
128
|
+
return await self._aio_processing_response()
|
python_rucaptcha/base.py
CHANGED
|
@@ -42,10 +42,8 @@ class BaseCaptcha:
|
|
|
42
42
|
# prepare result payload
|
|
43
43
|
self.result = ResponseSer()
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
for key in kwargs:
|
|
48
|
-
self.post_payload.update({key: kwargs[key]})
|
|
45
|
+
for key in kwargs:
|
|
46
|
+
self.post_payload.update({key: kwargs[key]})
|
|
49
47
|
|
|
50
48
|
# prepare session
|
|
51
49
|
self.session = requests.Session()
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from python_rucaptcha.core.base import BaseCaptcha
|
|
4
|
+
from python_rucaptcha.core.enums import ControlEnm
|
|
5
|
+
from python_rucaptcha.core.result_handler import get_sync_result, get_async_result
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Control(BaseCaptcha):
|
|
9
|
+
"""
|
|
10
|
+
The class is used to work with RuCaptcha control methods.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
action: Control action type
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
17
|
+
... action=ControlEnm.DEL_PINGBACK.value).domain_control(addr="all")
|
|
18
|
+
{
|
|
19
|
+
'serverAnswer': {},
|
|
20
|
+
'captchaSolve': 'OK',
|
|
21
|
+
'taskId': None,
|
|
22
|
+
'error': False,
|
|
23
|
+
'errorBody': None
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
27
|
+
... action=ControlEnm.GET.value).report(id="73043727671")
|
|
28
|
+
{
|
|
29
|
+
'serverAnswer': {},
|
|
30
|
+
'captchaSolve': '1',
|
|
31
|
+
'taskId': None,
|
|
32
|
+
'error': False,
|
|
33
|
+
'errorBody': None
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Dict with full server response
|
|
38
|
+
|
|
39
|
+
Notes:
|
|
40
|
+
https://rucaptcha.com/api-rucaptcha#manage_pingback
|
|
41
|
+
https://rucaptcha.com/api-rucaptcha#complain
|
|
42
|
+
https://rucaptcha.com/api-rucaptcha#additional
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
action: str,
|
|
48
|
+
*args,
|
|
49
|
+
**kwargs,
|
|
50
|
+
):
|
|
51
|
+
super().__init__(action=action, *args, **kwargs)
|
|
52
|
+
|
|
53
|
+
# check user params
|
|
54
|
+
if action not in ControlEnm.list_values():
|
|
55
|
+
raise ValueError(f"Invalid method parameter set, available - {ControlEnm.list_values()}")
|
|
56
|
+
|
|
57
|
+
def domain_control(self, addr: Optional[str] = None) -> dict:
|
|
58
|
+
"""
|
|
59
|
+
Callback domains control
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
addr: URL for pingback or `all` with pingback delete param
|
|
63
|
+
|
|
64
|
+
Examples:
|
|
65
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
66
|
+
... action=ControlEnm.DEL_PINGBACK.value).domain_control(addr="all")
|
|
67
|
+
{
|
|
68
|
+
'serverAnswer': {},
|
|
69
|
+
'captchaSolve': 'OK',
|
|
70
|
+
'taskId': None,
|
|
71
|
+
'error': False,
|
|
72
|
+
'errorBody': None
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
76
|
+
... action=ControlEnm.DEL_PINGBACK.value)\
|
|
77
|
+
... .domain_control(addr="http://mysite.com/pingback/url/")
|
|
78
|
+
{
|
|
79
|
+
'serverAnswer': {},
|
|
80
|
+
'captchaSolve': 'OK',
|
|
81
|
+
'taskId': None,
|
|
82
|
+
'error': False,
|
|
83
|
+
'errorBody': None
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
87
|
+
... action=ControlEnm.ADD_PINGBACK.value)\
|
|
88
|
+
... .domain_control(addr="http://mysite.com/pingback/url/")
|
|
89
|
+
{
|
|
90
|
+
'serverAnswer': {},
|
|
91
|
+
'captchaSolve': 'OK',
|
|
92
|
+
'taskId': None,
|
|
93
|
+
'error': False,
|
|
94
|
+
'errorBody': None
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
98
|
+
... action=ControlEnm.GET_PINGBACK.value).domain_control()
|
|
99
|
+
{
|
|
100
|
+
'serverAnswer': {},
|
|
101
|
+
'captchaSolve': 'http://mysite.com/pingback/url/',
|
|
102
|
+
'taskId': None,
|
|
103
|
+
'error': False,
|
|
104
|
+
'errorBody': None
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Dict with full server response
|
|
110
|
+
|
|
111
|
+
Notes:
|
|
112
|
+
https://rucaptcha.com/api-rucaptcha#manage_pingback
|
|
113
|
+
"""
|
|
114
|
+
self.get_payload.update({"addr": addr})
|
|
115
|
+
return get_sync_result(
|
|
116
|
+
get_payload=self.get_payload,
|
|
117
|
+
sleep_time=self.params.sleep_time,
|
|
118
|
+
url_response=self.params.url_response,
|
|
119
|
+
result=self.result,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
async def aio_domain_control(self, addr: Optional[str] = None) -> dict:
|
|
123
|
+
"""
|
|
124
|
+
Callback domains control
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
addr: URL for pingback or `all` with pingback delete param
|
|
128
|
+
|
|
129
|
+
Examples:
|
|
130
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
131
|
+
... action=ControlEnm.DEL_PINGBACK.value).aio_domain_control(addr="all")
|
|
132
|
+
{
|
|
133
|
+
'serverAnswer': {},
|
|
134
|
+
'captchaSolve': 'OK',
|
|
135
|
+
'taskId': None,
|
|
136
|
+
'error': False,
|
|
137
|
+
'errorBody': None
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
141
|
+
... action=ControlEnm.DEL_PINGBACK.value)\
|
|
142
|
+
... .aio_domain_control(addr="http://mysite.com/pingback/url/")
|
|
143
|
+
{
|
|
144
|
+
'serverAnswer': {},
|
|
145
|
+
'captchaSolve': 'OK',
|
|
146
|
+
'taskId': None,
|
|
147
|
+
'error': False,
|
|
148
|
+
'errorBody': None
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
152
|
+
... action=ControlEnm.ADD_PINGBACK.value)\
|
|
153
|
+
... .aio_domain_control(addr="http://mysite.com/pingback/url/")
|
|
154
|
+
{
|
|
155
|
+
'serverAnswer': {},
|
|
156
|
+
'captchaSolve': 'OK',
|
|
157
|
+
'taskId': None,
|
|
158
|
+
'error': False,
|
|
159
|
+
'errorBody': None
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
163
|
+
... action=ControlEnm.GET_PINGBACK.value).aio_domain_control()
|
|
164
|
+
{
|
|
165
|
+
'serverAnswer': {},
|
|
166
|
+
'captchaSolve': 'http://mysite.com/pingback/url/',
|
|
167
|
+
'taskId': None,
|
|
168
|
+
'error': False,
|
|
169
|
+
'errorBody': None
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Dict with full server response
|
|
175
|
+
|
|
176
|
+
Notes:
|
|
177
|
+
https://rucaptcha.com/api-rucaptcha#manage_pingback
|
|
178
|
+
"""
|
|
179
|
+
self.get_payload.update({"addr": addr})
|
|
180
|
+
return await get_async_result(
|
|
181
|
+
get_payload=self.get_payload,
|
|
182
|
+
sleep_time=self.params.sleep_time,
|
|
183
|
+
url_response=self.params.url_response,
|
|
184
|
+
result=self.result,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
def report(self, id: str) -> dict:
|
|
188
|
+
"""
|
|
189
|
+
Captcha results report
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
id: Captcha task ID
|
|
193
|
+
|
|
194
|
+
Examples:
|
|
195
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
196
|
+
... action=ControlEnm.GET.value).report(id="73043727671")
|
|
197
|
+
{
|
|
198
|
+
'serverAnswer': {},
|
|
199
|
+
'captchaSolve': '1',
|
|
200
|
+
'taskId': None,
|
|
201
|
+
'error': False,
|
|
202
|
+
'errorBody': None
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
206
|
+
... action=ControlEnm.REPORTGOOD.value).report(id="73043727671")
|
|
207
|
+
{
|
|
208
|
+
'serverAnswer': {},
|
|
209
|
+
'captchaSolve': 'OK_REPORT_RECORDED',
|
|
210
|
+
'taskId': None,
|
|
211
|
+
'error': False,
|
|
212
|
+
'errorBody': None
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
216
|
+
... action=ControlEnm.REPORTBAD.value).report(id="73043727671")
|
|
217
|
+
{
|
|
218
|
+
'serverAnswer': {},
|
|
219
|
+
'captchaSolve': 'OK_REPORT_RECORDED',
|
|
220
|
+
'taskId': None,
|
|
221
|
+
'error': False,
|
|
222
|
+
'errorBody': None
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Dict with full server response
|
|
228
|
+
|
|
229
|
+
Notes:
|
|
230
|
+
https://rucaptcha.com/api-rucaptcha#complain
|
|
231
|
+
"""
|
|
232
|
+
self.get_payload.update({"id": id})
|
|
233
|
+
return get_sync_result(
|
|
234
|
+
get_payload=self.get_payload,
|
|
235
|
+
sleep_time=self.params.sleep_time,
|
|
236
|
+
url_response=self.params.url_response,
|
|
237
|
+
result=self.result,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
async def aio_report(self, id: str) -> dict:
|
|
241
|
+
"""
|
|
242
|
+
Captcha results report
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
id: Captcha task ID
|
|
246
|
+
|
|
247
|
+
Examples:
|
|
248
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
249
|
+
... action=ControlEnm.GET.value).aio_report(id="73043727671")
|
|
250
|
+
{
|
|
251
|
+
'serverAnswer': {},
|
|
252
|
+
'captchaSolve': '1',
|
|
253
|
+
'taskId': None,
|
|
254
|
+
'error': False,
|
|
255
|
+
'errorBody': None
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
259
|
+
... action=ControlEnm.REPORTGOOD.value).aio_report(id="73043727671")
|
|
260
|
+
{
|
|
261
|
+
'serverAnswer': {},
|
|
262
|
+
'captchaSolve': 'OK_REPORT_RECORDED',
|
|
263
|
+
'taskId': None,
|
|
264
|
+
'error': False,
|
|
265
|
+
'errorBody': None
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
269
|
+
... action=ControlEnm.REPORTBAD.value).aio_report(id="73043727671")
|
|
270
|
+
{
|
|
271
|
+
'serverAnswer': {},
|
|
272
|
+
'captchaSolve': 'OK_REPORT_RECORDED',
|
|
273
|
+
'taskId': None,
|
|
274
|
+
'error': False,
|
|
275
|
+
'errorBody': None
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
Dict with full server response
|
|
281
|
+
|
|
282
|
+
Notes:
|
|
283
|
+
https://rucaptcha.com/api-rucaptcha#complain
|
|
284
|
+
"""
|
|
285
|
+
self.get_payload.update({"id": id})
|
|
286
|
+
return await get_async_result(
|
|
287
|
+
get_payload=self.get_payload,
|
|
288
|
+
sleep_time=self.params.sleep_time,
|
|
289
|
+
url_response=self.params.url_response,
|
|
290
|
+
result=self.result,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
def additional_methods(self, **kwargs) -> dict:
|
|
294
|
+
"""
|
|
295
|
+
Some additional methods for control API (like balance and etc.)
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
kwargs: Additional params for method, like `id`, `ids`, more info in service docs.
|
|
299
|
+
|
|
300
|
+
Examples:
|
|
301
|
+
>>> Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
302
|
+
... action=ControlEnm.GETBALANCE.value).additional_methods()
|
|
303
|
+
{
|
|
304
|
+
'serverAnswer': {},
|
|
305
|
+
'captchaSolve': '1044.23118',
|
|
306
|
+
'taskId': None,
|
|
307
|
+
'error': False,
|
|
308
|
+
'errorBody': None
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
Dict with full server response
|
|
313
|
+
|
|
314
|
+
Notes:
|
|
315
|
+
https://rucaptcha.com/api-rucaptcha#additional
|
|
316
|
+
"""
|
|
317
|
+
for key in kwargs:
|
|
318
|
+
self.get_payload.update({key: kwargs[key]})
|
|
319
|
+
return get_sync_result(
|
|
320
|
+
get_payload=self.get_payload,
|
|
321
|
+
sleep_time=self.params.sleep_time,
|
|
322
|
+
url_response=self.params.url_response,
|
|
323
|
+
result=self.result,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
async def aio_additional_methods(self, **kwargs) -> dict:
|
|
327
|
+
"""
|
|
328
|
+
Some additional methods for control API (like balance and etc.)
|
|
329
|
+
|
|
330
|
+
Args:
|
|
331
|
+
kwargs: Additional params for method, like `id`, `ids`, more info in service docs.
|
|
332
|
+
|
|
333
|
+
Examples:
|
|
334
|
+
>>> await Control(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
335
|
+
... action=ControlEnm.GETBALANCE.value).aio_additional_methods()
|
|
336
|
+
{
|
|
337
|
+
'serverAnswer': {},
|
|
338
|
+
'captchaSolve': '1044.23118',
|
|
339
|
+
'taskId': None,
|
|
340
|
+
'error': False,
|
|
341
|
+
'errorBody': None
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
Dict with full server response
|
|
346
|
+
|
|
347
|
+
Notes:
|
|
348
|
+
https://rucaptcha.com/api-rucaptcha#additional
|
|
349
|
+
"""
|
|
350
|
+
for key in kwargs:
|
|
351
|
+
self.get_payload.update({key: kwargs[key]})
|
|
352
|
+
return await get_async_result(
|
|
353
|
+
get_payload=self.get_payload,
|
|
354
|
+
sleep_time=self.params.sleep_time,
|
|
355
|
+
url_response=self.params.url_response,
|
|
356
|
+
result=self.result,
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
'''
|
|
361
|
+
# Async WebSocket method
|
|
362
|
+
class sockCaptchaControl(WebSocketRuCaptcha):
|
|
363
|
+
def __init__(self, rucaptcha_key: str, allSessions: bool = None, suppressSuccess: bool = None):
|
|
364
|
+
"""
|
|
365
|
+
Method setup WebSocket connection data
|
|
366
|
+
Params description check in parent class
|
|
367
|
+
"""
|
|
368
|
+
super().__init__(allSessions, suppressSuccess)
|
|
369
|
+
self.rucaptcha_key = rucaptcha_key
|
|
370
|
+
|
|
371
|
+
async def get_balance(self) -> dict:
|
|
372
|
+
"""
|
|
373
|
+
The asynchronous WebSocket method return account balance.
|
|
374
|
+
More info - https://wsrucaptcha.docs.apiary.io/#reference/4
|
|
375
|
+
:return: Server response dict
|
|
376
|
+
"""
|
|
377
|
+
balance_payload = ControlCaptchaSocketSer(
|
|
378
|
+
**{
|
|
379
|
+
"method": "balance",
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
return await self.send_request(balance_payload.json(exclude_none=True))
|
|
383
|
+
|
|
384
|
+
async def report(self, success: bool, captchaId: int) -> dict:
|
|
385
|
+
"""
|
|
386
|
+
The asynchronous WebSocket method send captcha solving reports (success or fail).
|
|
387
|
+
More info - https://wsrucaptcha.docs.apiary.io/#reference/2
|
|
388
|
+
:param success: Is captcha solved success?
|
|
389
|
+
:param captchaId: Captcha task unique id. For example - 5034284222
|
|
390
|
+
:return: Server response dict
|
|
391
|
+
"""
|
|
392
|
+
report_payload = ControlCaptchaSocketSer(
|
|
393
|
+
**{
|
|
394
|
+
"method": "report",
|
|
395
|
+
"success": success,
|
|
396
|
+
"captchaId": captchaId,
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
return await self.send_request(report_payload.json(exclude_none=True))
|
|
401
|
+
'''
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from python_rucaptcha.core.base import BaseCaptcha
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TextCaptcha(BaseCaptcha):
|
|
5
|
+
"""
|
|
6
|
+
The class is used to work with TextCaptcha.
|
|
7
|
+
Solve description:
|
|
8
|
+
https://rucaptcha.com/api-rucaptcha#solving_text_captcha
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
rucaptcha_key: User API key
|
|
12
|
+
language: Captcha text lang:
|
|
13
|
+
0 - not defined
|
|
14
|
+
1 - captcha contains only Cyrillic
|
|
15
|
+
2 - captcha contains only latin characters
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
>>> TextCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
19
|
+
... language=2).captcha_handler(textcaptcha="Our planet name?")
|
|
20
|
+
{
|
|
21
|
+
'serverAnswer': {},
|
|
22
|
+
'captchaSolve': 'earth',
|
|
23
|
+
'taskId': '73043008354',
|
|
24
|
+
'error': False,
|
|
25
|
+
'errorBody': None
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
>>> TextCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122")\
|
|
29
|
+
... .captcha_handler(textcaptcha="Our planet name?")
|
|
30
|
+
{
|
|
31
|
+
'serverAnswer': {},
|
|
32
|
+
'captchaSolve': 'earth',
|
|
33
|
+
'taskId': '73043008354',
|
|
34
|
+
'error': False,
|
|
35
|
+
'errorBody': None
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Dict with full server response
|
|
40
|
+
|
|
41
|
+
Notes:
|
|
42
|
+
https://rucaptcha.com/api-rucaptcha#solving_text_captcha
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
rucaptcha_key: str,
|
|
48
|
+
language: int = 0,
|
|
49
|
+
*args,
|
|
50
|
+
**kwargs,
|
|
51
|
+
):
|
|
52
|
+
super().__init__(rucaptcha_key=rucaptcha_key, *args, **kwargs)
|
|
53
|
+
|
|
54
|
+
self.post_payload.update({"language": language})
|
|
55
|
+
|
|
56
|
+
def captcha_handler(self, textcaptcha: str, **kwargs) -> dict:
|
|
57
|
+
"""
|
|
58
|
+
Synchronous method for captcha solving
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
textcaptcha: Captcha text
|
|
62
|
+
|
|
63
|
+
Examples:
|
|
64
|
+
>>> TextCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
65
|
+
... language=2).captcha_handler(textcaptcha="Our planet name?")
|
|
66
|
+
{
|
|
67
|
+
'serverAnswer': {},
|
|
68
|
+
'captchaSolve': 'earth',
|
|
69
|
+
'taskId': '73043008354',
|
|
70
|
+
'error': False,
|
|
71
|
+
'errorBody': None
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Response to captcha as JSON string with fields:
|
|
76
|
+
captchaSolve - captcha solution,
|
|
77
|
+
taskId - finds the ID of the task to solve the captcha,
|
|
78
|
+
error - False - if everything is fine, True - if there is an error,
|
|
79
|
+
errorBody - error name
|
|
80
|
+
|
|
81
|
+
Notes:
|
|
82
|
+
Check class docstirng for more info
|
|
83
|
+
"""
|
|
84
|
+
self.post_payload.update({"textcaptcha": textcaptcha})
|
|
85
|
+
|
|
86
|
+
return self._processing_response(**kwargs)
|
|
87
|
+
|
|
88
|
+
async def aio_captcha_handler(self, textcaptcha: str) -> dict:
|
|
89
|
+
"""
|
|
90
|
+
Asynchronous method for captcha solving
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
:param textcaptcha: Captcha text
|
|
94
|
+
|
|
95
|
+
Examples:
|
|
96
|
+
>>> await TextCaptcha(rucaptcha_key="aa9011f31111181111168611f1151122",
|
|
97
|
+
... language=2).aio_captcha_handler(textcaptcha="Our planet name?")
|
|
98
|
+
{
|
|
99
|
+
'serverAnswer': {},
|
|
100
|
+
'captchaSolve': 'earth',
|
|
101
|
+
'taskId': '73043008354',
|
|
102
|
+
'error': False,
|
|
103
|
+
'errorBody': None
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
Response to captcha as JSON string with fields:
|
|
108
|
+
captchaSolve - captcha solution,
|
|
109
|
+
taskId - finds the ID of the task to solve the captcha,
|
|
110
|
+
error - False - if everything is fine, True - if there is an error,
|
|
111
|
+
errorBody - error name
|
|
112
|
+
|
|
113
|
+
Notes:
|
|
114
|
+
Check class docstirng for more info
|
|
115
|
+
"""
|
|
116
|
+
self.post_payload.update({"textcaptcha": textcaptcha})
|
|
117
|
+
return await self._aio_processing_response()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from python_rucaptcha.core.base import BaseCaptcha
|
|
2
|
+
from python_rucaptcha.core.enums import TurnstileCaptchaEnm
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BaseTurnstile(BaseCaptcha):
|
|
6
|
+
def __init__(self, pageurl: str, sitekey: str, method: str = TurnstileCaptchaEnm.TURNSTILE.value, *args, **kwargs):
|
|
7
|
+
super().__init__(method=method, *args, **kwargs)
|
|
8
|
+
|
|
9
|
+
self.post_payload.update({"sitekey": sitekey, "pageurl": pageurl})
|
|
10
|
+
|
|
11
|
+
# check user params
|
|
12
|
+
if method not in TurnstileCaptchaEnm.list_values():
|
|
13
|
+
raise ValueError(f"Invalid method parameter set, available - {TurnstileCaptchaEnm.list_values()}")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Turnstile(BaseTurnstile):
|
|
17
|
+
"""
|
|
18
|
+
The class is used to work with Cloudflare Turnstile
|
|
19
|
+
Solve description:
|
|
20
|
+
https://rucaptcha.com/api-rucaptcha#turnstile
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def captcha_handler(self, **kwargs):
|
|
24
|
+
"""
|
|
25
|
+
The method is responsible for sending data to the server to solve the captcha
|
|
26
|
+
:param kwargs: Parameters for the `requests` library
|
|
27
|
+
:return: Response to captcha as JSON string with fields:
|
|
28
|
+
captchaSolve - captcha solution,
|
|
29
|
+
taskId - finds the ID of the task to solve the captcha,
|
|
30
|
+
error - False - if everything is fine, True - if there is an error,
|
|
31
|
+
errorBody - error name
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
return self._processing_response(**kwargs)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class aioTurnstile(BaseTurnstile):
|
|
38
|
+
"""
|
|
39
|
+
The class is used to work with Cloudflare Turnstile
|
|
40
|
+
Solve description:
|
|
41
|
+
https://rucaptcha.com/api-rucaptcha#turnstile
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
async def captcha_handler(self):
|
|
45
|
+
"""
|
|
46
|
+
The method is responsible for sending data to the server to solve the captcha
|
|
47
|
+
:return: Response to captcha as JSON string with fields:
|
|
48
|
+
captchaSolve - captcha solution,
|
|
49
|
+
taskId - finds the ID of the task to solve the captcha,
|
|
50
|
+
error - False - if everything is fine, True - if there is an error,
|
|
51
|
+
errorBody - error name
|
|
52
|
+
"""
|
|
53
|
+
return await self._aio_processing_response()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-rucaptcha
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0a0
|
|
4
4
|
Summary: Python 3.6+ RuCaptcha library with AIO module.
|
|
5
5
|
Home-page: https://github.com/AndreiDrang/python-rucaptcha
|
|
6
6
|
Author: AndreiDrang, redV0ID
|
|
@@ -27,6 +27,8 @@ Keywords: captcha
|
|
|
27
27
|
rucaptcha-client
|
|
28
28
|
yandex
|
|
29
29
|
turnstile
|
|
30
|
+
amazon
|
|
31
|
+
amazon_waf
|
|
30
32
|
Platform: UNKNOWN
|
|
31
33
|
Classifier: License :: OSI Approved :: MIT License
|
|
32
34
|
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
|
|
@@ -42,7 +44,7 @@ Classifier: Framework :: AsyncIO
|
|
|
42
44
|
Classifier: Operating System :: Unix
|
|
43
45
|
Classifier: Operating System :: Microsoft :: Windows
|
|
44
46
|
Classifier: Operating System :: MacOS
|
|
45
|
-
Requires-Python: >=3.
|
|
47
|
+
Requires-Python: >=3.7.0
|
|
46
48
|
Description-Content-Type: text/markdown
|
|
47
49
|
Requires-Dist: requests (>=2.21.0)
|
|
48
50
|
Requires-Dist: aiohttp (>=3.7.4)
|
|
@@ -62,6 +64,9 @@ Requires-Dist: tenacity (==8.*)
|
|
|
62
64
|
|
|
63
65
|
[](https://codeclimate.com/github/AndreiDrang/python-rucaptcha/maintainability)
|
|
64
66
|
|
|
67
|
+
[](https://github.com/AndreiDrang/python-rucaptcha/actions/workflows/test.yml)
|
|
68
|
+
[](https://github.com/AndreiDrang/python-rucaptcha/actions/workflows/lint.yml)
|
|
69
|
+
|
|
65
70
|
Python3 library for [RuCaptcha](https://rucaptcha.com/) and [2Captcha](https://2captcha.com/) service API.
|
|
66
71
|
|
|
67
72
|
Tested on UNIX based OS.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
python_rucaptcha/CaptchaControl.py,sha256=-UcKan0m6tb-l9LJ-Nz8_GVW8j6B_Te9VJwdW1eQ_AQ,6031
|
|
2
|
+
python_rucaptcha/CapyPuzzle.py,sha256=qxTJoZAr0PcklTCp1DVzJB7uxjBHhnuzWgk5iy2nqoc,2124
|
|
3
|
+
python_rucaptcha/FunCaptcha.py,sha256=4O-CUU4RksXfUNwE40fMKr5YJEixCh9Xp2-xJupuAPQ,2148
|
|
4
|
+
python_rucaptcha/GeeTest.py,sha256=0B83baV6O2IlLjRiwb72zzyDUFbufQIZmpXv79manBU,3303
|
|
5
|
+
python_rucaptcha/HCaptcha.py,sha256=n_fj1zq1bhn1HPzKAogEHzmv080VJFusVR73sM0QNQg,2076
|
|
6
|
+
python_rucaptcha/ImageCaptcha.py,sha256=yWr1f5CwjfITirOAbt4gLQzUaXiZsm1-iCeI8pROmpk,9021
|
|
7
|
+
python_rucaptcha/KeyCaptcha.py,sha256=m47iFeK0OVSDb2nQ_t2gHBMN9nIn36dhRmEiVZcXhjc,2480
|
|
8
|
+
python_rucaptcha/LeminCroppedCaptcha.py,sha256=TRMA554XDP2ysCft-VfE30bh3dy5NjrH6QpGCFh7iLw,2212
|
|
9
|
+
python_rucaptcha/ReCaptcha.py,sha256=8JNiO_8krcTT1xN3yTNGPjlC1BtF-TRq9doEhGaDCZw,2438
|
|
10
|
+
python_rucaptcha/RotateCaptcha.py,sha256=vz9GhKplK1PoexhCmgxhebEoySn4XWnFM17ga5tBz2Q,3295
|
|
11
|
+
python_rucaptcha/SocketAPI.py,sha256=W_ZmEaNTMx--lvaYiLJyckWGt3P-gxoZf0qdxK-onb0,4291
|
|
12
|
+
python_rucaptcha/TextCaptcha.py,sha256=vMNbQFWZa3FY5m01vw9DPAI389OImtuTuZRs06gNRio,2935
|
|
13
|
+
python_rucaptcha/TikTokCaptcha.py,sha256=l9GMq1eiXqxPTuath9s0uc-XUusQXDc8sNcFhDieCJg,2289
|
|
14
|
+
python_rucaptcha/Turnstile.py,sha256=C7MYHrsx-wVYCrHS0fwfIuLVWZqeks_W9x8C2TpbuUc,2019
|
|
15
|
+
python_rucaptcha/YandexSmartCaptcha.py,sha256=N_XyGZ92bjyRV9yD6I3A64Qcxzsl-HKxw5KaZWkGByE,2087
|
|
16
|
+
python_rucaptcha/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
python_rucaptcha/__version__.py,sha256=MlH-A-_oP01JeZLx9j1ZRRXkKE1SJSep_CffU4pyeJ8,23
|
|
18
|
+
python_rucaptcha/amazon_waf.py,sha256=VIf0RMs8i99KEQ9W6hlN420IBdehEk9hPWdFIaC6Uvs,4618
|
|
19
|
+
python_rucaptcha/base.py,sha256=UDAsyHUUKcsnvBJBnHqfUs2d1H-k6nVnDXL8dwR57Zs,5805
|
|
20
|
+
python_rucaptcha/config.py,sha256=xGFAeYmgqGEuUlAOCyZthEiTYlChqQQ2KSwfPeBOdXM,567
|
|
21
|
+
python_rucaptcha/control.py,sha256=ZFPdhNKiEOCTaMm2QpBPwKmEUGGY9ZcHdhz0tf9dTRA,13209
|
|
22
|
+
python_rucaptcha/enums.py,sha256=O2rpMnbKPO-HVVJD8LnKVE1xtxmjYgrkLaR0f1WGkoU,1705
|
|
23
|
+
python_rucaptcha/result_handler.py,sha256=W8meecABi2kADirNQ58gkmUI9CdVesI1x8zxHOIe1QA,3138
|
|
24
|
+
python_rucaptcha/serializer.py,sha256=kDr2FfNYy0NLL73n_tsIvqyPPDlL8vV0qsybZGX7-hA,3973
|
|
25
|
+
python_rucaptcha/text_captcha.py,sha256=5r0oK5Zd3HajwIgSw4XU582na3wwQm008K82erCl6UE,3759
|
|
26
|
+
python_rucaptcha/turnstile.py,sha256=U3CjcbXZvFuu97rEnNLQOk8iLN8kg_9f-d1JlxZOdRc,2061
|
|
27
|
+
python_rucaptcha-5.0.0a0.dist-info/METADATA,sha256=lpk8-A-KPzJvaiZ_n6zI9wo6lcnMJCL971awlLFW9u8,4056
|
|
28
|
+
python_rucaptcha-5.0.0a0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
29
|
+
python_rucaptcha-5.0.0a0.dist-info/top_level.txt,sha256=Eu_atEB79Y7jCsfXPcXF5N8OLt6kKVbvhuRsI1BmSWM,17
|
|
30
|
+
python_rucaptcha-5.0.0a0.dist-info/RECORD,,
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
python_rucaptcha/CaptchaControl.py,sha256=-UcKan0m6tb-l9LJ-Nz8_GVW8j6B_Te9VJwdW1eQ_AQ,6031
|
|
2
|
-
python_rucaptcha/CapyPuzzle.py,sha256=MLetxVoeXXw7X98pe_-djUJp97WG0JfQxov9DDSu-4s,2082
|
|
3
|
-
python_rucaptcha/FunCaptcha.py,sha256=Ij79BuaGUIdbsuIodC_XnK0POoiXNFRCfK4S0AghsOg,2106
|
|
4
|
-
python_rucaptcha/GeeTest.py,sha256=GbEwJtl3l5CpR00KvzAmnT2b_saeIwz84DV1VPqVQTk,3261
|
|
5
|
-
python_rucaptcha/HCaptcha.py,sha256=dmssVRVWjOykB-e_hK9uA_6zBH4kqFR0ezpxdLRFHAk,2034
|
|
6
|
-
python_rucaptcha/ImageCaptcha.py,sha256=HinU3-hUmZVS_NUrCSY5cxlcXnGI9dyXdBf8Kbtu5CU,8979
|
|
7
|
-
python_rucaptcha/KeyCaptcha.py,sha256=CDDM8bfxlvmL3wX5qFDAIJaQ7rKhVdkI181adeewPaY,2438
|
|
8
|
-
python_rucaptcha/LeminCroppedCaptcha.py,sha256=DMVwvers7dVLwNBHksBmZj9pGl2jrHgT5a5gT61k5HY,2170
|
|
9
|
-
python_rucaptcha/ReCaptcha.py,sha256=2UUKzDL9cg03G6d9n15TCJLPN_mPTezySrNSyB1lAYI,2396
|
|
10
|
-
python_rucaptcha/RotateCaptcha.py,sha256=Ik-n6toGaKqBxO99quXmzsZD3FlJbDHXpb4j4Iu5KAM,3253
|
|
11
|
-
python_rucaptcha/SocketAPI.py,sha256=W_ZmEaNTMx--lvaYiLJyckWGt3P-gxoZf0qdxK-onb0,4291
|
|
12
|
-
python_rucaptcha/TextCaptcha.py,sha256=vMNbQFWZa3FY5m01vw9DPAI389OImtuTuZRs06gNRio,2935
|
|
13
|
-
python_rucaptcha/TikTokCaptcha.py,sha256=TngS2ZE96Y1a32jl93CetTBMVTh04oe3c5bsPs0hm-c,2247
|
|
14
|
-
python_rucaptcha/Turnstile.py,sha256=C7MYHrsx-wVYCrHS0fwfIuLVWZqeks_W9x8C2TpbuUc,2019
|
|
15
|
-
python_rucaptcha/YandexSmartCaptcha.py,sha256=W4O0TkXcc3WiYWAt8qdIuPqlWItEXhJ0JgBhDEcHKQM,2045
|
|
16
|
-
python_rucaptcha/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
python_rucaptcha/__version__.py,sha256=gKhp048MdP-3cJ_eV-P1YyHenF2KvM2r8m9M1vLMB1A,22
|
|
18
|
-
python_rucaptcha/base.py,sha256=-Jo05hKrNBX-Qzjv2xOwIngWZZpQKUody9xptX9zjoM,5898
|
|
19
|
-
python_rucaptcha/config.py,sha256=xGFAeYmgqGEuUlAOCyZthEiTYlChqQQ2KSwfPeBOdXM,567
|
|
20
|
-
python_rucaptcha/enums.py,sha256=O2rpMnbKPO-HVVJD8LnKVE1xtxmjYgrkLaR0f1WGkoU,1705
|
|
21
|
-
python_rucaptcha/result_handler.py,sha256=W8meecABi2kADirNQ58gkmUI9CdVesI1x8zxHOIe1QA,3138
|
|
22
|
-
python_rucaptcha/serializer.py,sha256=kDr2FfNYy0NLL73n_tsIvqyPPDlL8vV0qsybZGX7-hA,3973
|
|
23
|
-
python_rucaptcha-4.3.1.dist-info/METADATA,sha256=tbjU83L7cTyZa1YuYX1WFRT7laMQsF76-m3ouUPTjOY,3654
|
|
24
|
-
python_rucaptcha-4.3.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
|
25
|
-
python_rucaptcha-4.3.1.dist-info/top_level.txt,sha256=Eu_atEB79Y7jCsfXPcXF5N8OLt6kKVbvhuRsI1BmSWM,17
|
|
26
|
-
python_rucaptcha-4.3.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|