twitter-openapi-python 0.1.1__py3-none-any.whl → 0.1.3__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.
@@ -2,6 +2,8 @@
2
2
 
3
3
  # flake8: noqa
4
4
 
5
+ from twitter_openapi_python.api.birdwatch_api import BirdwatchApiUtils
6
+ from twitter_openapi_python.api.community_api import CommunityApiUtils
5
7
  from twitter_openapi_python.api.default_api import DefaultApiUtils
6
8
  from twitter_openapi_python.api.initial_state_api import InitialStateApiUtils
7
9
  from twitter_openapi_python.api.post_api import PostApiUtils
@@ -0,0 +1,116 @@
1
+ from typing import Any, Optional
2
+
3
+ import twitter_openapi_python_generated as twitter
4
+ import twitter_openapi_python_generated.models as models
5
+ from x_client_transaction import ClientTransaction
6
+
7
+ from twitter_openapi_python.models import (
8
+ TimelineApiUtilsResponse,
9
+ TweetApiUtilsData,
10
+ TwitterApiUtilsResponse,
11
+ )
12
+ from twitter_openapi_python.utils import (
13
+ data_request,
14
+ error_check,
15
+ timeline_request,
16
+ tweet_entries_converter,
17
+ )
18
+
19
+ ResponseType = TwitterApiUtilsResponse[TimelineApiUtilsResponse[TweetApiUtilsData]]
20
+ ParamType = dict[str, Any]
21
+
22
+
23
+ class BirdwatchApiUtils:
24
+ """Community Notes."""
25
+
26
+ api: twitter.BirdwatchApi
27
+ flag: ParamType
28
+
29
+ def __init__(self, api: twitter.BirdwatchApi, flag: ParamType, ct: ClientTransaction):
30
+ self.api = api
31
+ self.flag = flag
32
+ self.ct = ct
33
+
34
+ def get_birdwatch_fetch_alias_self_select_status(
35
+ self,
36
+ extra_param: Optional[ParamType] = None,
37
+ ) -> TwitterApiUtilsResponse[models.BirdwatchAliasSelfSelectStatus]:
38
+ param: ParamType = {}
39
+ if extra_param is not None:
40
+ param.update(extra_param)
41
+ return data_request(
42
+ self.api.get_birdwatch_fetch_alias_self_select_status_with_http_info,
43
+ self.flag["BirdwatchFetchAliasSelfSelectStatus"],
44
+ self.ct,
45
+ lambda e: error_check(e.data, e.errors).authenticated_user_birdwatch_alias_self_select_status,
46
+ param,
47
+ )
48
+
49
+ def get_birdwatch_fetch_authenticated_user_profile(
50
+ self,
51
+ extra_param: Optional[ParamType] = None,
52
+ ) -> TwitterApiUtilsResponse[models.BirdwatchProfile]:
53
+ param: ParamType = {}
54
+ if extra_param is not None:
55
+ param.update(extra_param)
56
+ return data_request(
57
+ self.api.get_birdwatch_fetch_authenticated_user_profile_with_http_info,
58
+ self.flag["BirdwatchFetchAuthenticatedUserProfile"],
59
+ self.ct,
60
+ lambda e: error_check(e.data, e.errors).authenticated_user_birdwatch_profile,
61
+ param,
62
+ )
63
+
64
+ def get_birdwatch_fetch_birdwatch_profile(
65
+ self,
66
+ alias: str,
67
+ extra_param: Optional[ParamType] = None,
68
+ ) -> TwitterApiUtilsResponse[models.BirdwatchProfile]:
69
+ param: ParamType = {"alias": alias}
70
+ if extra_param is not None:
71
+ param.update(extra_param)
72
+ return data_request(
73
+ self.api.get_birdwatch_fetch_birdwatch_profile_with_http_info,
74
+ self.flag["BirdwatchFetchBirdwatchProfile"],
75
+ self.ct,
76
+ lambda e: error_check(e.data, e.errors).birdwatch_profile_by_alias,
77
+ param,
78
+ )
79
+
80
+ def get_birdwatch_fetch_global_timeline(
81
+ self,
82
+ cursor: Optional[str] = None,
83
+ extra_param: Optional[ParamType] = None,
84
+ ) -> ResponseType:
85
+ """Posts with notes on the Community Notes home page (first tab)."""
86
+ param: ParamType = {}
87
+ if cursor is not None:
88
+ param["cursor"] = cursor
89
+ if extra_param is not None:
90
+ param.update(extra_param)
91
+ return timeline_request(
92
+ self.api.get_birdwatch_fetch_global_timeline_with_http_info,
93
+ self.flag["BirdwatchFetchGlobalTimeline"],
94
+ self.ct,
95
+ lambda e: error_check(
96
+ e.data.viewer.birdwatch_home_page.body.initial_timeline.timeline.timeline, e.errors
97
+ ).instructions,
98
+ param,
99
+ tweet_entries_converter,
100
+ )
101
+
102
+ def get_birdwatch_fetch_public_data(
103
+ self,
104
+ extra_param: Optional[ParamType] = None,
105
+ ) -> TwitterApiUtilsResponse[models.BirdwatchPublicDataFileBundle]:
106
+ """Download urls of the latest public data files."""
107
+ param: ParamType = {}
108
+ if extra_param is not None:
109
+ param.update(extra_param)
110
+ return data_request(
111
+ self.api.get_birdwatch_fetch_public_data_with_http_info,
112
+ self.flag["BirdwatchFetchPublicData"],
113
+ self.ct,
114
+ lambda e: error_check(e.data, e.errors).birdwatch_latest_public_data_file_bundle,
115
+ param,
116
+ )
@@ -0,0 +1,149 @@
1
+ from typing import Any, List, Optional
2
+
3
+ import twitter_openapi_python_generated as twitter
4
+ import twitter_openapi_python_generated.models as models
5
+ from x_client_transaction import ClientTransaction
6
+
7
+ from twitter_openapi_python.models import (
8
+ TimelineApiUtilsResponse,
9
+ TweetApiUtilsData,
10
+ TwitterApiUtilsResponse,
11
+ )
12
+ from twitter_openapi_python.utils import (
13
+ data_request,
14
+ error_check,
15
+ timeline_request,
16
+ tweet_entries_converter,
17
+ )
18
+
19
+ ResponseType = TwitterApiUtilsResponse[TimelineApiUtilsResponse[TweetApiUtilsData]]
20
+ ParamType = dict[str, Any]
21
+
22
+
23
+ class CommunityApiUtils:
24
+ api: twitter.CommunityApi
25
+ flag: ParamType
26
+
27
+ def __init__(self, api: twitter.CommunityApi, flag: ParamType, ct: ClientTransaction):
28
+ self.api = api
29
+ self.flag = flag
30
+ self.ct = ct
31
+
32
+ def get_communities_fetch_one_query(
33
+ self,
34
+ community_id: str,
35
+ extra_param: Optional[ParamType] = None,
36
+ ) -> TwitterApiUtilsResponse[models.CommunityPageCommunity]:
37
+ """The community page (full members and moderators)."""
38
+ param: ParamType = {"communityId": community_id}
39
+ if extra_param is not None:
40
+ param.update(extra_param)
41
+ return data_request(
42
+ self.api.get_communities_fetch_one_query_with_http_info,
43
+ self.flag["CommunitiesFetchOneQuery"],
44
+ self.ct,
45
+ lambda e: error_check(e.data, e.errors).community_results.result,
46
+ param,
47
+ )
48
+
49
+ def get_community_query(
50
+ self,
51
+ community_id: str,
52
+ extra_param: Optional[ParamType] = None,
53
+ ) -> TwitterApiUtilsResponse[models.CommunitySettingsCommunity]:
54
+ """The community settings / moderation pages (partial users, trending hashtags)."""
55
+ param: ParamType = {"communityId": community_id}
56
+ if extra_param is not None:
57
+ param.update(extra_param)
58
+ return data_request(
59
+ self.api.get_community_query_with_http_info,
60
+ self.flag["CommunityQuery"],
61
+ self.ct,
62
+ lambda e: error_check(e.data, e.errors).community_results.result,
63
+ param,
64
+ )
65
+
66
+ def get_communities_search_query(
67
+ self,
68
+ query: str,
69
+ cursor: Optional[str] = None,
70
+ extra_param: Optional[ParamType] = None,
71
+ ) -> TwitterApiUtilsResponse[models.CommunitiesSearchSlice]:
72
+ """Community cards for a query; the next page is slice_info.next_cursor."""
73
+ param: ParamType = {"query": query}
74
+ if cursor is not None:
75
+ param["cursor"] = cursor
76
+ if extra_param is not None:
77
+ param.update(extra_param)
78
+ return data_request(
79
+ self.api.get_communities_search_query_with_http_info,
80
+ self.flag["CommunitiesSearchQuery"],
81
+ self.ct,
82
+ lambda e: error_check(e.data, e.errors).communities_search_slice,
83
+ param,
84
+ )
85
+
86
+ def get_topic_carousel_query(
87
+ self,
88
+ extra_param: Optional[ParamType] = None,
89
+ ) -> TwitterApiUtilsResponse[List[models.CommunityTopic]]:
90
+ param: ParamType = {}
91
+ if extra_param is not None:
92
+ param.update(extra_param)
93
+ return data_request(
94
+ self.api.get_topic_carousel_query_with_http_info,
95
+ self.flag["TopicCarouselQuery"],
96
+ self.ct,
97
+ lambda e: error_check(e.data, e.errors).community_topic_results.community_topics,
98
+ param,
99
+ )
100
+
101
+ def get_global_communities_post_search_timeline(
102
+ self,
103
+ raw_query: str,
104
+ cursor: Optional[str] = None,
105
+ count: Optional[int] = None,
106
+ extra_param: Optional[ParamType] = None,
107
+ ) -> ResponseType:
108
+ """Posts across communities (Top)."""
109
+ param: ParamType = {"rawQuery": raw_query}
110
+ if cursor is not None:
111
+ param["cursor"] = cursor
112
+ if count is not None:
113
+ param["count"] = count
114
+ if extra_param is not None:
115
+ param.update(extra_param)
116
+ return timeline_request(
117
+ self.api.get_global_communities_post_search_timeline_with_http_info,
118
+ self.flag["GlobalCommunitiesPostSearchTimeline"],
119
+ self.ct,
120
+ lambda e: error_check(e.data.search_by_raw_query.communities_posts_search_page.timeline, e.errors).instructions,
121
+ param,
122
+ tweet_entries_converter,
123
+ )
124
+
125
+ def get_global_communities_latest_post_search_timeline(
126
+ self,
127
+ raw_query: str,
128
+ cursor: Optional[str] = None,
129
+ count: Optional[int] = None,
130
+ extra_param: Optional[ParamType] = None,
131
+ ) -> ResponseType:
132
+ """Posts across communities (Latest)."""
133
+ param: ParamType = {"rawQuery": raw_query}
134
+ if cursor is not None:
135
+ param["cursor"] = cursor
136
+ if count is not None:
137
+ param["count"] = count
138
+ if extra_param is not None:
139
+ param.update(extra_param)
140
+ return timeline_request(
141
+ self.api.get_global_communities_latest_post_search_timeline_with_http_info,
142
+ self.flag["GlobalCommunitiesLatestPostSearchTimeline"],
143
+ self.ct,
144
+ lambda e: error_check(
145
+ e.data.search_by_raw_query.communities_latest_posts_search_page.timeline, e.errors
146
+ ).instructions,
147
+ param,
148
+ tweet_entries_converter,
149
+ )
@@ -78,3 +78,144 @@ class DefaultApiUtils:
78
78
  if response.data is None:
