twitter-openapi-python 0.0.25__py3-none-any.whl → 0.0.27__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.
@@ -1,4 +1,4 @@
1
- from typing import Any, Callable, Optional, Type, TypeVar
1
+ from typing import Any, Callable, Optional, TypeVar
2
2
 
3
3
  import twitter_openapi_python_generated as twitter
4
4
  import twitter_openapi_python_generated.models as models
@@ -7,13 +7,13 @@ from twitter_openapi_python.models import TweetApiUtilsData, TwitterApiUtilsResp
7
7
  from twitter_openapi_python.utils import (
8
8
  build_response,
9
9
  build_tweet_api_utils,
10
- check_error,
11
10
  get_kwargs,
12
11
  )
12
+ from twitter_openapi_python.utils.api import error_check
13
13
 
14
14
  T1 = TypeVar("T1")
15
15
  T2 = TypeVar("T2")
16
- ApiFnType = Callable[..., twitter.ApiResponse]
16
+ ApiFnType = Callable[..., twitter.ApiResponse[T1]]
17
17
  ParamType = dict[str, Any]
18
18
 
19
19
 
@@ -27,20 +27,15 @@ class DefaultApiUtils:
27
27
 
28
28
  def request(
29
29
  self,
30
- apiFn: ApiFnType,
30
+ apiFn: "ApiFnType[T1]",
31
31
  convertFn: Callable[[T1], T2],
32
- type1: Type[T1],
33
- type2: Type[T2],
34
32
  key: str,
35
33
  param: ParamType,
36
- ) -> TwitterApiUtilsResponse[T2]:
34
+ ):
37
35
  args = get_kwargs(flag=self.flag[key], additional=param)
38
36
  res = apiFn(**args)
39
- checked = check_error(data=res, type=type1)
40
-
41
- data = convertFn(checked)
42
-
43
- return build_response(response=res, data=data)
37
+ data = convertFn(res.data)
38
+ return build_response(res, data)
44
39
 
45
40
  def get_profile_spotlights_query(
46
41
  self,
@@ -55,9 +50,7 @@ class DefaultApiUtils:
55
50
 
56
51
  response = self.request(
57
52
  apiFn=self.api.get_profile_spotlights_query_with_http_info,
58
- convertFn=lambda x: x.data.user_result_by_screen_name,
59
- type1=models.ProfileResponse,
60
- type2=models.UserResultByScreenName,
53
+ convertFn=lambda x: error_check(x.data.user_result_by_screen_name, x.errors),
61
54
  key="ProfileSpotlightsQuery",
62
55
  param=param,
63
56
  )
@@ -74,9 +67,9 @@ class DefaultApiUtils:
74
67
 
75
68
  response = self.request(
76
69
  apiFn=self.api.get_tweet_result_by_rest_id_with_http_info,
77
- convertFn=lambda x: build_tweet_api_utils(x.data.tweet_result),
78
- type1=models.TweetResultByRestIdResponse,
79
- type2=TweetApiUtilsData,
70
+ convertFn=lambda x: error_check(
71
+ build_tweet_api_utils(error_check(x.data.tweet_result, x.errors)), x.errors
72
+ ),
80
73
  key="TweetResultByRestId",
81
74
  param=param,
82
75
  )
@@ -33,9 +33,7 @@ class InitialStateApiUtils:
33
33
  def get_initial_state(self, url: str) -> InitialStateApiUtilsResponse:
34
34
  response = self.request(url=url).data.decode("utf-8")
35
35
  reg = '<script type="text/javascript" charset="utf-8" nonce="{nonce}">{any}</script>'
36
- js = re.search(
37
- reg.format(nonce=r"([a-zA-Z0-9]{48})", any=r"([\s\S]*?)"), response
38
- )
36
+ js = re.search(reg.format(nonce=r"([a-zA-Z0-9]{48})", any=r"([\s\S]*?)"), response)
39
37
 
40
38
  if js is None:
41
39
  raise Exception("js is None")
@@ -56,14 +54,14 @@ class InitialStateApiUtils:
56
54
  def get_user(e: dict[str, Any]) -> Optional[models.UserLegacy]:
57
55
  try:
58
56
  entities = e["entities"]["users"]["entities"]
59
- return models.UserLegacy.parse_obj(list(entities.values())[0])
57
+ return models.UserLegacy.model_validate(list(entities.values())[0])
60
58
  except Exception:
61
59
  # todo: fix
62
60
  return None
63
61
 
64
62
  def get_session(e: dict[str, Any]) -> Optional[models.Session]:
65
63
  try:
66
- return models.Session.parse_obj(e["session"])
64
+ return models.Session.model_validate(e["session"])
67
65
  except Exception:
68
66
  return None
69
67
 
@@ -4,7 +4,7 @@ import twitter_openapi_python_generated as twitter
4
4
  import twitter_openapi_python_generated.models as models
5
5
 
6
6
  from twitter_openapi_python.models import TwitterApiUtilsResponse
7
- from twitter_openapi_python.utils import build_response, check_error, non_nullable
7
+ from twitter_openapi_python.utils import build_response, non_nullable
8
8
 
9
9
  T = TypeVar("T")
10
10
  ResponseType = TwitterApiUtilsResponse[T]
@@ -19,14 +19,6 @@ class PostApiUtils:
19
19
  self.api = api
20
20
  self.flag = flag
21
21
 
22
- def builder(
23
- self,
24
- res: twitter.ApiResponse,
25
- type: type[T],
26
- ) -> ResponseType[T]:
27
- checked = check_error(data=res, type=type)
28
- return build_response(response=res, data=checked)
29
-
30
22
  def post_create_tweet(
31
23
  self,
32
24
  tweet_text: str,
@@ -37,15 +29,9 @@ class PostApiUtils:
37
29
  conversation_control: Optional[str] = None,
38
30
  ) -> ResponseType[models.CreateTweetResponse]:
39
31
  variables = non_nullable(
40
- twitter.PostCreateTweetRequestVariables.from_dict(
41
- self.flag["CreateTweet"]["variables"]
42
- )
43
- )
44
- features = non_nullable(
45
- twitter.PostCreateTweetRequestFeatures.from_dict(
46
- self.flag["CreateTweet"]["features"]
47
- )
32
+ twitter.PostCreateTweetRequestVariables.from_dict(self.flag["CreateTweet"]["variables"])
48
33
  )
34
+ features = non_nullable(twitter.PostCreateTweetRequestFeatures.from_dict(self.flag["CreateTweet"]["features"]))
49
35
  variables.tweet_text = tweet_text
50
36
  if media_ids:
51
37
  tagged_or = tagged_users or []
@@ -58,10 +44,8 @@ class PostApiUtils:
58
44
  ]
