tweepy-self 1.6.3__py3-none-any.whl → 1.10.0b1__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.
- {tweepy_self-1.6.3.dist-info → tweepy_self-1.10.0b1.dist-info}/METADATA +16 -9
- tweepy_self-1.10.0b1.dist-info/RECORD +23 -0
- twitter/__init__.py +15 -5
- twitter/_capsolver/__init__.py +0 -0
- twitter/_capsolver/core/__init__.py +0 -0
- twitter/_capsolver/core/base.py +227 -0
- twitter/_capsolver/core/config.py +36 -0
- twitter/_capsolver/core/enum.py +66 -0
- twitter/_capsolver/core/serializer.py +85 -0
- twitter/_capsolver/fun_captcha.py +260 -0
- twitter/account.py +17 -13
- twitter/base/__init__.py +2 -2
- twitter/base/client.py +4 -4
- twitter/client.py +388 -222
- twitter/errors.py +14 -7
- twitter/models.py +126 -50
- twitter/utils/__init__.py +2 -0
- twitter/utils/other.py +13 -0
- tweepy_self-1.6.3.dist-info/RECORD +0 -16
- {tweepy_self-1.6.3.dist-info → tweepy_self-1.10.0b1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,260 @@
|
|
1
|
+
from typing import List, Union
|
2
|
+
|
3
|
+
from .core.base import BaseCaptcha
|
4
|
+
from .core.enum import FunCaptchaTypeEnm, FunCaptchaClassificationTypeEnm
|
5
|
+
from .core.serializer import (
|
6
|
+
FunCaptchaSer,
|
7
|
+
CaptchaResponseSer,
|
8
|
+
FunCaptchaClassificationOptionsSer,
|
9
|
+
)
|
10
|
+
|
11
|
+
|
12
|
+
class FunCaptcha(BaseCaptcha):
|
13
|
+
"""
|
14
|
+
The class is used to work with Capsolver FuncaptchaTask methods.
|
15
|
+
|
16
|
+
Args:
|
17
|
+
api_key: Capsolver API key
|
18
|
+
captcha_type: Captcha type name, like ``FunCaptchaTaskProxyLess`` and etc.
|
19
|
+
websiteURL: Address of a webpage with Geetest.
|
20
|
+
websitePublicKey: Funcaptcha website key.
|
21
|
+
|
22
|
+
Examples:
|
23
|
+
>>> with FunCaptcha(api_key="CAI-1324...",
|
24
|
+
... captcha_type="FunCaptchaTaskProxyLess",
|
25
|
+
... websiteURL="https://api.funcaptcha.com/fc/api/nojs/",
|
26
|
+
... websitePublicKey="69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
|
27
|
+
... funcaptchaApiJSSubdomain="https://api.funcaptcha.com/"
|
28
|
+
... ) as instance:
|
29
|
+
>>> instance.captcha_handler()
|
30
|
+
CaptchaResponseSer(errorId=0,
|
31
|
+
errorCode=None,
|
32
|
+
errorDescription=None,
|
33
|
+
taskId='73bdcd28-6c77-4414-8....',
|
34
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
35
|
+
solution={'token': '44795sds...'}
|
36
|
+
)
|
37
|
+
|
38
|
+
>>> with FunCaptcha(api_key="CAI-1324...",
|
39
|
+
... captcha_type="FunCaptchaTaskProxyLess",
|
40
|
+
... websiteURL="https://api.funcaptcha.com/fc/api/nojs/",
|
41
|
+
... websitePublicKey="69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
|
42
|
+
... funcaptchaApiJSSubdomain="https://api.funcaptcha.com/"
|
43
|
+
... ) as instance:
|
44
|
+
>>> await instance.aio_captcha_handler()
|
45
|
+
CaptchaResponseSer(errorId=0,
|
46
|
+
errorCode=None,
|
47
|
+
errorDescription=None,
|
48
|
+
taskId='73bdcd28-6c77-4414-8....',
|
49
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
50
|
+
solution={'token': '44795sds...'}
|
51
|
+
)
|
52
|
+
|
53
|
+
Returns:
|
54
|
+
CaptchaResponseSer model with full server response
|
55
|
+
|
56
|
+
Notes:
|
57
|
+
https://docs.capsolver.com/guide/captcha/FunCaptcha.html
|
58
|
+
"""
|
59
|
+
|
60
|
+
def __init__(
|
61
|
+
self,
|
62
|
+
captcha_type: Union[FunCaptchaTypeEnm, str],
|
63
|
+
websiteURL: str,
|
64
|
+
websitePublicKey: str,
|
65
|
+
*args,
|
66
|
+
**kwargs,
|
67
|
+
):
|
68
|
+
super().__init__(*args, **kwargs)
|
69
|
+
|
70
|
+
if captcha_type in FunCaptchaTypeEnm.list():
|
71
|
+
self.task_params = FunCaptchaSer(**locals()).dict()
|
72
|
+
else:
|
73
|
+
raise ValueError(
|
74
|
+
f"""Invalid `captcha_type` parameter set for `{self.__class__.__name__}`,
|
75
|
+
available - {FunCaptchaTypeEnm.list()}"""
|
76
|
+
)
|
77
|
+
for key in kwargs:
|
78
|
+
self.task_params.update({key: kwargs[key]})
|
79
|
+
|
80
|
+
def captcha_handler(self) -> CaptchaResponseSer:
|
81
|
+
"""
|
82
|
+
Sync solving method
|
83
|
+
|
84
|
+
Examples:
|
85
|
+
>>> FunCaptcha(api_key="CAI-BA9XXXXXXXXXXXXX2702E010",
|
86
|
+
... captcha_type="FunCaptchaTaskProxyLess",
|
87
|
+
... websiteURL="https://api.funcaptcha.com/fc/api/nojs/",
|
88
|
+
... websitePublicKey="69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
|
89
|
+
... funcaptchaApiJSSubdomain="https://api.funcaptcha.com/"
|
90
|
+
... ).captcha_handler()
|
91
|
+
CaptchaResponseSer(errorId=0,
|
92
|
+
errorCode=None,
|
93
|
+
errorDescription=None,
|
94
|
+
taskId='73bdcd28-6c77-4414-8....',
|
95
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
96
|
+
solution={'token': '44795sds...'}
|
97
|
+
)
|
98
|
+
|
99
|
+
>>> FunCaptcha(api_key="CAI-BA9XXXXXXXXXXXXX2702E010",
|
100
|
+
... captcha_type="FuncaptchaTask",
|
101
|
+
... websiteURL="https://api.funcaptcha.com/fc/api/nojs/",
|
102
|
+
... websitePublicKey="69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
|
103
|
+
... funcaptchaApiJSSubdomain="https://api.funcaptcha.com/",
|
104
|
+
... proxyType="http",
|
105
|
+
... proxyAddress="0.0.0.0",
|
106
|
+
... proxyPort=9090,
|
107
|
+
... ).captcha_handler()
|
108
|
+
CaptchaResponseSer(errorId=0,
|
109
|
+
errorCode=None,
|
110
|
+
errorDescription=None,
|
111
|
+
taskId='73bdcd28-6c77-4414-8....',
|
112
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
113
|
+
solution={'token': '44795sds...'}
|
114
|
+
)
|
115
|
+
|
116
|
+
Returns:
|
117
|
+
CaptchaResponseSer model with full service response
|
118
|
+
|
119
|
+
Notes:
|
120
|
+
Check class docstring for more info
|
121
|
+
"""
|
122
|
+
return self._processing_captcha(create_params=self.task_params)
|
123
|
+
|
124
|
+
async def aio_captcha_handler(self) -> CaptchaResponseSer:
|
125
|
+
"""
|
126
|
+
Async method for captcha solving
|
127
|
+
|
128
|
+
Examples:
|
129
|
+
>>> await FunCaptcha(api_key="CAI-1324...",
|
130
|
+
... captcha_type="FunCaptchaTaskProxyLess",
|
131
|
+
... websiteURL="https://api.funcaptcha.com/fc/api/nojs/",
|
132
|
+
... websitePublicKey="69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
|
133
|
+
... funcaptchaApiJSSubdomain="https://api.funcaptcha.com/"
|
134
|
+
... ).aio_captcha_handler()
|
135
|
+
CaptchaResponseSer(errorId=0,
|
136
|
+
errorCode=None,
|
137
|
+
errorDescription=None,
|
138
|
+
taskId='73bdcd28-6c77-4414-8....',
|
139
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
140
|
+
solution={'token': '44795sds...'}
|
141
|
+
)
|
142
|
+
|
143
|
+
>>> await FunCaptcha(api_key="CAI-1324...",
|
144
|
+
... captcha_type="FuncaptchaTask",
|
145
|
+
... websiteURL="https://api.funcaptcha.com/fc/api/nojs/",
|
146
|
+
... websitePublicKey="69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
|
147
|
+
... funcaptchaApiJSSubdomain="https://api.funcaptcha.com/",
|
148
|
+
... proxyType="http",
|
149
|
+
... proxyAddress="0.0.0.0",
|
150
|
+
... proxyPort=9090,
|
151
|
+
... ).aio_captcha_handler()
|
152
|
+
CaptchaResponseSer(errorId=0,
|
153
|
+
errorCode=None,
|
154
|
+
errorDescription=None,
|
155
|
+
taskId='73bdcd28-6c77-4414-8....',
|
156
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
157
|
+
solution={'token': '44795sds...'}
|
158
|
+
)
|
159
|
+
|
160
|
+
>>> with open('some_image.jpeg', 'rb') as img_file:
|
161
|
+
... img_data = img_file.read()
|
162
|
+
>>> body = base64.b64encode(img_data).decode("utf-8")
|
163
|
+
>>> await FunCaptcha(api_key="CAI-1324...",
|
164
|
+
... captcha_type="FunCaptchaClassification"
|
165
|
+
... ).aio_captcha_handler(
|
166
|
+
... image=body,
|
167
|
+
... question="Ask your question")
|
168
|
+
CaptchaResponseSer(errorId=0,
|
169
|
+
errorCode=None,
|
170
|
+
errorDescription=None,
|
171
|
+
taskId='73bdcd28-6c77-4414-8....',
|
172
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
173
|
+
solution={'token': '44795sds...'}
|
174
|
+
)
|
175
|
+
|
176
|
+
Returns:
|
177
|
+
CaptchaResponseSer model with full service response
|
178
|
+
|
179
|
+
Notes:
|
180
|
+
Check class docstring for more info
|
181
|
+
"""
|
182
|
+
return await self._aio_processing_captcha(create_params=self.task_params)
|
183
|
+
|
184
|
+
|
185
|
+
class FunCaptchaClassification(BaseCaptcha):
|
186
|
+
"""
|
187
|
+
The class is used to work with Capsolver FunCaptchaClassification methods.
|
188
|
+
|
189
|
+
Args:
|
190
|
+
api_key: Capsolver API key
|
191
|
+
captcha_type: Captcha type name, like ``FunCaptchaClassification`` and etc.
|
192
|
+
images: Base64 encoded image, can be a screenshot (pass only the hexagonal image, do not pass the rest of the content)
|
193
|
+
question: Question name. this param value from API response game_variant field. Exmaple: maze,maze2,flockCompass,3d_rollball_animals
|
194
|
+
|
195
|
+
Examples:
|
196
|
+
>>> FunCaptchaClassification(api_key="CAI-1324...",
|
197
|
+
... captcha_type="FunCaptchaClassification",
|
198
|
+
... images=["image payload"],
|
199
|
+
... question="maze2",
|
200
|
+
... ).captcha_handler()
|
201
|
+
CaptchaResponseSer(errorId=0,
|
202
|
+
errorCode=None,
|
203
|
+
errorDescription=None,
|
204
|
+
taskId='73bdcd28-6c77-4414-8....',
|
205
|
+
status=<ResponseStatusEnm.Ready: 'ready'>,
|
206
|
+
solution={"objects": [ 4 ]}
|
207
|
+
)
|
208
|
+
|
209
|
+
Returns:
|
210
|
+
CaptchaResponseSer model with full server response
|
211
|
+
|
212
|
+
Notes:
|
213
|
+
https://docs.capsolver.com/guide/recognition/FunCaptchaClassification.html
|
214
|
+
"""
|
215
|
+
|
216
|
+
def __init__(
|
217
|
+
self,
|
218
|
+
images: List[str],
|
219
|
+
question: str,
|
220
|
+
captcha_type: Union[
|
221
|
+
FunCaptchaClassificationTypeEnm, str
|
222
|
+
] = FunCaptchaClassificationTypeEnm.FunCaptchaClassification,
|
223
|
+
*args,
|
224
|
+
**kwargs,
|
225
|
+
):
|
226
|
+
super().__init__(*args, **kwargs)
|
227
|
+
|
228
|
+
if captcha_type in FunCaptchaClassificationTypeEnm.list():
|
229
|
+
self.task_params = FunCaptchaClassificationOptionsSer(**locals()).dict()
|
230
|
+
else:
|
231
|
+
raise ValueError(
|
232
|
+
f"""Invalid `captcha_type` parameter set for `{self.__class__.__name__}`,
|
233
|
+
available - {FunCaptchaClassificationTypeEnm.list()}"""
|
234
|
+
)
|
235
|
+
for key in kwargs:
|
236
|
+
self.task_params.update({key: kwargs[key]})
|
237
|
+
|
238
|
+
def captcha_handler(self) -> CaptchaResponseSer:
|
239
|
+
"""
|
240
|
+
Sync solving method
|
241
|
+
|
242
|
+
Returns:
|
243
|
+
CaptchaResponseSer model with full service response
|
244
|
+
|
245
|
+
Notes:
|
246
|
+
Check class docstring for more info
|
247
|
+
"""
|
248
|
+
return self._processing_captcha(create_params=self.task_params)
|
249
|
+
|
250
|
+
async def aio_captcha_handler(self) -> CaptchaResponseSer:
|
251
|
+
"""
|
252
|
+
Async method for captcha solving
|
253
|
+
|
254
|
+
Returns:
|
255
|
+
CaptchaResponseSer model with full service response
|
256
|
+
|
257
|
+
Notes:
|
258
|
+
Check class docstring for more info
|
259
|
+
"""
|
260
|
+
return await self._aio_processing_captcha(create_params=self.task_params)
|
twitter/account.py
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
from pathlib import Path
|
2
2
|
from typing import Sequence, Iterable
|
3
3
|
|
4
|
-
from pydantic import
|
4
|
+
from pydantic import Field
|
5
5
|
import pyotp
|
6
6
|
|
7
7
|
from .utils import hidden_value, load_lines, write_lines
|
8
8
|
from .enums import AccountStatus
|
9
|
+
from .models import User
|
9
10
|
|
10
11
|
|
11
|
-
class Account(
|
12
|
+
class Account(User):
|
12
13
|
# fmt: off
|
13
14
|
auth_token: str | None = Field(default=None, pattern=r"^[a-f0-9]{40}$")
|
14
|
-
ct0: str | None = None
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
email: str | None = None
|
20
|
-
totp_secret: str | None = None
|
21
|
-
backup_code: str | None = None
|
15
|
+
ct0: str | None = None # 160
|
16
|
+
password: str | None = None # 128
|
17
|
+
email: str | None = None # 254
|
18
|
+
totp_secret: str | None = None # 16
|
19
|
+
backup_code: str | None = None # 12
|
22
20
|
status: AccountStatus = AccountStatus.UNKNOWN
|
23
21
|
# fmt: on
|
24
22
|
|
@@ -38,12 +36,18 @@ class Account(BaseModel):
|
|
38
36
|
def hidden_backup_code(self) -> str | None:
|
39
37
|
return hidden_value(self.backup_code) if self.backup_code else None
|
40
38
|
|
41
|
-
def __repr__(self):
|
42
|
-
return f"{self.__class__.__name__}(auth_token={self.hidden_auth_token}, username={self.username})"
|
43
|
-
|
44
39
|
def __str__(self):
|
45
40
|
return self.hidden_auth_token
|
46
41
|
|
42
|
+
def __repr__(self):
|
43
|
+
return f"{self.__class__.__name__}(id={self.id}, username={self.username}, auth_token={self.hidden_auth_token})"
|
44
|
+
|
45
|
+
def update(self, **data: dict):
|
46
|
+
update = self.dict()
|
47
|
+
update.update(data)
|
48
|
+
for k, v in self.validate(update).dict(exclude_defaults=True).items():
|
49
|
+
setattr(self, k, v)
|
50
|
+
|
47
51
|
def get_totp_code(self) -> str | None:
|
48
52
|
if not self.totp_secret:
|
49
53
|
raise ValueError("No key2fa")
|
twitter/base/__init__.py
CHANGED
twitter/base/client.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from .session import BaseAsyncSession
|
2
2
|
|
3
3
|
|
4
|
-
class
|
4
|
+
class BaseHTTPClient:
|
5
5
|
_DEFAULT_HEADERS = None
|
6
6
|
|
7
7
|
def __init__(self, **session_kwargs):
|
@@ -14,7 +14,7 @@ class BaseClient:
|
|
14
14
|
return self
|
15
15
|
|
16
16
|
async def __aexit__(self, *args):
|
17
|
-
self.close()
|
17
|
+
await self.close()
|
18
18
|
|
19
|
-
def close(self):
|
20
|
-
self._session.close()
|
19
|
+
async def close(self):
|
20
|
+
await self._session.close()
|