tweepy-self 1.6.3__py3-none-any.whl → 1.10.0b9__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.10.0b9.dist-info/METADATA +303 -0
- tweepy_self-1.10.0b9.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 +744 -382
- twitter/errors.py +14 -7
- twitter/models.py +147 -50
- twitter/utils/__init__.py +2 -0
- twitter/utils/html.py +6 -2
- twitter/utils/other.py +13 -0
- tweepy_self-1.6.3.dist-info/METADATA +0 -218
- tweepy_self-1.6.3.dist-info/RECORD +0 -16
- {tweepy_self-1.6.3.dist-info → tweepy_self-1.10.0b9.dist-info}/WHEEL +0 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
from types import DynamicClassAttribute
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
|
6
|
+
class MyEnum(Enum):
|
7
|
+
@classmethod
|
8
|
+
def list(cls) -> List[Enum]:
|
9
|
+
return list(map(lambda c: c, cls))
|
10
|
+
|
11
|
+
@classmethod
|
12
|
+
def list_values(cls) -> List[str]:
|
13
|
+
return list(map(lambda c: c.value, cls))
|
14
|
+
|
15
|
+
@classmethod
|
16
|
+
def list_names(cls) -> List[str]:
|
17
|
+
return list(map(lambda c: c.name, cls))
|
18
|
+
|
19
|
+
@DynamicClassAttribute
|
20
|
+
def name(self) -> str:
|
21
|
+
"""
|
22
|
+
The name of the Enum member
|
23
|
+
"""
|
24
|
+
return self._name_
|
25
|
+
|
26
|
+
@DynamicClassAttribute
|
27
|
+
def value(self) -> str:
|
28
|
+
"""
|
29
|
+
The name of the Enum member
|
30
|
+
"""
|
31
|
+
return self._value_
|
32
|
+
|
33
|
+
|
34
|
+
class EndpointPostfixEnm(str, MyEnum):
|
35
|
+
"""
|
36
|
+
Enum stored URL postfixes for API endpoints
|
37
|
+
"""
|
38
|
+
|
39
|
+
GET_BALANCE = "getBalance"
|
40
|
+
CREATE_TASK = "createTask"
|
41
|
+
GET_TASK_RESULT = "getTaskResult"
|
42
|
+
AKAMAI_BMP_INVOKE = "akamaibmp/invoke"
|
43
|
+
AKAMAI_WEB_INVOKE = "akamaiweb/invoke"
|
44
|
+
|
45
|
+
|
46
|
+
class FunCaptchaTypeEnm(str, MyEnum):
|
47
|
+
FunCaptchaTask = "FunCaptchaTask"
|
48
|
+
FunCaptchaTaskProxyLess = "FunCaptchaTaskProxyLess"
|
49
|
+
|
50
|
+
|
51
|
+
class FunCaptchaClassificationTypeEnm(str, MyEnum):
|
52
|
+
FunCaptchaClassification = "FunCaptchaClassification"
|
53
|
+
|
54
|
+
|
55
|
+
class ResponseStatusEnm(str, MyEnum):
|
56
|
+
"""
|
57
|
+
Enum store results `status` field variants
|
58
|
+
|
59
|
+
Notes:
|
60
|
+
https://docs.capsolver.com/guide/api-createtask.html
|
61
|
+
"""
|
62
|
+
|
63
|
+
Idle = "idle" # Task created
|
64
|
+
Processing = "processing" # Task is not ready yet
|
65
|
+
Ready = "ready" # Task completed, solution object can be found in solution property
|
66
|
+
Failed = "failed" # Task failed, check the errorDescription to know why failed.
|
@@ -0,0 +1,85 @@
|
|
1
|
+
from typing import Any, Dict, List, Literal, Optional
|
2
|
+
|
3
|
+
from pydantic import Field, BaseModel, conint
|
4
|
+
|
5
|
+
from .enum import ResponseStatusEnm
|
6
|
+
from .config import APP_ID
|
7
|
+
|
8
|
+
"""
|
9
|
+
HTTP API Request ser
|
10
|
+
"""
|
11
|
+
|
12
|
+
|
13
|
+
class PostRequestSer(BaseModel):
|
14
|
+
clientKey: str = Field(..., description="Client account key, can be found in user account")
|
15
|
+
task: dict = Field(None, description="Task object")
|
16
|
+
|
17
|
+
|
18
|
+
class TaskSer(BaseModel):
|
19
|
+
type: str = Field(..., description="Task type name", alias="captcha_type")
|
20
|
+
|
21
|
+
|
22
|
+
class RequestCreateTaskSer(PostRequestSer):
|
23
|
+
appId: Literal[APP_ID] = APP_ID
|
24
|
+
|
25
|
+
|
26
|
+
class RequestGetTaskResultSer(PostRequestSer):
|
27
|
+
taskId: Optional[str] = Field(None, description="ID created by the createTask method")
|
28
|
+
|
29
|
+
|
30
|
+
"""
|
31
|
+
HTTP API Response ser
|
32
|
+
"""
|
33
|
+
|
34
|
+
|
35
|
+
class ResponseSer(BaseModel):
|
36
|
+
errorId: int = Field(..., description="Error message: `False` - no error, `True` - with error")
|
37
|
+
# error info
|
38
|
+
errorCode: Optional[str] = Field(None, description="Error code")
|
39
|
+
errorDescription: Optional[str] = Field(None, description="Error description")
|
40
|
+
|
41
|
+
|
42
|
+
class CaptchaResponseSer(ResponseSer):
|
43
|
+
taskId: Optional[str] = Field(None, description="Task ID for future use in getTaskResult method.")
|
44
|
+
status: ResponseStatusEnm = Field(ResponseStatusEnm.Processing, description="Task current status")
|
45
|
+
solution: Dict[str, Any] = Field(None, description="Task result data. Different for each type of task.")
|
46
|
+
|
47
|
+
class Config:
|
48
|
+
populate_by_name = True
|
49
|
+
|
50
|
+
|
51
|
+
class ControlResponseSer(ResponseSer):
|
52
|
+
balance: Optional[float] = Field(0, description="Account balance value in USD")
|
53
|
+
|
54
|
+
|
55
|
+
"""
|
56
|
+
Other ser
|
57
|
+
"""
|
58
|
+
|
59
|
+
|
60
|
+
class CaptchaOptionsSer(BaseModel):
|
61
|
+
api_key: str
|
62
|
+
sleep_time: conint(ge=5) = 5
|
63
|
+
|
64
|
+
|
65
|
+
"""
|
66
|
+
Captcha tasks ser
|
67
|
+
"""
|
68
|
+
|
69
|
+
|
70
|
+
class FunCaptchaClassificationOptionsSer(TaskSer):
|
71
|
+
images: List[str] = Field(..., description="Base64-encoded images, do not include 'data:image/***;base64,'")
|
72
|
+
question: str = Field(
|
73
|
+
...,
|
74
|
+
description="Question name. this param value from API response game_variant field. Exmaple: maze,maze2,flockCompass,3d_rollball_animals",
|
75
|
+
)
|
76
|
+
|
77
|
+
|
78
|
+
class FunCaptchaSer(TaskSer):
|
79
|
+
websiteURL: str = Field(..., description="Address of a webpage with Funcaptcha")
|
80
|
+
websitePublicKey: str = Field(..., description="Funcaptcha website key.")
|
81
|
+
funcaptchaApiJSSubdomain: Optional[str] = Field(
|
82
|
+
None,
|
83
|
+
description="A special subdomain of funcaptcha.com, from which the JS captcha widget should be loaded."
|
84
|
+
"Most FunCaptcha installations work from shared domains.",
|
85
|
+
)
|
@@ -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()
|