79
79
  raise Exception("No tweet")
80
80
  return response # type: ignore
81
+
82
+ def get_authenticate_periscope(
83
+ self,
84
+ extra_param: Optional[ParamType] = None,
85
+ ) -> TwitterApiUtilsResponse[str]:
86
+ """A Periscope (live video) token for the account."""
87
+ param: ParamType = {}
88
+ if extra_param is not None:
89
+ param.update(extra_param)
90
+ return self.request(
91
+ apiFn=self.api.get_authenticate_periscope_with_http_info,
92
+ convertFn=lambda x: error_check(x.data, x.errors).authenticate_periscope,
93
+ key="AuthenticatePeriscope",
94
+ param=param,
95
+ )
96
+
97
+ def get_creator_studio_tab_bar_item_query(
98
+ self,
99
+ extra_param: Optional[ParamType] = None,
100
+ ) -> TwitterApiUtilsResponse[models.CreatorStudioTabBarItemQueryResponseData]:
101
+ param: ParamType = {}
102
+ if extra_param is not None:
103
+ param.update(extra_param)
104
+ return self.request(
105
+ apiFn=self.api.get_creator_studio_tab_bar_item_query_with_http_info,
106
+ convertFn=lambda x: error_check(x.data, x.errors),
107
+ key="CreatorStudioTabBarItemQuery",
108
+ param=param,
109
+ )
110
+
111
+ def get_data_saver_mode(
112
+ self,
113
+ device_id: Optional[str] = None,
114
+ extra_param: Optional[ParamType] = None,
115
+ ) -> TwitterApiUtilsResponse[models.DataSaverModeResponseData]:
116
+ param: ParamType = {}
117
+ if device_id is not None:
118
+ param["device_id"] = device_id
119
+ if extra_param is not None:
120
+ param.update(extra_param)
121
+ return self.request(
122
+ apiFn=self.api.get_data_saver_mode_with_http_info,
123
+ convertFn=lambda x: error_check(x.data, x.errors),
124
+ key="DataSaverMode",
125
+ param=param,
126
+ )
127
+
128
+ def get_grok_home(
129
+ self,
130
+ extra_param: Optional[ParamType] = None,
131
+ ) -> TwitterApiUtilsResponse[models.GrokHome]:
132
+ """Grok model options, prompts and eligibility."""
133
+ param: ParamType = {}
134
+ if extra_param is not None:
135
+ param.update(extra_param)
136
+ return self.request(
137
+ apiFn=self.api.get_grok_home_with_http_info,
138
+ convertFn=lambda x: error_check(x.data, x.errors).grok_home,
139
+ key="GrokHome",
140
+ param=param,
141
+ )
142
+
143
+ def get_pinned_timelines(
144
+ self,
145
+ extra_param: Optional[ParamType] = None,
146
+ ) -> TwitterApiUtilsResponse[models.PinnedTimelines]:
147
+ param: ParamType = {}
148
+ if extra_param is not None:
149
+ param.update(extra_param)
150
+ return self.request(
151
+ apiFn=self.api.get_pinned_timelines_with_http_info,
152
+ convertFn=lambda x: error_check(x.data, x.errors).pinned_timelines,
153
+ key="PinnedTimelines",
154
+ param=param,
155
+ )
156
+
157
+ def get_broadcast_query(
158
+ self,
159
+ id: str,
160
+ extra_param: Optional[ParamType] = None,
161
+ ) -> TwitterApiUtilsResponse[models.Broadcast]:
162
+ """A live video broadcast by id."""
163
+ param: ParamType = {"id": id}
164
+ if extra_param is not None:
165
+ param.update(extra_param)
166
+ return self.request(
167
+ apiFn=self.api.get_broadcast_query_with_http_info,
168
+ convertFn=lambda x: error_check(x.data, x.errors).broadcast,
169
+ key="BroadcastQuery",
170
+ param=param,
171
+ )
172
+
173
+ def get_audio_space_by_id(
174
+ self,
175
+ id: str,
176
+ extra_param: Optional[ParamType] = None,
177
+ ) -> TwitterApiUtilsResponse[models.AudioSpace]:
178
+ """A Space by id: metadata, participants and the announcing post."""
179
+ param: ParamType = {"id": id}
180
+ if extra_param is not None:
181
+ param.update(extra_param)
182
+ return self.request(
183
+ apiFn=self.api.get_audio_space_by_id_with_http_info,
184
+ convertFn=lambda x: error_check(x.data, x.errors).audio_space,
185
+ key="AudioSpaceById",
186
+ param=param,
187
+ )
188
+
189
+ def get_use_story_topic_query(
190
+ self,
191
+ rest_id: str = "For You",
192
+ limit: Optional[int] = None,
193
+ extra_param: Optional[ParamType] = None,
194
+ ) -> TwitterApiUtilsResponse[models.StoryTopic]:
195
+ """AI-written stories of an explore topic."""
196
+ param: ParamType = {"rest_id": rest_id}
197
+ if limit is not None:
198
+ param["limit"] = limit
199
+ if extra_param is not None:
200
+ param.update(extra_param)
201
+ return self.request(
202
+ apiFn=self.api.get_use_story_topic_query_with_http_info,
203
+ convertFn=lambda x: error_check(x.data, x.errors).story_topic,
204
+ key="useStoryTopicQuery",
205
+ param=param,
206
+ )
207
+
208
+ def get_grok_account_jwt_query(
209
+ self,
210
+ extra_param: Optional[ParamType] = None,
211
+ ) -> TwitterApiUtilsResponse[models.GrokAccountJwt]:
212
+ """Whether the account is linked to a Grok account."""
213
+ param: ParamType = {}
214
+ if extra_param is not None:
215
+ param.update(extra_param)
216
+ return self.request(
217
+ apiFn=self.api.get_grok_account_jwt_query_with_http_info,
218
+ convertFn=lambda x: error_check(x.data, x.errors).grok_account_jwt,
219
+ key="grokAccountJwtQuery",
220
+ param=param,
221
+ )
@@ -93,9 +93,11 @@ class TweetApiUtils:
93
93
 