59
45
  variables.attachment_url = attachment_url
60
46
  if conversation_control:
61
- variables.conversation_control = (
62
- twitter.PostCreateTweetRequestVariablesConversationControl(
63
- mode=conversation_control
64
- )
47
+ variables.conversation_control = twitter.PostCreateTweetRequestVariablesConversationControl(
48
+ mode=conversation_control
65
49
  )
66
50
 
67
51
  if in_reply_to_tweet_id:
@@ -78,17 +62,14 @@ class PostApiUtils:
78
62
  features=features,
79
63
  ),
80
64
  )
81
-
82
- return self.builder(res=res, type=models.CreateTweetResponse)
65
+ return build_response(res, res.data)
83
66
 
84
67
  def post_delete_tweet(
85
68
  self,
86
69
  tweet_id: str,
87
70
  ) -> ResponseType[models.DeleteTweetResponse]:
88
71
  variables = non_nullable(
89
- twitter.PostCreateRetweetRequestVariables.from_dict(
90
- self.flag["DeleteTweet"]["variables"]
91
- )
72
+ twitter.PostCreateRetweetRequestVariables.from_dict(self.flag["DeleteTweet"]["variables"])
92
73
  )
93
74
  variables.tweet_id = tweet_id
94
75
 
@@ -99,17 +80,14 @@ class PostApiUtils:
99
80
  variables=variables,
100
81
  ),
101
82
  )
102
-
103
- return self.builder(res=res, type=models.DeleteTweetResponse)
83
+ return build_response(res, res.data)
104
84
 
105
85
  def post_create_retweet(
106
86
  self,
107
87
  tweet_id: str,
108
88
  ) -> ResponseType[models.CreateRetweetResponse]:
109
89
  variables = non_nullable(
110
- twitter.PostCreateRetweetRequestVariables.from_dict(
111
- self.flag["CreateRetweet"]["variables"]
112
- )
90
+ twitter.PostCreateRetweetRequestVariables.from_dict(self.flag["CreateRetweet"]["variables"])
113
91
  )
114
92
  variables.tweet_id = tweet_id
115
93
 
@@ -120,17 +98,14 @@ class PostApiUtils:
120
98
  variables=variables,
121
99
  ),
122
100
  )
123
-
124
- return self.builder(res=res, type=models.CreateRetweetResponse)
101
+ return build_response(res, res.data)
125
102
 
126
103
  def post_delete_retweet(
127
104
  self,
128
105
  source_tweet_id: str,
129
106
  ) -> ResponseType[models.DeleteRetweetResponse]:
130
107
  variables = non_nullable(
131
- twitter.PostDeleteRetweetRequestVariables.from_dict(
132
- self.flag["DeleteRetweet"]["variables"]
133
- )
108
+ twitter.PostDeleteRetweetRequestVariables.from_dict(self.flag["DeleteRetweet"]["variables"])
134
109
  )
135
110
  variables.source_tweet_id = source_tweet_id
136
111
 
@@ -141,18 +116,15 @@ class PostApiUtils:
141
116
  variables=variables,
142
117
  ),
143
118
  )
144
-
145
- return self.builder(res=res, type=models.DeleteRetweetResponse)
119
+ return build_response(res, res.data)
146
120
 
147
121
  # postFavoriteTweet
148
122
  def post_favorite_tweet(
149
123
  self,
150
124
  tweet_id: str,
151
- ) -> ResponseType[models.FavoriteTweetResponseData]:
125
+ ) -> ResponseType[models.FavoriteTweetResponse]:
152
126
  variables = non_nullable(
153
- twitter.PostCreateBookmarkRequestVariables.from_dict(
154
- self.flag["FavoriteTweet"]["variables"]
155
- )
127
+ twitter.PostCreateBookmarkRequestVariables.from_dict(self.flag["FavoriteTweet"]["variables"])
156
128
  )
157
129
  variables.tweet_id = tweet_id
158
130
 
@@ -163,17 +135,15 @@ class PostApiUtils:
163
135
  variables=variables,
164
136
  ),
165
137
  )
166
- return self.builder(res=res, type=models.FavoriteTweetResponseData)
138
+ return build_response(res, res.data)
167
139
 
168
140
  # postUnfavoriteTweet
169
141
  def post_unfavorite_tweet(
170
142
  self,
171
143
  tweet_id: str,
172
- ) -> ResponseType[models.UnfavoriteTweetResponseData]:
144
+ ) -> ResponseType[models.UnfavoriteTweetResponse]:
173
145
  variables = non_nullable(
174
- twitter.PostCreateRetweetRequestVariables.from_dict(
175
- self.flag["UnfavoriteTweet"]["variables"]
176
- )
146
+ twitter.PostCreateRetweetRequestVariables.from_dict(self.flag["UnfavoriteTweet"]["variables"])
177
147
  )
178
148
  variables.tweet_id = tweet_id
179
149
 
@@ -184,4 +154,4 @@ class PostApiUtils:
184
154
  variables=variables,
185
155
  ),
186
156
  )
187
- return self.builder(res=res, type=models.UnfavoriteTweetResponseData)
157
+ return build_response(res, res.data)
@@ -1,4 +1,4 @@
1
- from typing import Any, Callable, List, Optional, Type, TypeVar
1
+ from typing import Any, Callable, List, Optional, TypeVar
2
2
 
