twitter-openapi-python 0.1.0__py3-none-any.whl → 0.1.2__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.
@@ -7,6 +7,7 @@ from x_client_transaction import ClientTransaction
7
7
  from twitter_openapi_python.models import TwitterApiUtilsResponse, UserApiUtilsData
8
8
  from twitter_openapi_python.utils import (
9
9
  build_response,
10
+ data_request,
10
11
  error_check,
11
12
  get_kwargs,
12
13
  user_result_converter,
@@ -54,3 +55,20 @@ class UsersApiUtils:
54
55
  key="UsersByRestIds",
55
56
  param=param,
56
57
  )
58
+
59
+ def get_users_verified_avatars(
60
+ self,
61
+ user_ids: list[str],
62
+ extra_param: Optional[ParamType] = None,
63
+ ) -> TwitterApiUtilsResponse[list[models.VerifiedAvatarUser]]:
64
+ """Partial users (avatar shape, verification) for the given ids."""
65
+ param: ParamType = {"userIds": user_ids}
66
+ if extra_param is not None:
67
+ param.update(extra_param)
68
+ return data_request(
69
+ self.api.get_users_verified_avatars_with_http_info,
70
+ self.flag["UsersVerifiedAvatars"],
71
+ self.ct,
72
+ lambda e: [x.result for x in error_check(e.data, e.errors).users_results],
73
+ param,
74
+ )
@@ -8,6 +8,8 @@ import urllib3
8
8
  from x_client_transaction import ClientTransaction
9
9
 