94
94
  response = self.request(
95
95
  apiFn=self.api.get_search_timeline_with_http_info,
96
- convertFn=lambda e: error_check(
97
- error_check(e.data.search_by_raw_query, e.errors).search_timeline.timeline, e.errors
98
- ).instructions,
96
+ convertFn=lambda e: (
97
+ error_check(
98
+ error_check(e.data.search_by_raw_query, e.errors).search_timeline.timeline, e.errors
99
+ ).instructions
100
+ ),
99
101
  key="SearchTimeline",
100
102
  param=param,
101
103
  )
@@ -162,9 +164,9 @@ class TweetApiUtils:
162
164
 
163
165
  response = self.request(
164
166
  apiFn=self.api.get_list_latest_tweets_timeline_with_http_info,
165
- convertFn=lambda e: error_check(
166
- error_check(e.data.list, e.errors).tweets_timeline.timeline, e.errors
167
- ).instructions,
167
+ convertFn=lambda e: (
168
+ error_check(error_check(e.data.list, e.errors).tweets_timeline.timeline, e.errors).instructions
169
+ ),
168
170
  key="ListLatestTweetsTimeline",
169
171
  param=param,
170
172
  )
@@ -187,9 +189,11 @@ class TweetApiUtils:
187
189
 
188
190
  response = self.request(
189
191
  apiFn=self.api.get_user_tweets_with_http_info,
190
- convertFn=lambda e: error_check(
191
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
192
- ).instructions,
192
+ convertFn=lambda e: (
193
+ error_check(
194
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
195
+ ).instructions
196
+ ),
193
197
  key="UserTweets",
194
198
  param=param,
195
199
  )