3
3
  import twitter_openapi_python_generated as twitter
4
4
  import twitter_openapi_python_generated.models as models
@@ -11,17 +11,16 @@ from twitter_openapi_python.models import (
11
11
  )
12
12
  from twitter_openapi_python.utils import (
13
13
  build_response,
14
- check_error,
15
14
  entries_cursor,
15
+ error_check,
16
16
  get_kwargs,
17
17
  instruction_to_entry,
18
18
  tweet_entries_converter,
19
19
  )
20
- from twitter_openapi_python.utils.api import non_nullable
21
20
 
22
21
  T = TypeVar("T")
23
22
  ResponseType = TwitterApiUtilsResponse[TimelineApiUtilsResponse[TweetApiUtilsData]]
24
- ApiFnType = Callable[..., twitter.ApiResponse]
23
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
25
24
  ParamType = dict[str, Any]
26
25
 
27
26
 
@@ -35,17 +34,14 @@ class TweetApiUtils:
35
34
 
36
35
  def request(
37
36
  self,
38
- apiFn: ApiFnType,
37
+ apiFn: "ApiFnType[T]",
39
38
  convertFn: Callable[[T], List[models.InstructionUnion]],
40
- type: Type[T],
41
39
  key: str,
42
40
  param: ParamType,
43
41
  ) -> ResponseType:
44
42
  args = get_kwargs(flag=self.flag[key], additional=param)
45
43
  res = apiFn(**args)
46
- checked = check_error(data=res, type=type)
47
-
48
- instruction = convertFn(checked)
44
+ instruction = convertFn(res.data)
49
45
  entry = instruction_to_entry(instruction)
50
46
  tweet_list = tweet_entries_converter(entry)
51
47
  raw = ApiUtilsRaw(
@@ -57,8 +53,7 @@ class TweetApiUtils:
57
53
  cursor=entries_cursor(entry),
58
54
  data=tweet_list,
59
55
  )
60
-
61
- return build_response(response=res, data=data)
56
+ return build_response(res, data)
62
57
 