10
10
  from twitter_openapi_python.api import (
11
+ BirdwatchApiUtils,
12
+ CommunityApiUtils,
11
13
  DefaultApiUtils,
12
14
  InitialStateApiUtils,
13
15
  PostApiUtils,
@@ -32,6 +34,12 @@ class TwitterOpenapiPythonClient:
32
34
  self.placeholder = placeholder
33
35
  self.ct = ct
34
36
 
37
+ def get_birdwatch_api(self) -> BirdwatchApiUtils:
38
+ return BirdwatchApiUtils(twitter.BirdwatchApi(self.api), self.placeholder, self.ct)
39
+
40
+ def get_community_api(self) -> CommunityApiUtils:
41
+ return CommunityApiUtils(twitter.CommunityApi(self.api), self.placeholder, self.ct)
42
+
35
43
  def get_default_api(self) -> DefaultApiUtils:
36
44
  return DefaultApiUtils(twitter.DefaultApi(self.api), self.placeholder, self.ct)
37
45
 
@@ -61,7 +69,7 @@ class TwitterOpenapiPythonClient:
61
69
 
62
70
 
63
71
  class TwitterOpenapiPython:
64
- hash: str = "103dca20cc540be8dc8291e6f573c3d48ba7af3e"
72
+ hash: str = "127fa210d7f9b0252276c86a1860a7db816d9d69"
65
73
  placeholder_url = "https://raw.githubusercontent.com/fa0311/twitter-openapi/{hash}/src/config/placeholder.json"
66
74
  header = "https://raw.githubusercontent.com/fa0311/latest-user-agent/refs/heads/main/header.json"
67
75
  access_token: str = (
@@ -15,6 +15,7 @@ from twitter_openapi_python.models.response import (
15
15
  )
16
16
  from twitter_openapi_python.models.timeline import (
17
17
  ApiUtilsRaw,
18
+ CommunityApiUtilsData,
18
19
  CursorApiUtilsResponse,
19
20
  TimelineApiUtilsResponse,
20
21
  TweetApiUtilsData,
@@ -34,6 +34,11 @@ class UserApiUtilsData(BaseModel):
34
34
  user: models.User = Field()
35
35
 
36
36
 
37
+ class CommunityApiUtilsData(BaseModel):
38
+ raw: models.TimelineCommunity = Field()
39
+ community: models.Community = Field()
40
+
41
+
37
42
  class TimelineApiUtilsResponse(BaseModel, Generic[T]):
38
43
  raw: ApiUtilsRaw = Field()
39
44
  cursor: CursorApiUtilsResponse = Field()
@@ -8,11 +8,18 @@ from twitter_openapi_python.utils.api import (
8
8
  build_header,
9
9
  build_response,
10
10
  build_tweet_api_utils,
11
+ community_entries_converter,
12
+ data_request,
11
13
  error_check,
12
14
  entries_cursor,
13
15
  get_kwargs,
14
16
  get_legacy_kwargs,
15
17
  instruction_to_entry,
18
+ item_contents,
19
+ list_entries_converter,
20
+ notification_entries_converter,
21
+ timeline_request,
22
+ trend_entries_converter,
16
23
  tweet_entries_converter,
17
24
  tweet_results_converter,
18
25
  user_entries_converter,
@@ -1,5 +1,5 @@
1
1
  import json
2
- from typing import Any, Dict, List, Mapping, Optional, TypeGuard, TypeVar
2
+ from typing import Any, Callable, Dict, List, Mapping, Optional, TypeGuard, TypeVar
3
3
 
4
4
  import twitter_openapi_python_generated as twitter
5
5
  import twitter_openapi_python_generated.models as models
@@ -7,7 +7,10 @@ from x_client_transaction import ClientTransaction
7
7
 
8
8
  from twitter_openapi_python.models import (
9
9
  ApiUtilsHeader,
10
+ ApiUtilsRaw,
11
+ CommunityApiUtilsData,
10
12
  CursorApiUtilsResponse,
13
+ TimelineApiUtilsResponse,
11
14
  TweetApiUtilsData,
12
15
  TwitterApiUtilsRaw,
13
16
  TwitterApiUtilsResponse,
@@ -198,17 +201,45 @@ def tweet_results_converter(tweetResults: models.ItemResult) -> Optional[models.
198
201
  raise Exception()
199
202
 
200
203
 
204
+ def item_contents(item: List[models.TimelineAddEntry]) -> List[Any]:
205
+ """Every item of the entries, module items included (TimelineTweet, TimelineUser, TimelineTrend, ...)."""
206
+
207
+ def map_fn(x: models.TimelineAddEntry) -> List[Any]:
208
+ one_of = x.content.actual_instance
209
+ if isinstance(one_of, models.TimelineTimelineItem):
210
+ return [one_of.item_content.actual_instance]
211
+ elif isinstance(one_of, models.TimelineTimelineModule):
212
+ return [y.item.item_content.actual_instance for y in one_of.items or []]
213
+ return []
214
+
215
+ return flat(list(map(map_fn, item)))
216
+
217
+
201
218
  def user_entries_converter(
202
219
  item: list[models.TimelineAddEntry],
203
220
  ) -> list[models.UserResults]:
204
- def map_fn(x: models.TimelineAddEntry) -> Optional[models.UserResults]:
205
- one_of = x.content.actual_instance
206
- if isinstance(one_of, models.TimelineTimelineItem):
207
- item = one_of.item_content.actual_instance
208
- if isinstance(item, models.TimelineUser):
209
- return item.user_results
221
+ return [x.user_results for x in item_contents(item) if isinstance(x, models.TimelineUser)]
210
222
 
211
- return non_nullable_list(list(map(map_fn, item)))
223
+
224
+ def trend_entries_converter(item: List[models.TimelineAddEntry]) -> List[models.TimelineTrend]:
225
+ return [x for x in item_contents(item) if isinstance(x, models.TimelineTrend)]
226
+
227
+
228
+ def notification_entries_converter(item: List[models.TimelineAddEntry]) -> List[models.TimelineNotification]:
229
+ return [x for x in item_contents(item) if isinstance(x, models.TimelineNotification)]
230
+
231
+
232
+ def list_entries_converter(item: List[models.TimelineAddEntry]) -> List[models.TwitterList]:
233
+ return [x.list for x in item_contents(item) if isinstance(x, models.TimelineTwitterList)]
234
+
235
+
236
+ def community_entries_converter(item: List[models.TimelineAddEntry]) -> List[CommunityApiUtilsData]:
237
+ def map_fn(x: models.TimelineCommunity) -> Optional[CommunityApiUtilsData]:
238
+ community = x.community_results.result.actual_instance
239
+ if isinstance(community, models.Community):
240
+ return CommunityApiUtilsData(raw=x, community=community)
241
+
242
+ return non_nullable_list([map_fn(x) for x in item_contents(item) if isinstance(x, models.TimelineCommunity)])
212
243
 
213
244
 
214
245
  def user_result_converter(item: list[models.UserResults]) -> List[UserApiUtilsData]:
@@ -270,6 +301,36 @@ def build_header(headers: Dict[str, str]) -> ApiUtilsHeader:
270
301
  )
271
302
 
272
303
 
304
+ def timeline_request(
305
+ api_fn: Callable[..., twitter.ApiResponse[T1]],
306
+ flag: ParamType,
307
+ ct: ClientTransaction,
308
+ convert_fn: Callable[[T1], List[models.InstructionUnion]],
309
+ param: ParamType,
310
+ items_fn: Callable[[List[models.TimelineAddEntry]], List[T2]],
311
+ ) -> TwitterApiUtilsResponse[TimelineApiUtilsResponse[T2]]:
312
+ res = api_fn(**get_kwargs(flag=flag, additional=param, ct=ct))
313
+ instruction = convert_fn(res.data)
314
+ entry = instruction_to_entry(instruction)
315
+ data = TimelineApiUtilsResponse[T2](
316
+ raw=ApiUtilsRaw(instruction=instruction, entry=entry),
317
+ cursor=entries_cursor(entry),
318
+ data=items_fn(entry),
319
+ )
320
+ return build_response(res, data)
321
+
322
+
323
+ def data_request(
324
+ api_fn: Callable[..., twitter.ApiResponse[T1]],
325
+ flag: ParamType,
326
+ ct: ClientTransaction,
327
+ convert_fn: Callable[[T1], T2],
328
+ param: ParamType,
329
+ ) -> TwitterApiUtilsResponse[T2]:
330
+ res = api_fn(**get_kwargs(flag=flag, additional=param, ct=ct))
331
+ return build_response(res, convert_fn(res.data))
332
+
333
+
273
334
  def build_response(response: twitter.ApiResponse, data: T1) -> TwitterApiUtilsResponse[T1]:
274
335
  if response.headers is None:
275
336
  raise Exception("headers is None")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: twitter_openapi_python
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Twitter OpenAPI
5
5
  Keywords: twitter,api,python,scraper
6
6
  Author: fa0311
@@ -8,7 +8,7 @@ Author-email: fa0311 <yuki@yuki0311.com>
8
8
  License-Expression: LicenseRef-Custom OR AGPL-3.0-or-later
9
9
  License-File: LICENSE
10
10
  License-File: LICENSE.AGPL
11
- Requires-Dist: twitter-openapi-python-generated==0.1.0
11
+ Requires-Dist: twitter-openapi-python-generated==0.1.2
12
12
  Requires-Dist: pydantic>=2.6
13
13
  Requires-Dist: requests>=2.31.0,<3.0.0
14
14
  Requires-Dist: urllib3>=2.1.0,<3.0.0
@@ -0,0 +1,29 @@
1
+ twitter_openapi_python/__init__.py,sha256=IyCanHNVJtKPGaYEMBqF37VXfMtZNUJlPhSOZMvO5jg,324
2
+ twitter_openapi_python/api/__init__.py,sha256=1YPsr8wnqlrBFAViXCwYwDdk2kNwA6PMC8DAnsWC62U,772
3
+ twitter_openapi_python/api/birdwatch_api.py,sha256=_SpT0-RU3GhEvYa9Sqf7JpC62kxnE-u0CbUnCHNTrBM,4121
4
+ twitter_openapi_python/api/community_api.py,sha256=hht31A83v3BfqcYa1-H9LyNIKd7UJMUWM9kzMUEJCus,5379
5
+ twitter_openapi_python/api/default_api.py,sha256=iuzWVgQsjZtsa5E6fVXESOJzXVx0u7iVnfGPwjo96hs,5334
6
+ twitter_openapi_python/api/initial_state_api.py,sha256=nAkb25-btWdMoSyyncxS_VrBQ9uKDgzmG7jBubfETYo,2269
7
+ twitter_openapi_python/api/post_api.py,sha256=YSiGjV95AxxxSukZZESVRJ34D8hde6YRjd0Q6ElQ8fE,13166
8
+ twitter_openapi_python/api/tweet_api.py,sha256=gBa0-7Pwvfau56SpTuY30t7-7wZ-2txRefW8vTnLZoE,23476
9
+ twitter_openapi_python/api/user_api.py,sha256=CF9ST6jNI54H_ShBZLT-O1uu1h-xkaKKJmcQ0Au0H7g,4477
10
+ twitter_openapi_python/api/user_list_api.py,sha256=VNMbvGxwV5t-77-H5x6vs55bcnbnVW5rRk9AjwKk2mw,13061
11
+ twitter_openapi_python/api/users_api.py,sha256=u7jauEpXJ-beXcOl054Vpz8WZOIh2ubma0bPnU5JECY,2440
12
+ twitter_openapi_python/api/v11_get_api.py,sha256=UXe34f6IBYExqWCJ8HCld_8d_ChQb92je0G5VtLxmyM,1978
13
+ twitter_openapi_python/api/v11_post_api.py,sha256=eErGBOo-y4E1AAMIHgeWnc0rAFmc5KgIoipJI-8V0Y8,1781
14
+ twitter_openapi_python/client.py,sha256=jeh0TGhNcBjyghnwaSV9Uz6YrmKf_3S1VFAbcgwMv8c,7126
15
+ twitter_openapi_python/models/__init__.py,sha256=pHISZJrEPBlXS25kMydl1SxXuCct-CUpnPDfL7kEEBo,588
16
+ twitter_openapi_python/models/base.py,sha256=3sw6wdQn9i8FoujFxhEFVWIB26-qjI6JTDuXKuebM0Y,189
17
+ twitter_openapi_python/models/header.py,sha256=EKujtBRZOJmeh2SD1QOCsLWaE9gdGY4wsNUgwCnbTCU,644
18
+ twitter_openapi_python/models/initial_state.py,sha256=XULKiYznCIG5TsLfV5RGPD_xOiE2bmKt1C8EtL-tQKM,513
19
+ twitter_openapi_python/models/response.py,sha256=ziBYbwdGSeCN3zfu5mFTTd8613zaZetzkZf8y_roTaI,461
20
+ twitter_openapi_python/models/timeline.py,sha256=dRMoc7zqyW_E2iehs4F6HfX8Iy_1b-e3Uo_c2b6Apbg,1484
21
+ twitter_openapi_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ twitter_openapi_python/tid.py,sha256=xjqJMyPOp62nw2MQjMGHaB4L6G6OZHuWkMR-WKJo7aU,1120
23
+ twitter_openapi_python/utils/__init__.py,sha256=lIEPoDqtgCvUk0A8cWqdTlTWMhkEp_NbVxL7sJ0uiu8,612
24
+ twitter_openapi_python/utils/api.py,sha256=ytdYSv08LYGCe8gof4DptzhjCkgIBV1uJmJXC9htQnU,12623
25
+ twitter_openapi_python-0.1.2.dist-info/licenses/LICENSE,sha256=sLv8EMhrPCMG_LeweYvYKS_B-cDMBwBSKZel7LSMGAs,1493
26
+ twitter_openapi_python-0.1.2.dist-info/licenses/LICENSE.AGPL,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
27
+ twitter_openapi_python-0.1.2.dist-info/WHEEL,sha256=9IUYslYuG_asT4WlWvfk_K76nveuLvSTKDoLeL0cV-Q,80
28
+ twitter_openapi_python-0.1.2.dist-info/METADATA,sha256=Cm2f6SkQGROikAKlvltINUo-9xUaMtW4i50SOyt5kYY,3232
29
+ twitter_openapi_python-0.1.2.dist-info/RECORD,,
@@ -1,27 +0,0 @@
1
- twitter_openapi_python/__init__.py,sha256=IyCanHNVJtKPGaYEMBqF37VXfMtZNUJlPhSOZMvO5jg,324
2
- twitter_openapi_python/api/__init__.py,sha256=m9S_EoojMhead7EToafmdHKUxpyYHm9-qaKN_auWhSM,630
3
- twitter_openapi_python/api/default_api.py,sha256=34l_jG5Mq1u0StPRX-QfGYHoGVYP8EEY_-5vFG_Xz7o,2586
4
- twitter_openapi_python/api/initial_state_api.py,sha256=nAkb25-btWdMoSyyncxS_VrBQ9uKDgzmG7jBubfETYo,2269
5
- twitter_openapi_python/api/post_api.py,sha256=uM-TzRKJQo5mFLXk8h8eu0zfYRXAvIZ0uRWA1eCnyuU,6526
6
- twitter_openapi_python/api/tweet_api.py,sha256=F-oa2FJk4ySkUPkALp3cRindjsisbkCdyZh9XTLrRnQ,14178
7
- twitter_openapi_python/api/user_api.py,sha256=AmGhdLrIidDwNn9eOmA3O0kYKbyustv3ZlrZdxTcvwc,2457
8
- twitter_openapi_python/api/user_list_api.py,sha256=KYNYZfBFuvvZQERJcVjj5ZYc93tuCLNNOMv7r3dknOo,5502
9
- twitter_openapi_python/api/users_api.py,sha256=8bcRi-kYZ9MtsgTxYDU1SnVqKtcyQ1b7QqWEVXVafqk,1750
10
- twitter_openapi_python/api/v11_get_api.py,sha256=UXe34f6IBYExqWCJ8HCld_8d_ChQb92je0G5VtLxmyM,1978
11
- twitter_openapi_python/api/v11_post_api.py,sha256=eErGBOo-y4E1AAMIHgeWnc0rAFmc5KgIoipJI-8V0Y8,1781
12
- twitter_openapi_python/client.py,sha256=LUGEgRmCgnqNJJwQu1WO3ssJfQjVUzhvnf7vchF1UuM,6786
13
- twitter_openapi_python/models/__init__.py,sha256=Mt28XGFXzAauvwrjFhKyKpo2ZoN7uP_TMq-d9JuM9qk,561
14
- twitter_openapi_python/models/base.py,sha256=3sw6wdQn9i8FoujFxhEFVWIB26-qjI6JTDuXKuebM0Y,189
15
- twitter_openapi_python/models/header.py,sha256=EKujtBRZOJmeh2SD1QOCsLWaE9gdGY4wsNUgwCnbTCU,644
16
- twitter_openapi_python/models/initial_state.py,sha256=XULKiYznCIG5TsLfV5RGPD_xOiE2bmKt1C8EtL-tQKM,513
17
- twitter_openapi_python/models/response.py,sha256=ziBYbwdGSeCN3zfu5mFTTd8613zaZetzkZf8y_roTaI,461
18
- twitter_openapi_python/models/timeline.py,sha256=5oyOUgCtrfuY8hDPVgAL2-s7Ma4jOdzWtV8kiCR1V98,1356
19
- twitter_openapi_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- twitter_openapi_python/tid.py,sha256=xjqJMyPOp62nw2MQjMGHaB4L6G6OZHuWkMR-WKJo7aU,1120
21
- twitter_openapi_python/utils/__init__.py,sha256=dCcm68kn5uv5rCRMLRd0rpeN6hAKulIz9khp0HLgx1c,427
22
- twitter_openapi_python/utils/api.py,sha256=k51VenadKXzLeoA_fS9YyAb_Ufx6Hz7p_l3WnITdUBs,10131
23
- twitter_openapi_python-0.1.0.dist-info/licenses/LICENSE,sha256=sLv8EMhrPCMG_LeweYvYKS_B-cDMBwBSKZel7LSMGAs,1493
24
- twitter_openapi_python-0.1.0.dist-info/licenses/LICENSE.AGPL,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
25
- twitter_openapi_python-0.1.0.dist-info/WHEEL,sha256=9IUYslYuG_asT4WlWvfk_K76nveuLvSTKDoLeL0cV-Q,80
26
- twitter_openapi_python-0.1.0.dist-info/METADATA,sha256=c1EtDT83hxNtKvGdwrrHX77NyF-k1LEtR69Kohl-hkw,3232
27
- twitter_openapi_python-0.1.0.dist-info/RECORD,,