@@ -212,9 +216,11 @@ class TweetApiUtils:
212
216
 
213
217
  response = self.request(
214
218
  apiFn=self.api.get_user_originals_timeline_with_http_info,
215
- convertFn=lambda e: error_check(
216
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
217
- ).instructions,
219
+ convertFn=lambda e: (
220
+ error_check(
221
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
222
+ ).instructions
223
+ ),
218
224
  key="UserOriginalsTimeline",
219
225
  param=param,
220
226
  )
@@ -237,9 +243,11 @@ class TweetApiUtils:
237
243
 
238
244
  response = self.request(
239
245
  apiFn=self.api.get_user_replies_timeline_with_http_info,
240
- convertFn=lambda e: error_check(
241
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
242
- ).instructions,
246
+ convertFn=lambda e: (
247
+ error_check(
248
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
249
+ ).instructions
250
+ ),
243
251
  key="UserRepliesTimeline",
244
252
  param=param,
245
253
  )
@@ -262,9 +270,11 @@ class TweetApiUtils:
262
270
 
263
271
  response = self.request(
264
272
  apiFn=self.api.get_user_video_timeline_with_http_info,
265
- convertFn=lambda e: error_check(
266
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
267
- ).instructions,
273
+ convertFn=lambda e: (
274
+ error_check(
275
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
276
+ ).instructions
277
+ ),
268
278
  key="UserVideoTimeline",
269
279
  param=param,
270
280
  )