63
58
  def get_tweet_detail(
64
59
  self,
@@ -77,8 +72,7 @@ class TweetApiUtils:
77
72
 
78
73
  response = self.request(
79
74
  apiFn=self.api.get_tweet_detail_with_http_info,
80
- convertFn=lambda e: e.data.threaded_conversation_with_injections_v2.instructions,
81
- type=models.TweetDetailResponse,
75
+ convertFn=lambda e: error_check(e.data.threaded_conversation_with_injections_v2, e.errors).instructions,
82
76
  key="TweetDetail",
83
77
  param=param,
84
78
  )
@@ -104,8 +98,7 @@ class TweetApiUtils:
104
98
 
105
99
  response = self.request(
106
100
  apiFn=self.api.get_search_timeline_with_http_info,
107
- convertFn=lambda e: e.data.search_by_raw_query.search_timeline.timeline.instructions,
108
- type=models.SearchTimelineResponse,
101
+ convertFn=lambda e: error_check(e.data.search_by_raw_query, e.errors).search_timeline.timeline.instructions,
109
102
  key="SearchTimeline",
110
103
  param=param,
111
104
  )
@@ -127,8 +120,7 @@ class TweetApiUtils:
127
120
 
128
121
  response = self.request(
129
122
  apiFn=self.api.get_home_timeline_with_http_info,
130
- convertFn=lambda e: e.data.home.home_timeline_urt.instructions,
131
- type=models.TimelineResponse,
123
+ convertFn=lambda e: error_check(e.data.home, e.errors).home_timeline_urt.instructions,
132
124
  key="HomeTimeline",
133
125
  param=param,
134
126
  )
@@ -150,8 +142,7 @@ class TweetApiUtils:
150
142
 
151
143
  response = self.request(
152
144
  apiFn=self.api.get_home_latest_timeline_with_http_info,
153
- convertFn=lambda e: e.data.home.home_timeline_urt.instructions,
154
- type=models.TimelineResponse,
145
+ convertFn=lambda e: error_check(e.data.home, e.errors).home_timeline_urt.instructions,
155
146
  key="HomeLatestTimeline",
156
147
  param=param,
157
148
  )
@@ -174,10 +165,9 @@ class TweetApiUtils:
174
165
 
175
166
  response = self.request(
176
167
  apiFn=self.api.get_list_latest_tweets_timeline_with_http_info,
177
- convertFn=lambda e: []
178
- if (x := e.data.list.tweets_timeline.timeline) is None
179
- else x.instructions,
180
- type=models.ListLatestTweetsTimelineResponse,
168
+ convertFn=lambda e: error_check(
169
+ error_check(e.data.list, e.errors).tweets_timeline.timeline, e.errors
170
+ ).instructions,
181
171
  key="ListLatestTweetsTimeline",
182
172
  param=param,
183
173
  )
@@ -200,10 +190,9 @@ class TweetApiUtils:
200
190
 
201
191
  response = self.request(
202
192
  apiFn=self.api.get_user_tweets_with_http_info,
203
- convertFn=lambda e: non_nullable(
204
- e.data.user.result.timeline_v2.timeline
193
+ convertFn=lambda e: error_check(
194
+ error_check(e.data.user, e.errors).result.timeline_v2.timeline, e.errors
205
195
  ).instructions,
206
- type=models.UserTweetsResponse,
207
196
  key="UserTweets",
208
197
  param=param,
209
198
  )
@@ -226,10 +215,9 @@ class TweetApiUtils:
226
215
 
227
216
  response = self.request(
228
217
  apiFn=self.api.get_user_tweets_and_replies_with_http_info,
229
- convertFn=lambda e: non_nullable(
230
- e.data.user.result.timeline_v2.timeline
218
+ convertFn=lambda e: error_check(
219
+ error_check(e.data.user, e.errors).result.timeline_v2.timeline, e.errors
231
220
  ).instructions,
232
- type=models.UserTweetsResponse,
233
221
  key="UserTweetsAndReplies",
234
222
  param=param,
235
223
  )
@@ -252,10 +240,9 @@ class TweetApiUtils:
252
240
 
253
241
  response = self.request(
254
242
  apiFn=self.api.get_user_media_with_http_info,
255
- convertFn=lambda e: non_nullable(
256
- e.data.user.result.timeline_v2.timeline
243
+ convertFn=lambda e: error_check(
244
+ error_check(e.data.user, e.errors).result.timeline_v2.timeline, e.errors
257
245
  ).instructions,
258
- type=models.UserTweetsResponse,
259
246
  key="UserMedia",
260
247
  param=param,
261
248
  )
@@ -278,10 +265,9 @@ class TweetApiUtils:
278
265
 
279
266
  response = self.request(
280
267
  apiFn=self.api.get_likes_with_http_info,
281
- convertFn=lambda e: non_nullable(
282
- e.data.user.result.timeline_v2.timeline
268
+ convertFn=lambda e: error_check(
269
+ error_check(e.data.user, e.errors).result.timeline_v2.timeline, e.errors
283
270
  ).instructions,
284
- type=models.UserTweetsResponse,
285
271
  key="Likes",
286
272
  param=param,
287
273
  )
@@ -303,8 +289,9 @@ class TweetApiUtils:
303
289
 
304
290
  response = self.request(
305
291
  apiFn=self.api.get_bookmarks_with_http_info,
306
- convertFn=lambda e: e.data.bookmark_timeline_v2.timeline.instructions,
307
- type=models.BookmarksResponse,
292
+ convertFn=lambda e: error_check(
293
+ error_check(e.data, e.errors).bookmark_timeline_v2.timeline, e.errors
294
+ ).instructions,
308
295
  key="Bookmarks",
309
296
  param=param,
310
297
  )
@@ -1,4 +1,4 @@
1
- from typing import Any, Callable, Optional, Type, TypeVar
1
+ from typing import Any, Callable, Optional, TypeVar
2
2
 
3
3
  import twitter_openapi_python_generated as twitter
4
4
  import twitter_openapi_python_generated.models as models
@@ -6,14 +6,14 @@ import twitter_openapi_python_generated.models as models
6
6
  from twitter_openapi_python.models import TwitterApiUtilsResponse, UserApiUtilsData
7
7
  from twitter_openapi_python.utils import (
8
8
  build_response,
9
- check_error,
9
+ error_check,
10
10
  get_kwargs,
11
11
  user_or_null_converter,
12
12
  )
13
13
 
14
14
  T = TypeVar("T")
15
15
  ResponseType = TwitterApiUtilsResponse[UserApiUtilsData]
16
- ApiFnType = Callable[..., twitter.ApiResponse]
16
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
17
17
  ParamType = dict[str, Any]
18
18
 
19
19
 
@@ -27,27 +27,19 @@ class UserApiUtils:
27
27
 
28
28
  def request(
29
29
  self,
30
- apiFn: ApiFnType,
30
+ apiFn: "ApiFnType[T]",
31
31
  convertFn: Callable[[T], models.UserResults],
32
- type: Type[T],
33
32
  key: str,
34
33
  param: ParamType,
35
34
  ) -> ResponseType:
36
35
  args = get_kwargs(flag=self.flag[key], additional=param)
37
36
  res = apiFn(**args)
38
- checked = check_error(data=res, type=type)
39
-
40
- result = convertFn(checked)
37
+ result = convertFn(res.data)
41
38
  if result.result is None:
42
- # never reach this point.
43
39
  raise Exception("No user")
44
-
45
40
  user = user_or_null_converter(result.result)
46
-
47
41
  if user is None:
48
- # never reach this point.
49
42
  raise Exception("No user")
50
-
51
43
  data = UserApiUtilsData(
52
44
  raw=result,
53
45
  user=user,
@@ -65,8 +57,7 @@ class UserApiUtils:
65
57
  param.update(extra_param)
66
58
  return self.request(
67
59
  apiFn=self.api.get_user_by_screen_name_with_http_info,
68
- convertFn=lambda e: e.data.user,
69
- type=models.UserResponse,
60
+ convertFn=lambda e: error_check(e.data.user, e.errors),
70
61
  key="UserByScreenName",
71
62
  param=param,
72
63
  )
@@ -81,8 +72,7 @@ class UserApiUtils:
81
72
  param.update(extra_param)
82
73
  return self.request(
83
74
  apiFn=self.api.get_user_by_rest_id_with_http_info,
84
- convertFn=lambda e: e.data.user,
85
- type=models.UserResponse,
75
+ convertFn=lambda e: error_check(e.data.user, e.errors),
86
76
  key="UserByRestId",
87
77
  param=param,
88
78
  )
@@ -1,4 +1,4 @@
1
- from typing import Any, Callable, List, Optional, Type, TypeVar
1
+ from typing import Any, Callable, List, Optional, TypeVar
2
2
 
3
3
  import twitter_openapi_python_generated as twitter
4
4
  import twitter_openapi_python_generated.models as models
@@ -11,18 +11,17 @@ from twitter_openapi_python.models import (
11
11
  )
12
12
  from twitter_openapi_python.utils import (
13
13
  build_response,
14
- check_error,
15
14
  entries_cursor,
15
+ error_check,
16
16
  get_kwargs,
17
17
  instruction_to_entry,
18
- non_nullable,
19
18
  user_entries_converter,
20
19
  user_result_converter,
21
20
  )
22
21
 
23
22
  T = TypeVar("T")
24
23
  ResponseType = TwitterApiUtilsResponse[TimelineApiUtilsResponse[UserApiUtilsData]]
25
- ApiFnType = Callable[..., twitter.ApiResponse]
24
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
26
25
  ParamType = dict[str, Any]
27
26
 
28
27
 
@@ -36,17 +35,14 @@ class UserListApiUtils:
36
35
 
37
36
  def request(
38
37
  self,
39
- apiFn: ApiFnType,
38
+ apiFn: "ApiFnType[T]",
40
39
  convertFn: Callable[[T], List[models.InstructionUnion]],
41
- type: Type[T],
42
40
  key: str,
43
41
  param: ParamType,
44
42
  ) -> ResponseType:
45
43
  args = get_kwargs(flag=self.flag[key], additional=param)
46
44
  res = apiFn(**args)
47
- checked = check_error(data=res, type=type)
48
-
49
- instruction = convertFn(checked)
45
+ instruction = convertFn(res.data)
50
46
  entry = instruction_to_entry(instruction)
51
47
  user_list = user_entries_converter(entry)
52
48
  user = user_result_converter(user_list)
@@ -79,8 +75,7 @@ class UserListApiUtils:
79
75
  param.update(extra_param)
80
76
  return self.request(
81
77
  apiFn=self.api.get_followers_with_http_info,
82
- convertFn=lambda e: e.data.user.result.timeline.timeline.instructions,
83
- type=models.FollowResponse,
78
+ convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
84
79
  key="Followers",
85
80
  param=param,
86
81
  )
@@ -101,8 +96,7 @@ class UserListApiUtils:
101
96
  param.update(extra_param)
102
97
  return self.request(
103
98
  apiFn=self.api.get_following_with_http_info,
104
- convertFn=lambda e: e.data.user.result.timeline.timeline.instructions,
105
- type=models.FollowResponse,
99
+ convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
106
100
  key="Following",
107
101
  param=param,
108
102
  )
@@ -123,8 +117,7 @@ class UserListApiUtils:
123
117
  param.update(extra_param)
124
118
  return self.request(
125
119
  apiFn=self.api.get_followers_you_know_with_http_info,
126
- convertFn=lambda e: e.data.user.result.timeline.timeline.instructions,
127
- type=models.FollowResponse,
120
+ convertFn=lambda e: error_check(e.data.user, e.errors).result.timeline.timeline.instructions,
128
121
  key="FollowersYouKnow",
129
122
  param=param,
130
123
  )
@@ -145,10 +138,9 @@ class UserListApiUtils:
145
138
  param.update(extra_param)
146
139
  return self.request(
147
140
  apiFn=self.api.get_favoriters_with_http_info,
148
- convertFn=lambda e: non_nullable(
149
- e.data.favoriters_timeline.timeline
141
+ convertFn=lambda e: error_check(
142
+ error_check(e.data.favoriters_timeline, e.errors).timeline, e.errors
150
143
  ).instructions,
151
- type=models.TweetFavoritersResponse,
152
144
  key="Favoriters",
153
145
  param=param,
154
146
  )
@@ -169,10 +161,9 @@ class UserListApiUtils:
169
161
  param.update(extra_param)
170
162
  return self.request(
171
163
  apiFn=self.api.get_retweeters_with_http_info,
172
- convertFn=lambda e: non_nullable(
173
- e.data.retweeters_timeline.timeline
164
+ convertFn=lambda e: error_check(
165
+ error_check(e.data.retweeters_timeline, e.errors).timeline, e.errors
174
166
  ).instructions,
175
- type=models.TweetRetweetersResponse,
176
167
  key="Retweeters",
177
168
  param=param,
178
169
  )
@@ -1,4 +1,4 @@
1
- from typing import Any, Callable, Optional, Type, TypeVar
1
+ from typing import Any, Callable, Optional, TypeVar
2
2
 
3
3
  import twitter_openapi_python_generated as twitter
4
4
  import twitter_openapi_python_generated.models as models
@@ -6,14 +6,14 @@ import twitter_openapi_python_generated.models as models
6
6
  from twitter_openapi_python.models import TwitterApiUtilsResponse, UserApiUtilsData
7
7
  from twitter_openapi_python.utils import (
8
8
  build_response,
9
- check_error,
9
+ error_check,
10
10
  get_kwargs,
11
11
  user_result_converter,
12
12
  )
13
13
 
14
14
  T = TypeVar("T")
15
15
  ResponseType = TwitterApiUtilsResponse[list[UserApiUtilsData]]
16
- ApiFnType = Callable[..., twitter.ApiResponse]
16
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
17
17
  ParamType = dict[str, Any]
18
18
 
19
19
 
@@ -27,17 +27,14 @@ class UsersApiUtils:
27
27
 
28
28
  def request(
29
29
  self,
30
- apiFn: ApiFnType,
30
+ apiFn: "ApiFnType[T]",
31
31
  convertFn: Callable[[T], list[models.UserResults]],
32
- type: Type[T],
33
32
  key: str,
34
33
  param: ParamType,
35
34
  ) -> ResponseType:
36
35
  args = get_kwargs(flag=self.flag[key], additional=param)
37
36
  res = apiFn(**args)
38
- checked = check_error(data=res, type=type)
39
-
40
- user_result = convertFn(checked)
37
+ user_result = convertFn(res.data)
41
38
  user = user_result_converter(user_result)
42
39
  return build_response(response=res, data=user)
43
40
 
@@ -51,8 +48,7 @@ class UsersApiUtils:
51
48
  param.update(extra_param)
52
49
  return self.request(
53
50
  apiFn=self.api.get_users_by_rest_ids_with_http_info,
54
- convertFn=lambda e: e.data.users,
55
- type=models.UsersResponse,
51
+ convertFn=lambda e: error_check(e.data.users, e.errors),
56
52
  key="UsersByRestIds",
57
53
  param=param,
58
54
  )
@@ -1,5 +1,4 @@
1
- from types import NoneType
2
- from typing import Any, Callable, Optional, Type, TypeVar
1
+ from typing import Any, Callable, Optional, TypeVar
3
2
 
4
3
  import twitter_openapi_python_generated as twitter
5
4
 
@@ -7,7 +6,7 @@ from twitter_openapi_python.models import TwitterApiUtilsResponse
7
6
  from twitter_openapi_python.utils import build_response, get_legacy_kwargs
8
7
 
9
8
  T = TypeVar("T")
10
- ApiFnType = Callable[..., twitter.ApiResponse]
9
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
11
10
  ParamType = dict[str, Any]
12
11
 
13
12
 
@@ -21,18 +20,15 @@ class V11GetApiUtils:
21
20
 
22
21
  def request(
23
22
  self,
24
- apiFn: ApiFnType,
25
- type: Type[T],
23
+ apiFn: "ApiFnType[T]",
26
24
  key: str,
27
25
  param: ParamType,
28
26
  ) -> TwitterApiUtilsResponse[T]:
29
27
  args = get_legacy_kwargs(flag=self.flag[key], additional=param)
30
28
  res = apiFn(**args)
31
29
  data = res.data
32
-
33
30
  if not isinstance(data, type):
34
31
  raise Exception("Error")
35
-
36
32
  return build_response(response=res, data=data)
37
33
 
38
34
  def get_friends_following_list(
@@ -52,7 +48,6 @@ class V11GetApiUtils:
52
48
 
53
49
  response = self.request(
54
50
  apiFn=self.api.get_friends_following_list_with_http_info,
55
- type=NoneType,
56
51
  param=param,
57
52
  key="friends/following/list.json",
58
53
  )
@@ -69,7 +64,6 @@ class V11GetApiUtils:
69
64
 
70
65
  response = self.request(
71
66
  apiFn=self.api.get_search_typeahead_with_http_info,
72
- type=NoneType,
73
67
  param=param,
74
68
  key="search/typeahead.json",
75
69
  )
@@ -1,5 +1,4 @@
1
- from types import NoneType
2
- from typing import Any, Callable, Optional, Type, TypeVar
1
+ from typing import Any, Callable, Optional, TypeVar
3
2
 
4
3
  import twitter_openapi_python_generated as twitter
5
4
 
@@ -7,7 +6,7 @@ from twitter_openapi_python.models import TwitterApiUtilsResponse
7
6
  from twitter_openapi_python.utils import build_response, get_legacy_kwargs
8
7
 
9
8
  T = TypeVar("T")
10
- ApiFnType = Callable[..., twitter.ApiResponse]
9
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
11
10
  ParamType = dict[str, Any]
12
11
 
13
12
 
@@ -21,8 +20,7 @@ class V11PostApiUtils:
21
20
 
22
21
  def request(
23
22
  self,
24
- apiFn: ApiFnType,
25
- type: Type[T],
23
+ apiFn: "ApiFnType[T]",
26
24
  key: str,
27
25
  param: ParamType,
28
26
  ) -> TwitterApiUtilsResponse[T]:
@@ -46,7 +44,6 @@ class V11PostApiUtils:
46
44
 
47
45
  response = self.request(
48
46
  apiFn=self.api.post_create_friendships_with_http_info,
49
- type=NoneType,
50
47
  param=param,
51
48
  key="friendships/create.json",
52
49
  )
@@ -63,7 +60,6 @@ class V11PostApiUtils:
63
60
 
64
61
  response = self.request(
65
62
  apiFn=self.api.post_destroy_friendships_with_http_info,
66
- type=NoneType,
67
63
  param=param,
68
64
  key="friendships/destroy.json",
69
65
  )
@@ -58,7 +58,7 @@ class TwitterOpenapiPythonClient:
58
58
 
59
59
 
60
60
  class TwitterOpenapiPython:
61
- hash: str = "0c64eebbfb93b3ed69c3aba923ec8d6894a39902"
61
+ hash: str = "4b27150977e1bdd807de8969dc0ddd7918ac9923"
62
62
  placeholder_url = "https://raw.githubusercontent.com/fa0311/twitter-openapi/{hash}/src/config/placeholder.json"
63
63
  header = "https://raw.githubusercontent.com/fa0311/latest-user-agent/refs/heads/main/header.json"
64
64
  access_token: str = "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"
@@ -81,7 +81,6 @@ class TwitterOpenapiPython:
81
81
  {
82
82
  **getHader("chrome-fetch"),
83
83
  "accept-encoding": "identity",
84
- "pragma": "no-cache",
85
84
  "referer": self.twitter_url,
86
85
  "priority": "u=1, i",
87
86
  "x-twitter-client-language": "en",
@@ -98,11 +97,18 @@ class TwitterOpenapiPython:
98
97
  },
99
98
  )
100
99
 
100
+ def remove_prefix(self, text: str) -> str:
101
+ if text.startswith("x-twitter-"):
102
+ return text[10:]
103
+ if text.startswith("x-"):
104
+ return text[2:]
105
+ return text
106
+
101
107
  def kebab_to_upper_camel(self, text: dict[str, Any]) -> dict[str, Any]:
102
108
  res = {}
103
109
  for key, value in text.items():
104
110
  new_key = "".join(
105
- [x.capitalize() for x in key.replace("x-twitter-", "").split("-")]
111
+ [x.capitalize() for x in self.remove_prefix(key).split("-")]
106
112
  )
107
113
  res[new_key] = value
108
114
  return res
@@ -8,7 +8,7 @@ from twitter_openapi_python.utils.api import (
8
8
  build_header,
9
9
  build_response,
10
10
  build_tweet_api_utils,
11
- check_error,
11
+ error_check,
12
12
  entries_cursor,
13
13
  get_kwargs,
14
14
  get_legacy_kwargs,
@@ -28,6 +28,7 @@ def non_nullable(x: Optional[T]) -> T:
28
28
  raise Exception("No data")
29
29
  return x
30
30
 
31
+
31
32
  def non_nullable_list(x: List[Optional[T]]) -> List[T]:
32
33
  def filter_fn(x: Optional[T]) -> TypeGuard[T]:
33
34
  return x is not None
@@ -58,15 +59,13 @@ def get_legacy_kwargs(flag: ParamType, additional: ParamType) -> ParamType:
58
59
  return res | additional
59
60
 
60
61
 
61
- def check_error(data: twitter.ApiResponse, type: type[T]) -> T:
62
- if data.data is None:
63
- raise Exception("No data")
64
- oneOf = data.data.actual_instance
65
- if isinstance(oneOf, models.Errors):
66
- raise Exception(oneOf)
67
- if isinstance(oneOf, type):
68
- return oneOf
69
- raise Exception("Error")
62
+ def error_check(data: Optional[T], error: Optional[List[models.ErrorResponse]]) -> T:
63
+ if data is None:
64
+ if error is None:
65
+ raise Exception("No data")
66
+ else:
67
+ raise Exception(", ".join([x.message for x in error]))
68
+ return data
70
69
 
71
70
 
72
71
  def instruction_to_entry(
@@ -263,10 +262,7 @@ def build_header(headers: Dict[str, str]) -> ApiUtilsHeader:
263
262
  )
264
263
 
265
264
 
266
- def build_response(
267
- response: twitter.ApiResponse,
268
- data: T1,
269
- ) -> TwitterApiUtilsResponse[T1]:
265
+ def build_response(response: twitter.ApiResponse, data: T1) -> TwitterApiUtilsResponse[T1]:
270
266
  if response.headers is None:
271
267
  raise Exception("headers is None")
272
268
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: twitter-openapi-python
3
- Version: 0.0.25
3
+ Version: 0.0.27
4
4
  Summary: Twitter OpenAPI
5
5
  Home-page: https://github.com/fa0311/twitter_openapi_python
6
6
  Author: fa0311
@@ -10,7 +10,7 @@ Keywords: OpenAPI,OpenAPI-Generator,Twitter OpenAPI
10
10
  Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  License-File: LICENSE.AGPL
13
- Requires-Dist: twitter-openapi-python-generated ==0.0.21
13
+ Requires-Dist: twitter-openapi-python-generated ==0.0.25
14
14
  Requires-Dist: pydantic >=2.6
15
15
 
16
16
  # twitter_openapi_python
@@ -48,8 +48,18 @@ else:
48
48
  )
49
49
  cookies_dict = auth_handler.get_cookies().get_dict()
50
50
 
51
+ # To extract cookies from Windows (Linux by default)
52
+ # If you use tweepy_authlib, you must be on Windows
53
+ client = TwitterOpenapiPython()
54
+ client.additional_api_headers = {
55
+ "sec-ch-ua-platform": '"Windows"',
56
+ }
57
+ client.additional_browser_headers = {
58
+ "sec-ch-ua-platform": '"Windows"',
59
+ }
60
+
51
61
  # get client from cookies
52
- 撫 = TwitterOpenapiPython().get_client_from_cookies(cookies=cookies_dict)
62
+ 撫 = client.get_client_from_cookies(cookies=cookies_dict)
53
63
 
54
64
  # tweet "Hello World!!" with current time
55
65
  time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
@@ -79,8 +89,9 @@ In other words, if the sec-ch-ua-platform does not match, the Token cannot be us
79
89
  This library uses the Linux Chrome header by default.
80
90
  To use Token issued by Windows, do the following.
81
91
 
82
- ```typescript
83
- TwitterOpenapiPython.additional_api_headers = {
92
+ ```python
93
+ client = TwitterOpenapiPython()
94
+ client.additional_api_headers = {
84
95
  "sec-ch-ua-platform": '"Windows"',
85
96
  };
86
97
  ```
@@ -0,0 +1,27 @@
1
+ twitter_openapi_python/__init__.py,sha256=stqYIfWDqM0yC93SQNp4-b2hSz-ONWR3QxOG5g2oREg,339
2
+ twitter_openapi_python/client.py,sha256=zs95e9BLmYLMfO5ZF3XqrSlj2wMBCeOHsYALtBNd8fQ,6836
3
+ twitter_openapi_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ twitter_openapi_python/api/__init__.py,sha256=-2hoS75Fp0KvCIWKYQFpvAl0pcbFyt7Be3ood08P7n8,643
5
+ twitter_openapi_python/api/default_api.py,sha256=oYKuwEtj9Y072qmP5Rlc-BQAOmvntHbcwzYscL30ivc,2557
6
+ twitter_openapi_python/api/initial_state_api.py,sha256=eByv3zyjmDHL2bu_rA7_KNvh-oc36AsIUi78Dg1SYK0,2341
7
+ twitter_openapi_python/api/post_api.py,sha256=bAT79kH6NIoxfUJ1LqohwYagA6rEeQXz9JAnvy5_qm4,6107
8
+ twitter_openapi_python/api/tweet_api.py,sha256=luJ7brGW7Nt7SoACJelsJVFLlAHhMsi4j4MnIxfmtsc,9892
9
+ twitter_openapi_python/api/user_api.py,sha256=YvywjW8Qb_4wDN1VkCoFS2YEpfgVCbOICa0n2ekrGqI,2428
10
+ twitter_openapi_python/api/user_list_api.py,sha256=Vnc0LEUwYLGKv7STjUNEJpjH4z5nlF37y84Fs8hKZug,5564
11
+ twitter_openapi_python/api/users_api.py,sha256=cqC8S2Obd5gjlVmVLo7jqzgzFnJkoq7byhl0CVSTmz4,1697
12
+ twitter_openapi_python/api/v11_get_api.py,sha256=Gz5hLf4yJkGdpzjmJIsSqdr1eI6mqtjB3DHQii_uzzg,2144
13
+ twitter_openapi_python/api/v11_post_api.py,sha256=y1jJ5Q_-CYLC4HGjvl3eKDnKdtCVbHVRC2VAbJr8_EM,1945
14
+ twitter_openapi_python/models/__init__.py,sha256=uKZYFWWoXinGRjMU7ErbunUhfsThEuZf8aGFBd7lus0,583
15
+ twitter_openapi_python/models/base.py,sha256=3C1SKqgEZhf3QQIHPNob5vasEV7FE8KxP9rNwWYmHG0,198
16
+ twitter_openapi_python/models/header.py,sha256=hP0fjrm-3Mogt9IkAucQnmDletRuzMmCfoEBaAtoyJ0,594
17
+ twitter_openapi_python/models/initial_state.py,sha256=h8P3hC_tLVSmDuYxB03fuSviz22cpp-4RfSR2npP_Yo,530
18
+ twitter_openapi_python/models/response.py,sha256=ZuaX36mKRsVx5aiJhNw3CjrvVGVaGjMCGdXy28PMFy8,480
19
+ twitter_openapi_python/models/timeline.py,sha256=AoWfrJsonYImlweciaUSjFzmeciaX0zshi7d-FkT4LM,1392
20
+ twitter_openapi_python/utils/__init__.py,sha256=2Am22zCH-BUwPxKnnPoHQvKEF-gWX_eryKgA4OZeiog,449
21
+ twitter_openapi_python/utils/api.py,sha256=NLLPNaG0A4O1XF6qa97M-3FLOR3CjqBH48mW_alVVyw,9964
22
+ twitter_openapi_python-0.0.27.dist-info/LICENSE,sha256=xthyYzrtSmRlBu2gnfuIxzsZeHrqtIZgZPL9UPrYiQU,1524
23
+ twitter_openapi_python-0.0.27.dist-info/LICENSE.AGPL,sha256=Nv6u1ubULm-E2y6q2-pQPK8s2BzkOltLaVlPKQ3tkcs,35182
24
+ twitter_openapi_python-0.0.27.dist-info/METADATA,sha256=ewf_y0MK4BHmi4DECYcqcX5rBUnBiCwcpm2CGEorBiE,3070
25
+ twitter_openapi_python-0.0.27.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
26
+ twitter_openapi_python-0.0.27.dist-info/top_level.txt,sha256=wKFCnW_S6aWD3nFPmd65SxZIviiqQ30LqHOLLpcnTdE,23
27
+ twitter_openapi_python-0.0.27.dist-info/RECORD,,
@@ -1,27 +0,0 @@
1
- twitter_openapi_python/__init__.py,sha256=stqYIfWDqM0yC93SQNp4-b2hSz-ONWR3QxOG5g2oREg,339
2
- twitter_openapi_python/client.py,sha256=i0ynE5orodZtPCLGUYmalBD7lL4HMBBItypdUmlJYJg,6673
3
- twitter_openapi_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- twitter_openapi_python/api/__init__.py,sha256=-2hoS75Fp0KvCIWKYQFpvAl0pcbFyt7Be3ood08P7n8,643
5
- twitter_openapi_python/api/default_api.py,sha256=PeHYaAw6xaUB9ZE3An5SKcEvW71JLTFSgyte80BBvX4,2751
6
- twitter_openapi_python/api/initial_state_api.py,sha256=N4yA3oXDbke7bH-XOuKQ4WVUm5sKbC2C3Dd3AvFINLY,2355
7
- twitter_openapi_python/api/post_api.py,sha256=9xvA0LrtcxWOVBkkVwvMS-zBcJFh1ZVUF_dm1zzZq5o,6826
8
- twitter_openapi_python/api/tweet_api.py,sha256=iZC3PlFS9SD3olb4BRrMYfyoCUf1UuD2XToXd33S-UM,10184
9
- twitter_openapi_python/api/user_api.py,sha256=oH5JBNemBSCyUFAbDSDbjRUOZN3bZMa_tI8PQ4C1wYk,2619
10
- twitter_openapi_python/api/user_list_api.py,sha256=7o1dqRrXzk0F6ywQ-dhyMR0eCzsGJ6HeUHYswPDx3hI,5748
11
- twitter_openapi_python/api/users_api.py,sha256=82CM20-dp7JfpTRqSIzU5Lbm4xoB32Cq18ECRfVMt_I,1789
12
- twitter_openapi_python/api/v11_get_api.py,sha256=OimuRRA4oG2z6IGhJuzgo2CvJqpoD4-CDNZrwZRg6GQ,2254
13
- twitter_openapi_python/api/v11_post_api.py,sha256=d7H-ewGhLql-lQagkGLdOm9FybtjN05lCoGatDMh9rc,2051
14
- twitter_openapi_python/models/__init__.py,sha256=uKZYFWWoXinGRjMU7ErbunUhfsThEuZf8aGFBd7lus0,583
15
- twitter_openapi_python/models/base.py,sha256=3C1SKqgEZhf3QQIHPNob5vasEV7FE8KxP9rNwWYmHG0,198
16
- twitter_openapi_python/models/header.py,sha256=hP0fjrm-3Mogt9IkAucQnmDletRuzMmCfoEBaAtoyJ0,594
17
- twitter_openapi_python/models/initial_state.py,sha256=h8P3hC_tLVSmDuYxB03fuSviz22cpp-4RfSR2npP_Yo,530
18
- twitter_openapi_python/models/response.py,sha256=ZuaX36mKRsVx5aiJhNw3CjrvVGVaGjMCGdXy28PMFy8,480
19
- twitter_openapi_python/models/timeline.py,sha256=AoWfrJsonYImlweciaUSjFzmeciaX0zshi7d-FkT4LM,1392
20
- twitter_openapi_python/utils/__init__.py,sha256=QVT1eCClP9EVfcZ4QU96TVegfAUDEtJ-PVp3zv6qy6w,449
21
- twitter_openapi_python/utils/api.py,sha256=JTSXE1Wh3AiuOb_APTDTQMrR4HTkI9AihzrXkJGV2d8,10026
22
- twitter_openapi_python-0.0.25.dist-info/LICENSE,sha256=xthyYzrtSmRlBu2gnfuIxzsZeHrqtIZgZPL9UPrYiQU,1524
23
- twitter_openapi_python-0.0.25.dist-info/LICENSE.AGPL,sha256=Nv6u1ubULm-E2y6q2-pQPK8s2BzkOltLaVlPKQ3tkcs,35182
24
- twitter_openapi_python-0.0.25.dist-info/METADATA,sha256=DBxA123_stiz681r3-Ttb4UfWg5cYuP0SKy-KLjnHmc,2769
25
- twitter_openapi_python-0.0.25.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
26
- twitter_openapi_python-0.0.25.dist-info/top_level.txt,sha256=wKFCnW_S6aWD3nFPmd65SxZIviiqQ30LqHOLLpcnTdE,23
27
- twitter_openapi_python-0.0.25.dist-info/RECORD,,