@@ -287,9 +297,11 @@ class TweetApiUtils:
287
297
 
288
298
  response = self.request(
289
299
  apiFn=self.api.get_user_tweets_and_replies_with_http_info,
290
- convertFn=lambda e: error_check(
291
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
292
- ).instructions,
300
+ convertFn=lambda e: (
301
+ error_check(
302
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
303
+ ).instructions
304
+ ),
293
305
  key="UserTweetsAndReplies",
294
306
  param=param,
295
307
  )
@@ -312,9 +324,11 @@ class TweetApiUtils:
312
324
 
313
325
  response = self.request(
314
326
  apiFn=self.api.get_user_media_with_http_info,
315
- convertFn=lambda e: error_check(
316
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
317
- ).instructions,
327
+ convertFn=lambda e: (
328
+ error_check(
329
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
330
+ ).instructions
331
+ ),
318
332
  key="UserMedia",
319
333
  param=param,
320
334
  )
@@ -337,9 +351,11 @@ class TweetApiUtils:
337
351
 
338
352
  response = self.request(
339
353
  apiFn=self.api.get_likes_with_http_info,
340
- convertFn=lambda e: error_check(
341
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
342
- ).instructions,
354
+ convertFn=lambda e: (
355
+ error_check(
356
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
357
+ ).instructions
358
+ ),
343
359
  key="Likes",
344
360
  param=param,
345
361
  )
@@ -361,9 +377,9 @@ class TweetApiUtils:
361
377
 
362
378
  response = self.request(
363
379
  apiFn=self.api.get_bookmarks_with_http_info,
364
- convertFn=lambda e: error_check(
365
- error_check(e.data, e.errors).bookmark_timeline_v2.timeline, e.errors
366
- ).instructions,
380
+ convertFn=lambda e: (
381
+ error_check(error_check(e.data, e.errors).bookmark_timeline_v2.timeline, e.errors).instructions
382
+ ),
367
383
  key="Bookmarks",
368
384
  param=param,
369
385
  )
@@ -389,9 +405,11 @@ class TweetApiUtils:
389
405
 
390
406
  response = self.request(
391
407
  apiFn=self.api.get_community_tweets_timeline_with_http_info,
392
- convertFn=lambda e: error_check(
393
- error_check(e.data, e.errors).community_results.result.ranked_community_timeline.timeline, e.errors
394
- ).instructions,
408
+ convertFn=lambda e: (
409
+ error_check(
410
+ error_check(e.data, e.errors).community_results.result.ranked_community_timeline.timeline, e.errors
411
+ ).instructions
412
+ ),
395
413
  key="CommunityTweetsTimeline",
396
414
  param=param,
397
415
  )
@@ -414,9 +432,11 @@ class TweetApiUtils:
414
432
 
415
433
  response = self.request(
416
434
  apiFn=self.api.get_community_media_timeline_with_http_info,
417
- convertFn=lambda e: error_check(
418
- error_check(e.data, e.errors).community_results.result.community_media_timeline.timeline, e.errors
419
- ).instructions,
435
+ convertFn=lambda e: (
436
+ error_check(
437
+ error_check(e.data, e.errors).community_results.result.community_media_timeline.timeline, e.errors
438
+ ).instructions
439
+ ),
420
440
  key="CommunityMediaTimeline",
421
441
  param=param,
422
442
  )
@@ -439,7 +459,9 @@ class TweetApiUtils:
439
459
 
440
460
  response = self.request(
441
461
  apiFn=self.api.get_user_highlights_tweets_with_http_info,
442
- convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
462
+ convertFn=lambda e: (
463
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline.instructions
464
+ ),
443
465
  key="UserHighlightsTweets",
444
466
  param=param,
445
467
  )
@@ -462,9 +484,11 @@ class TweetApiUtils:
462
484
 
463
485
  response = self.request(
464
486
  apiFn=self.api.get_user_reposts_timeline_with_http_info,
465
- convertFn=lambda e: error_check(
466
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
467
- ).instructions,
487
+ convertFn=lambda e: (
488
+ error_check(
489
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
490
+ ).instructions
491
+ ),
468
492
  key="UserRepostsTimeline",
469
493
  param=param,
470
494
  )
@@ -488,9 +512,11 @@ class TweetApiUtils:
488
512
 
489
513
  response = self.request(
490
514
  apiFn=self.api.get_user_super_follow_tweets_with_http_info,
491
- convertFn=lambda e: error_check(
492
- error_check(e.data.user, e.errors).result.timeline.timeline, e.errors
493
- ).instructions,
515
+ convertFn=lambda e: (
516
+ error_check(
517
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
518
+ ).instructions
519
+ ),
494
520
  key="UserSuperFollowTweets",
495
521
  param=param,
496
522
  )
@@ -564,9 +590,9 @@ class TweetApiUtils:
564
590
  self.api.get_notifications_timeline_with_http_info,
565
591
  self.flag["NotificationsTimeline"],
566
592
  self.ct,
567
- lambda e: error_check(
568
- e.data.viewer_v2.user_results.result.notification_timeline.timeline, e.errors
569
- ).instructions,
593
+ lambda e: (
594
+ error_check(e.data.viewer_v2.user_results.result.notification_timeline.timeline, e.errors).instructions
595
+ ),
570
596
  param,
571
597
  notification_entries_converter,
572
598
  )
@@ -636,3 +662,47 @@ class TweetApiUtils:
636
662
  param,
637
663
  lambda entry: user_result_converter(user_entries_converter(entry)),
638
664
  )
665
+
666
+ def get_bookmark_search_timeline(
667
+ self,
668
+ raw_query: str,
669
+ cursor: Optional[str] = None,
670
+ count: Optional[int] = None,
671
+ extra_param: Optional[ParamType] = None,
672
+ ) -> ResponseType:
673
+ """Search the account's bookmarks."""
674
+ param: ParamType = {"rawQuery": raw_query}
675
+ if cursor is not None:
676
+ param["cursor"] = cursor
677
+ if count is not None:
678
+ param["count"] = count
679
+ if extra_param is not None:
680
+ param.update(extra_param)
681
+
682
+ response = self.request(
683
+ apiFn=self.api.get_bookmark_search_timeline_with_http_info,
684
+ convertFn=lambda e: (
685
+ error_check(e.data.search_by_raw_query.bookmarks_search_timeline.timeline, e.errors).instructions
686
+ ),
687
+ key="BookmarkSearchTimeline",
688
+ param=param,
689
+ )
690
+ return response
691
+
692
+ def get_explore_sidebar(
693
+ self,
694
+ extra_param: Optional[ParamType] = None,
695
+ ) -> TrendResponseType:
696
+ """Trends of the explore sidebar."""
697
+ param: ParamType = {}
698
+ if extra_param is not None:
699
+ param.update(extra_param)
700
+
701
+ return timeline_request(
702
+ self.api.get_explore_sidebar_with_http_info,
703
+ self.flag["ExploreSidebar"],
704
+ self.ct,
705
+ lambda e: error_check(e.data.explore_sidebar.timeline, e.errors).instructions,
706
+ param,
707
+ trend_entries_converter,
708
+ )
@@ -80,6 +80,23 @@ class UserApiUtils:
80
80
  param=param,
81
81
  )
82
82
 
83
+ def get_about_account_query(
84
+ self,
85
+ screen_name: str,
86
+ extra_param: Optional[ParamType] = None,
87
+ ) -> TwitterApiUtilsResponse[models.AboutAccountUser]:
88
+ """The "About this account" panel: join date, where the account is based, username changes, verification."""
89
+ param: ParamType = {"screenName": screen_name}
90
+ if extra_param is not None:
91
+ param.update(extra_param)
92
+ return data_request(
93
+ self.api.get_about_account_query_with_http_info,
94
+ self.flag["AboutAccountQuery"],
95
+ self.ct,
96
+ lambda e: error_check(e.data, e.errors).user_result_by_screen_name.result,
97
+ param,
98
+ )
99
+
83
100
  def get_viewer_badge_counts(
84
101
  self,
85
102
  extra_param: Optional[ParamType] = None,
@@ -66,7 +66,9 @@ class UserListApiUtils:
66
66
  param.update(extra_param)
67
67
  return self.request(
68
68
  apiFn=self.api.get_followers_with_http_info,
69
- convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
69
+ convertFn=lambda e: (
70
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline.instructions
71
+ ),
70
72
  key="Followers",
71
73
  param=param,
72
74
  )
@@ -87,7 +89,9 @@ class UserListApiUtils:
87
89
  param.update(extra_param)
88
90
  return self.request(
89
91
  apiFn=self.api.get_following_with_http_info,
90
- convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
92
+ convertFn=lambda e: (
93
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline.instructions
94
+ ),
91
95
  key="Following",
92
96
  param=param,
93
97
  )
@@ -108,7 +112,9 @@ class UserListApiUtils:
108
112
  param.update(extra_param)
109
113
  return self.request(
110
114
  apiFn=self.api.get_followers_you_know_with_http_info,
111
- convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
115
+ convertFn=lambda e: (
116
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline.instructions
117
+ ),
112
118
  key="FollowersYouKnow",
113
119
  param=param,
114
120
  )
@@ -129,9 +135,9 @@ class UserListApiUtils:
129
135
  param.update(extra_param)
130
136
  return self.request(
131
137
  apiFn=self.api.get_favoriters_with_http_info,
132
- convertFn=lambda e: error_check(
133
- error_check(e.data.favoriters_timeline, e.errors).timeline, e.errors
134
- ).instructions,
138
+ convertFn=lambda e: (
139
+ error_check(error_check(e.data.favoriters_timeline, e.errors).timeline, e.errors).instructions
140
+ ),
135
141
  key="Favoriters",
136
142
  param=param,
137
143
  )
@@ -152,9 +158,9 @@ class UserListApiUtils:
152
158
  param.update(extra_param)
153
159
  return self.request(
154
160
  apiFn=self.api.get_retweeters_with_http_info,
155
- convertFn=lambda e: error_check(
156
- error_check(e.data.retweeters_timeline, e.errors).timeline, e.errors
157
- ).instructions,
161
+ convertFn=lambda e: (
162
+ error_check(error_check(e.data.retweeters_timeline, e.errors).timeline, e.errors).instructions
163
+ ),
158
164
  key="Retweeters",
159
165
  param=param,
160
166
  )
@@ -175,7 +181,9 @@ class UserListApiUtils:
175
181
  param.update(extra_param)
176
182
  return self.request(
177
183
  apiFn=self.api.get_blue_verified_followers_with_http_info,
178
- convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
184
+ convertFn=lambda e: (
185
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline.instructions
186
+ ),
179
187
  key="BlueVerifiedFollowers",
180
188
  param=param,
181
189
  )
@@ -282,7 +290,11 @@ class UserListApiUtils:
282
290
  self.api.get_list_ownerships_with_http_info,
283
291
  self.flag["ListOwnerships"],
284
292
  self.ct,
285
- lambda e: error_check(error_check(e.data.user, e.errors).result.timeline.timeline, e.errors).instructions,
293
+ lambda e: (
294
+ error_check(
295
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
296
+ ).instructions
297
+ ),
286
298
  param,
287
299
  list_entries_converter,
288
300
  )
@@ -302,3 +314,77 @@ class UserListApiUtils:
302
314
  lambda e: error_check(e.data, e.errors).list,
303
315
  param,
304
316
  )
317
+
318
+ def get_list_search_timeline(
319
+ self,
320
+ raw_query: str,
321
+ cursor: Optional[str] = None,
322
+ count: Optional[int] = None,
323
+ extra_param: Optional[ParamType] = None,
324
+ ) -> ListResponseType:
325
+ param: ParamType = {"rawQuery": raw_query}
326
+ if cursor is not None:
327
+ param["cursor"] = cursor
328
+ if count is not None:
329
+ param["count"] = count
330
+ if extra_param is not None:
331
+ param.update(extra_param)
332
+ return timeline_request(
333
+ self.api.get_list_search_timeline_with_http_info,
334
+ self.flag["ListSearchTimeline"],
335
+ self.ct,
336
+ lambda e: error_check(e.data.search_by_raw_query.list_search_timeline.timeline, e.errors).instructions,
337
+ param,
338
+ list_entries_converter,
339
+ )
340
+
341
+ def get_combined_lists(
342
+ self,
343
+ user_id: str,
344
+ cursor: Optional[str] = None,
345
+ count: Optional[int] = None,
346
+ extra_param: Optional[ParamType] = None,
347
+ ) -> ListResponseType:
348
+ """Lists a user owns or follows."""
349
+ param: ParamType = {"userId": user_id}
350
+ if cursor is not None:
351
+ param["cursor"] = cursor
352
+ if count is not None:
353
+ param["count"] = count
354
+ if extra_param is not None:
355
+ param.update(extra_param)
356
+ return timeline_request(
357
+ self.api.get_combined_lists_with_http_info,
358
+ self.flag["CombinedLists"],
359
+ self.ct,
360
+ lambda e: (
361
+ error_check(
362
+ error_check(error_check(e.data.user, e.errors).result.timeline, e.errors).timeline, e.errors
363
+ ).instructions
364
+ ),
365
+ param,
366
+ list_entries_converter,
367
+ )
368
+
369
+ def get_lists_management_page_timeline(
370
+ self,
371
+ cursor: Optional[str] = None,
372
+ count: Optional[int] = None,
373
+ extra_param: Optional[ParamType] = None,
374
+ ) -> ListResponseType:
375
+ """The account's lists management page."""
376
+ param: ParamType = {}
377
+ if cursor is not None:
378
+ param["cursor"] = cursor
379
+ if count is not None:
380
+ param["count"] = count
381
+ if extra_param is not None:
382
+ param.update(extra_param)
383
+ return timeline_request(
384
+ self.api.get_lists_management_page_timeline_with_http_info,
385
+ self.flag["ListsManagementPageTimeline"],
386
+ self.ct,
387
+ lambda e: error_check(e.data.viewer.list_management_timeline.timeline, e.errors).instructions,
388
+ param,
389
+ list_entries_converter,
390
+ )
@@ -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,37 @@ 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
+ )
75
+
76
+ def get_sidebar_user_recommendations(
77
+ self,
78
+ profile_user_id: str,
79
+ extra_param: Optional[ParamType] = None,
80
+ ) -> TwitterApiUtilsResponse[list[models.SidebarUserRecommendation]]:
81
+ """Who to follow, shown in the sidebar of a profile, each with its recommendation token."""
82
+ param: ParamType = {"profileUserId": profile_user_id}
83
+ if extra_param is not None:
84
+ param.update(extra_param)
85
+ return data_request(
86
+ self.api.get_sidebar_user_recommendations_with_http_info,
87
+ self.flag["SidebarUserRecommendations"],
88
+ self.ct,
89
+ lambda e: error_check(e.data, e.errors).sidebar_user_recommendations,
90
+ param,
91
+ )
@@ -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 = "ec7d907e12cfaca5b93dde55522dcc6045457570"
72
+ hash: str = "82d12f1e93e93cd283534f6abb4102bf7dc31c74"
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 = (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: twitter_openapi_python
3
- Version: 0.1.1
3
+ Version: 0.1.3
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.1
11
+ Requires-Dist: twitter-openapi-python-generated==0.1.3
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
@@ -1,15 +1,17 @@
1
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
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=Ca8OYS6TiYYVWo64QG-HUcmgog8FXwo5Xe8_-PUI6Js,7765
4
6
  twitter_openapi_python/api/initial_state_api.py,sha256=nAkb25-btWdMoSyyncxS_VrBQ9uKDgzmG7jBubfETYo,2269
5
7
  twitter_openapi_python/api/post_api.py,sha256=YSiGjV95AxxxSukZZESVRJ34D8hde6YRjd0Q6ElQ8fE,13166
6
- twitter_openapi_python/api/tweet_api.py,sha256=VktFxYf8XLIZjIUaON_rVzuImJIrCe5s7HYKpbqTSE0,22000
7
- twitter_openapi_python/api/user_api.py,sha256=CF9ST6jNI54H_ShBZLT-O1uu1h-xkaKKJmcQ0Au0H7g,4477
8
- twitter_openapi_python/api/user_list_api.py,sha256=EzBHlLNsbqTiXgZJoRR8SNru8Adr5F47SoAY6SxCrgM,10539
9
- twitter_openapi_python/api/users_api.py,sha256=8bcRi-kYZ9MtsgTxYDU1SnVqKtcyQ1b7QqWEVXVafqk,1750
8
+ twitter_openapi_python/api/tweet_api.py,sha256=qaFin2czb9SObvEz_ObMG6NOf7e_Da90m7Pkckon7rM,24226
9
+ twitter_openapi_python/api/user_api.py,sha256=zZFczuDwm7izp_WGFEgNTL4RQyN1aRPSijFTa8hZ_OI,5176
10
+ twitter_openapi_python/api/user_list_api.py,sha256=dCp_K0bIC0CBn_kI5B8hpKy0TVhZgET4zpfadc_TrZ0,13471
11
+ twitter_openapi_python/api/users_api.py,sha256=_vLDKAu5RfvPVwBeOcFpuSUd47fAgLjTLVK40dJuLMQ,3170
10
12
  twitter_openapi_python/api/v11_get_api.py,sha256=UXe34f6IBYExqWCJ8HCld_8d_ChQb92je0G5VtLxmyM,1978
11
13
  twitter_openapi_python/api/v11_post_api.py,sha256=eErGBOo-y4E1AAMIHgeWnc0rAFmc5KgIoipJI-8V0Y8,1781
12
- twitter_openapi_python/client.py,sha256=FSIArYbykUREGLISz9pcwYsux3xgDRgH_vkbM6zc2Ps,6786
14
+ twitter_openapi_python/client.py,sha256=Ra44Oxc-DfU_Jar93nXndVF_xjbPkYlCtT3JxAy5L_M,7126
13
15
  twitter_openapi_python/models/__init__.py,sha256=pHISZJrEPBlXS25kMydl1SxXuCct-CUpnPDfL7kEEBo,588
14
16
  twitter_openapi_python/models/base.py,sha256=3sw6wdQn9i8FoujFxhEFVWIB26-qjI6JTDuXKuebM0Y,189
15
17
  twitter_openapi_python/models/header.py,sha256=EKujtBRZOJmeh2SD1QOCsLWaE9gdGY4wsNUgwCnbTCU,644
@@ -20,8 +22,8 @@ twitter_openapi_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
20
22
  twitter_openapi_python/tid.py,sha256=xjqJMyPOp62nw2MQjMGHaB4L6G6OZHuWkMR-WKJo7aU,1120
21
23
  twitter_openapi_python/utils/__init__.py,sha256=lIEPoDqtgCvUk0A8cWqdTlTWMhkEp_NbVxL7sJ0uiu8,612
22
24
  twitter_openapi_python/utils/api.py,sha256=ytdYSv08LYGCe8gof4DptzhjCkgIBV1uJmJXC9htQnU,12623
23
- twitter_openapi_python-0.1.1.dist-info/licenses/LICENSE,sha256=sLv8EMhrPCMG_LeweYvYKS_B-cDMBwBSKZel7LSMGAs,1493
24
- twitter_openapi_python-0.1.1.dist-info/licenses/LICENSE.AGPL,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
25
- twitter_openapi_python-0.1.1.dist-info/WHEEL,sha256=9IUYslYuG_asT4WlWvfk_K76nveuLvSTKDoLeL0cV-Q,80
26
- twitter_openapi_python-0.1.1.dist-info/METADATA,sha256=KwMg1oNCnWMvRFro3Bh-Qi7Q88-ebem6u8b4vfoatUo,3232
27
- twitter_openapi_python-0.1.1.dist-info/RECORD,,
25
+ twitter_openapi_python-0.1.3.dist-info/licenses/LICENSE,sha256=sLv8EMhrPCMG_LeweYvYKS_B-cDMBwBSKZel7LSMGAs,1493
26
+ twitter_openapi_python-0.1.3.dist-info/licenses/LICENSE.AGPL,sha256=TfPDBt3ar0uv_f9cqCDMZ5rIzW3CY8anRRd4PkL6ejs,34522
27
+ twitter_openapi_python-0.1.3.dist-info/WHEEL,sha256=9IUYslYuG_asT4WlWvfk_K76nveuLvSTKDoLeL0cV-Q,80
28
+ twitter_openapi_python-0.1.3.dist-info/METADATA,sha256=yjdR3DLGE3SoEu6yuHgaoAgweBEwicaBYLfIi3-PaFk,3232
29
+ twitter_openapi_python-0.1.3.dist-info/RECORD,,