twitter-openapi-python 0.0.44__py3-none-any.whl → 0.1.0__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.
Files changed (28) hide show
  1. twitter_openapi_python/__init__.py +15 -15
  2. twitter_openapi_python/api/__init__.py +13 -13
  3. twitter_openapi_python/api/default_api.py +80 -80
  4. twitter_openapi_python/api/initial_state_api.py +72 -72
  5. twitter_openapi_python/api/post_api.py +166 -166
  6. twitter_openapi_python/api/tweet_api.py +428 -353
  7. twitter_openapi_python/api/user_api.py +80 -80
  8. twitter_openapi_python/api/user_list_api.py +171 -171
  9. twitter_openapi_python/api/users_api.py +56 -56
  10. twitter_openapi_python/api/v11_get_api.py +67 -70
  11. twitter_openapi_python/api/v11_post_api.py +61 -66
  12. twitter_openapi_python/client.py +194 -194
  13. twitter_openapi_python/models/__init__.py +22 -22
  14. twitter_openapi_python/models/base.py +9 -9
  15. twitter_openapi_python/models/header.py +20 -20
  16. twitter_openapi_python/models/initial_state.py +17 -17
  17. twitter_openapi_python/models/response.py +19 -19
  18. twitter_openapi_python/models/timeline.py +40 -40
  19. twitter_openapi_python/tid.py +27 -17
  20. twitter_openapi_python/utils/__init__.py +22 -22
  21. twitter_openapi_python/utils/api.py +288 -288
  22. {twitter_openapi_python-0.0.44.dist-info → twitter_openapi_python-0.1.0.dist-info}/METADATA +118 -117
  23. twitter_openapi_python-0.1.0.dist-info/RECORD +27 -0
  24. {twitter_openapi_python-0.0.44.dist-info → twitter_openapi_python-0.1.0.dist-info}/WHEEL +1 -2
  25. {twitter_openapi_python-0.0.44.dist-info → twitter_openapi_python-0.1.0.dist-info}/licenses/LICENSE +31 -31
  26. {twitter_openapi_python-0.0.44.dist-info → twitter_openapi_python-0.1.0.dist-info}/licenses/LICENSE.AGPL +660 -660
  27. twitter_openapi_python-0.0.44.dist-info/RECORD +0 -28
  28. twitter_openapi_python-0.0.44.dist-info/top_level.txt +0 -1
@@ -1,70 +1,67 @@
1
- from typing import Any, Callable, Optional, TypeVar
2
-
3
- import twitter_openapi_python_generated as twitter
4
-
5
- from twitter_openapi_python.models import TwitterApiUtilsResponse
6
- from twitter_openapi_python.utils import build_response, get_legacy_kwargs
7
-
8
- T = TypeVar("T")
9
- ApiFnType = Callable[..., twitter.ApiResponse[T]]
10
- ParamType = dict[str, Any]
11
-
12
-
13
- class V11GetApiUtils:
14
- api: twitter.V11GetApi
15
- flag: ParamType
16
-
17
- def __init__(self, api: twitter.V11GetApi, flag: ParamType):
18
- self.api = api
19
- self.flag = flag
20
-
21
- def request(
22
- self,
23
- apiFn: "ApiFnType[T]",
24
- key: str,
25
- param: ParamType,
26
- ) -> TwitterApiUtilsResponse[T]:
27
- args = get_legacy_kwargs(flag=self.flag[key], additional=param)
28
- res = apiFn(**args)
29
- data = res.data
30
- if not isinstance(data, type):
31
- raise Exception("Error")
32
- return build_response(response=res, data=data)
33
-
34
- def get_friends_following_list(
35
- self,
36
- user_id: str,
37
- cursor: Optional[str] = None,
38
- count: Optional[int] = None,
39
- extra_param: Optional[ParamType] = None,
40
- ) -> TwitterApiUtilsResponse[None]:
41
- param: ParamType = {"user_id": user_id}
42
- if cursor is not None:
43
- param["cursor"] = cursor
44
- if count is not None:
45
- param["count"] = count
46
- if extra_param is not None:
47
- param.update(extra_param)
48
-
49
- response = self.request(
50
- apiFn=self.api.get_friends_following_list_with_http_info,
51
- param=param,
52
- key="friends/following/list.json",
53
- )
54
- return response
55
-
56
- def get_search_typeahead(
57
- self,
58
- q: str,
59
- extra_param: Optional[ParamType] = None,
60
- ) -> TwitterApiUtilsResponse[None]:
61
- param = {"q": q}
62
- if extra_param is not None:
63
- param.update(extra_param)
64
-
65
- response = self.request(
66
- apiFn=self.api.get_search_typeahead_with_http_info,
67
- param=param,
68
- key="search/typeahead.json",
69
- )
70
- return response
1
+ from typing import Any, Callable, Optional, TypeVar
2
+
3
+ import twitter_openapi_python_generated as twitter
4
+
5
+ from twitter_openapi_python.models import TwitterApiUtilsResponse
6
+ from twitter_openapi_python.utils import build_response, get_legacy_kwargs
7
+
8
+ T = TypeVar("T")
9
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
10
+ ParamType = dict[str, Any]
11
+
12
+
13
+ class V11GetApiUtils:
14
+ api: twitter.V11GetApi
15
+ flag: ParamType
16
+
17
+ def __init__(self, api: twitter.V11GetApi, flag: ParamType):
18
+ self.api = api
19
+ self.flag = flag
20
+
21
+ def request(
22
+ self,
23
+ apiFn: "ApiFnType[T]",
24
+ key: str,
25
+ param: ParamType,
26
+ ) -> TwitterApiUtilsResponse[T]:
27
+ args = get_legacy_kwargs(flag=self.flag[key], additional=param)
28
+ res = apiFn(**args)
29
+ return build_response(response=res, data=res.data)
30
+
31
+ def get_friends_following_list(
32
+ self,
33
+ user_id: str,
34
+ cursor: Optional[str] = None,
35
+ count: Optional[int] = None,
36
+ extra_param: Optional[ParamType] = None,
37
+ ) -> TwitterApiUtilsResponse[None]:
38
+ param: ParamType = {"user_id": user_id}
39
+ if cursor is not None:
40
+ param["cursor"] = cursor
41
+ if count is not None:
42
+ param["count"] = count
43
+ if extra_param is not None:
44
+ param.update(extra_param)
45
+
46
+ response = self.request(
47
+ apiFn=self.api.get_friends_following_list_with_http_info,
48
+ param=param,
49
+ key="friends/following/list.json",
50
+ )
51
+ return response
52
+
53
+ def get_search_typeahead(
54
+ self,
55
+ q: str,
56
+ extra_param: Optional[ParamType] = None,
57
+ ) -> TwitterApiUtilsResponse[None]:
58
+ param = {"q": q}
59
+ if extra_param is not None:
60
+ param.update(extra_param)
61
+
62
+ response = self.request(
63
+ apiFn=self.api.get_search_typeahead_with_http_info,
64
+ param=param,
65
+ key="search/typeahead.json",
66
+ )
67
+ return response
@@ -1,66 +1,61 @@
1
- from typing import Any, Callable, Optional, TypeVar
2
-
3
- import twitter_openapi_python_generated as twitter
4
-
5
- from twitter_openapi_python.models import TwitterApiUtilsResponse
6
- from twitter_openapi_python.utils import build_response, get_legacy_kwargs
7
-
8
- T = TypeVar("T")
9
- ApiFnType = Callable[..., twitter.ApiResponse[T]]
10
- ParamType = dict[str, Any]
11
-
12
-
13
- class V11PostApiUtils:
14
- api: twitter.V11PostApi
15
- flag: ParamType
16
-
17
- def __init__(self, api: twitter.V11PostApi, flag: ParamType):
18
- self.api = api
19
- self.flag = flag
20
-
21
- def request(
22
- self,
23
- apiFn: "ApiFnType[T]",
24
- key: str,
25
- param: ParamType,
26
- ) -> TwitterApiUtilsResponse[T]:
27
- args = get_legacy_kwargs(flag=self.flag[key], additional=param)
28
- res = apiFn(**args)
29
- data = res.data
30
-
31
- if not isinstance(data, type):
32
- raise Exception("Error")
33
-
34
- return build_response(response=res, data=data)
35
-
36
- def post_create_friendships(
37
- self,
38
- user_id: str,
39
- extra_param: Optional[ParamType] = None,
40
- ) -> TwitterApiUtilsResponse[None]:
41
- param = {"user_id": user_id}
42
- if extra_param is not None:
43
- param.update(extra_param)
44
-
45
- response = self.request(
46
- apiFn=self.api.post_create_friendships_with_http_info,
47
- param=param,
48
- key="friendships/create.json",
49
- )
50
- return response
51
-
52
- def post_destroy_friendships(
53
- self,
54
- user_id: str,
55
- extra_param: Optional[ParamType] = None,
56
- ) -> TwitterApiUtilsResponse[None]:
57
- param = {"user_id": user_id}
58
- if extra_param is not None:
59
- param.update(extra_param)
60
-
61
- response = self.request(
62
- apiFn=self.api.post_destroy_friendships_with_http_info,
63
- param=param,
64
- key="friendships/destroy.json",
65
- )
66
- return response
1
+ from typing import Any, Callable, Optional, TypeVar
2
+
3
+ import twitter_openapi_python_generated as twitter
4
+
5
+ from twitter_openapi_python.models import TwitterApiUtilsResponse
6
+ from twitter_openapi_python.utils import build_response, get_legacy_kwargs
7
+
8
+ T = TypeVar("T")
9
+ ApiFnType = Callable[..., twitter.ApiResponse[T]]
10
+ ParamType = dict[str, Any]
11
+
12
+
13
+ class V11PostApiUtils:
14
+ api: twitter.V11PostApi
15
+ flag: ParamType
16
+
17
+ def __init__(self, api: twitter.V11PostApi, flag: ParamType):
18
+ self.api = api
19
+ self.flag = flag
20
+
21
+ def request(
22
+ self,
23
+ apiFn: "ApiFnType[T]",
24
+ key: str,
25
+ param: ParamType,
26
+ ) -> TwitterApiUtilsResponse[T]:
27
+ args = get_legacy_kwargs(flag=self.flag[key], additional=param)
28
+ res = apiFn(**args)
29
+ return build_response(response=res, data=res.data)
30
+
31
+ def post_create_friendships(
32
+ self,
33
+ user_id: str,
34
+ extra_param: Optional[ParamType] = None,
35
+ ) -> TwitterApiUtilsResponse[None]:
36
+ param = {"user_id": user_id}
37
+ if extra_param is not None:
38
+ param.update(extra_param)
39
+
40
+ response = self.request(
41
+ apiFn=self.api.post_create_friendships_with_http_info,
42
+ param=param,
43
+ key="friendships/create.json",
44
+ )
45
+ return response
46
+
47
+ def post_destroy_friendships(
48
+ self,
49
+ user_id: str,
50
+ extra_param: Optional[ParamType] = None,
51
+ ) -> TwitterApiUtilsResponse[None]:
52
+ param = {"user_id": user_id}
53
+ if extra_param is not None:
54
+ param.update(extra_param)
55
+
56
+ response = self.request(
57
+ apiFn=self.api.post_destroy_friendships_with_http_info,
58
+ param=param,
59
+ key="friendships/destroy.json",
60
+ )
61
+ return response
@@ -1,194 +1,194 @@
1
- import json
2
- import re
3
- from typing import Any
4
-
5
- import twitter_openapi_python_generated as twitter
6
- import twitter_openapi_python_generated.configuration as conf
7
- import urllib3
8
- from x_client_transaction import ClientTransaction
9
-
10
- from twitter_openapi_python.api import (
11
- DefaultApiUtils,
12
- InitialStateApiUtils,
13
- PostApiUtils,
14
- TweetApiUtils,
15
- UserApiUtils,
16
- UserListApiUtils,
17
- UsersApiUtils,
18
- V11GetApiUtils,
19
- V11PostApiUtils,
20
- )
21
- from twitter_openapi_python.tid import get_tid
22
-
23
- ParamType = dict[str, Any]
24
-
25
-
26
- class TwitterOpenapiPythonClient:
27
- api: twitter.ApiClient
28
- placeholder: ParamType
29
-
30
- def __init__(self, api: twitter.ApiClient, placeholder: ParamType, ct: ClientTransaction):
31
- self.api = api
32
- self.placeholder = placeholder
33
- self.ct = ct
34
-
35
- def get_default_api(self) -> DefaultApiUtils:
36
- return DefaultApiUtils(twitter.DefaultApi(self.api), self.placeholder, self.ct)
37
-
38
- def get_initial_state_api(self) -> InitialStateApiUtils:
39
- return InitialStateApiUtils(self.api)
40
-
41
- def get_post_api(self) -> PostApiUtils:
42
- return PostApiUtils(twitter.PostApi(self.api), self.placeholder, self.ct)
43
-
44
- def get_tweet_api(self) -> TweetApiUtils:
45
- return TweetApiUtils(twitter.TweetApi(self.api), self.placeholder, self.ct)
46
-
47
- def get_user_api(self) -> UserApiUtils:
48
- return UserApiUtils(twitter.UserApi(self.api), self.placeholder, self.ct)
49
-
50
- def get_users_api(self) -> UsersApiUtils:
51
- return UsersApiUtils(twitter.UsersApi(self.api), self.placeholder, self.ct)
52
-
53
- def get_user_list_api(self) -> UserListApiUtils:
54
- return UserListApiUtils(twitter.UserListApi(self.api), self.placeholder, self.ct)
55
-
56
- def get_v11_get_api(self) -> V11GetApiUtils:
57
- return V11GetApiUtils(twitter.V11GetApi(self.api), self.placeholder)
58
-
59
- def get_v11_post_api(self) -> V11PostApiUtils:
60
- return V11PostApiUtils(twitter.V11PostApi(self.api), self.placeholder)
61
-
62
-
63
- class TwitterOpenapiPython:
64
- hash: str = "590dae5c9f8575abc91d3774946bfe6f23960aba"
65
- placeholder_url = "https://raw.githubusercontent.com/fa0311/twitter-openapi/{hash}/src/config/placeholder.json"
66
- header = "https://raw.githubusercontent.com/fa0311/latest-user-agent/refs/heads/main/header.json"
67
- access_token: str = (
68
- "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"
69
- )
70
- twitter_url: str = "https://x.com/home"
71
- additional_browser_headers = {}
72
- additional_api_headers = {}
73
-
74
- def get_header(self) -> tuple[dict[str, str], dict[str, str]]:
75
- http = urllib3.PoolManager()
76
- res = http.request("GET", self.header)
77
- data = json.loads(res.data)
78
- ignore = ["host", "connection"]
79
-
80
- def getHader(name: str) -> dict[str, str]:
81
- return {key: value for key, value in data[name].items() if key not in ignore}
82
-
83
- return (
84
- {
85
- **getHader("chrome-fetch"),
86
- "accept-encoding": "identity",
87
- "referer": self.twitter_url,
88
- "priority": "u=1, i",
89
- "x-twitter-client-language": "en",
90
- "x-twitter-active-user": "yes",
91
- # 'x-twitter-auth-type': 'xxxx'
92
- # 'x-csrf-token': 'xxxx',
93
- # 'x-guest-token': 'xxxx',
94
- "authorization": f"Bearer {self.access_token}",
95
- **self.additional_api_headers,
96
- },
97
- {
98
- **getHader("chrome"),
99
- **self.additional_browser_headers,
100
- },
101
- )
102
-
103
- def remove_prefix(self, text: str) -> str:
104
- if text.startswith("x-twitter-"):
105
- return text[10:]
106
- if text.startswith("x-"):
107
- return text[2:]
108
- return text
109
-
110
- def kebab_to_upper_camel(self, text: dict[str, Any]) -> dict[str, Any]:
111
- res = {}
112
- for key, value in text.items():
113
- new_key = "".join([x.capitalize() for x in self.remove_prefix(key).split("-")])
114
- res[new_key] = value
115
- return res
116
-
117
- def cookie_normalize(self, cookie: list[str]) -> dict[str, str]:
118
- return {x.split("; ")[0].split("=")[0]: x.split("; ")[0].split("=")[1] for x in cookie}
119
-
120
- def cookie_to_str(self, cookie: dict[str, str]) -> str:
121
- return "; ".join([f"{key}={value}" for key, value in cookie.items()])
122
-
123
- def get_twitter_openapi_python_client(
124
- self,
125
- api: twitter.ApiClient,
126
- ) -> TwitterOpenapiPythonClient:
127
- http = urllib3.PoolManager()
128
- flag = http.request("GET", self.placeholder_url.format(hash=self.hash))
129
- ct = get_tid()
130
- return TwitterOpenapiPythonClient(api, json.loads(flag.data), ct)
131
-
132
- def get_client_from_cookies(
133
- self,
134
- cookies: dict[str, str],
135
- ) -> TwitterOpenapiPythonClient:
136
- api_key = self.kebab_to_upper_camel(self.get_header()[0])
137
-
138
- if cookies.get("ct0"):
139
- api_key.update({"AuthType": "OAuth2Session"})
140
- api_key.update({"CsrfToken": cookies["ct0"]})
141
-
142
- if cookies.get("gt"):
143
- api_key.update({"GuestToken": cookies["gt"]})
144
-
145
- api_conf = conf.Configuration(api_key=api_key)
146
- api_conf.access_token = self.access_token
147
- api_client = twitter.ApiClient(
148
- configuration=api_conf,
149
- cookie=self.cookie_to_str(cookies),
150
- )
151
- api_client.user_agent = api_key["UserAgent"]
152
- return self.get_twitter_openapi_python_client(api_client)
153
-
154
- def get_guest_client(self) -> TwitterOpenapiPythonClient:
155
- http = urllib3.PoolManager()
156
- session = {}
157
-
158
- header = self.get_header()
159
-
160
- res_1 = http.request(
161
- "GET",
162
- self.twitter_url,
163
- redirect=False,
164
- headers=header[1],
165
- )
166
- cookie = res_1.headers._container["set-cookie"][1:]
167
- session.update(self.cookie_normalize(cookie))
168
- res_2 = http.request(
169
- "GET",
170
- self.twitter_url,
171
- redirect=False,
172
- headers=header[1],
173
- )
174
-
175
- find = re.findall(r'document.cookie="(.*?)";', res_2.data.decode())
176
- session.update(self.cookie_normalize(find))
177
-
178
- session.pop("ct0")
179
-
180
- if not session.get("gt"):
181
- activate_header = header[0] | {
182
- "cookie": self.cookie_to_str(session),
183
- }
184
- res_3 = http.request(
185
- "POST",
186
- "https://api.x.com/1.1/guest/activate.json",
187
- headers=activate_header,
188
- )
189
- gt = json.loads(res_3.data.decode())["guest_token"]
190
- session.update({"gt": gt})
191
-
192
- # ct0 = cookies.get("ct0", "".join(random.choices("0123456789abcdef", k=32)))
193
-
194
- return self.get_client_from_cookies(session)
1
+ import json
2
+ import re
3
+ from typing import Any
4
+
5
+ import twitter_openapi_python_generated as twitter
6
+ import twitter_openapi_python_generated.configuration as conf
7
+ import urllib3
8
+ from x_client_transaction import ClientTransaction
9
+
10
+ from twitter_openapi_python.api import (
11
+ DefaultApiUtils,
12
+ InitialStateApiUtils,
13
+ PostApiUtils,
14
+ TweetApiUtils,
15
+ UserApiUtils,
16
+ UserListApiUtils,
17
+ UsersApiUtils,
18
+ V11GetApiUtils,
19
+ V11PostApiUtils,
20
+ )
21
+ from twitter_openapi_python.tid import get_tid
22
+
23
+ ParamType = dict[str, Any]
24
+
25
+
26
+ class TwitterOpenapiPythonClient:
27
+ api: twitter.ApiClient
28
+ placeholder: ParamType
29
+
30
+ def __init__(self, api: twitter.ApiClient, placeholder: ParamType, ct: ClientTransaction):
31
+ self.api = api
32
+ self.placeholder = placeholder
33
+ self.ct = ct
34
+
35
+ def get_default_api(self) -> DefaultApiUtils:
36
+ return DefaultApiUtils(twitter.DefaultApi(self.api), self.placeholder, self.ct)
37
+
38
+ def get_initial_state_api(self) -> InitialStateApiUtils:
39
+ return InitialStateApiUtils(self.api)
40
+
41
+ def get_post_api(self) -> PostApiUtils:
42
+ return PostApiUtils(twitter.PostApi(self.api), self.placeholder, self.ct)
43
+
44
+ def get_tweet_api(self) -> TweetApiUtils:
45
+ return TweetApiUtils(twitter.TweetApi(self.api), self.placeholder, self.ct)
46
+
47
+ def get_user_api(self) -> UserApiUtils:
48
+ return UserApiUtils(twitter.UserApi(self.api), self.placeholder, self.ct)
49
+
50
+ def get_users_api(self) -> UsersApiUtils:
51
+ return UsersApiUtils(twitter.UsersApi(self.api), self.placeholder, self.ct)
52
+
53
+ def get_user_list_api(self) -> UserListApiUtils:
54
+ return UserListApiUtils(twitter.UserListApi(self.api), self.placeholder, self.ct)
55
+
56
+ def get_v11_get_api(self) -> V11GetApiUtils:
57
+ return V11GetApiUtils(twitter.V11GetApi(self.api), self.placeholder)
58
+
59
+ def get_v11_post_api(self) -> V11PostApiUtils:
60
+ return V11PostApiUtils(twitter.V11PostApi(self.api), self.placeholder)
61
+
62
+
63
+ class TwitterOpenapiPython:
64
+ hash: str = "103dca20cc540be8dc8291e6f573c3d48ba7af3e"
65
+ placeholder_url = "https://raw.githubusercontent.com/fa0311/twitter-openapi/{hash}/src/config/placeholder.json"
66
+ header = "https://raw.githubusercontent.com/fa0311/latest-user-agent/refs/heads/main/header.json"
67
+ access_token: str = (
68
+ "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"
69
+ )
70
+ twitter_url: str = "https://x.com/home"
71
+ additional_browser_headers = {}
72
+ additional_api_headers = {}
73
+
74
+ def get_header(self) -> tuple[dict[str, str], dict[str, str]]:
75
+ http = urllib3.PoolManager()
76
+ res = http.request("GET", self.header)
77
+ data = json.loads(res.data)
78
+ ignore = ["host", "connection"]
79
+
80
+ def getHader(name: str) -> dict[str, str]:
81
+ return {key: value for key, value in data[name].items() if key not in ignore}
82
+
83
+ return (
84
+ {
85
+ **getHader("chrome-fetch"),
86
+ "accept-encoding": "identity",
87
+ "referer": self.twitter_url,
88
+ "priority": "u=1, i",
89
+ "x-twitter-client-language": "en",
90
+ "x-twitter-active-user": "yes",
91
+ # 'x-twitter-auth-type': 'xxxx'
92
+ # 'x-csrf-token': 'xxxx',
93
+ # 'x-guest-token': 'xxxx',
94
+ "authorization": f"Bearer {self.access_token}",
95
+ **self.additional_api_headers,
96
+ },
97
+ {
98
+ **getHader("chrome"),
99
+ **self.additional_browser_headers,
100
+ },
101
+ )
102
+
103
+ def remove_prefix(self, text: str) -> str:
104
+ if text.startswith("x-twitter-"):
105
+ return text[10:]
106
+ if text.startswith("x-"):
107
+ return text[2:]
108
+ return text
109
+
110
+ def kebab_to_upper_camel(self, text: dict[str, Any]) -> dict[str, Any]:
111
+ res = {}
112
+ for key, value in text.items():
113
+ new_key = "".join([x.capitalize() for x in self.remove_prefix(key).split("-")])
114
+ res[new_key] = value
115
+ return res
116
+
117
+ def cookie_normalize(self, cookie: list[str]) -> dict[str, str]:
118
+ return {x.split("; ")[0].split("=")[0]: x.split("; ")[0].split("=")[1] for x in cookie}
119
+
120
+ def cookie_to_str(self, cookie: dict[str, str]) -> str:
121
+ return "; ".join([f"{key}={value}" for key, value in cookie.items()])
122
+
123
+ def get_twitter_openapi_python_client(
124
+ self,
125
+ api: twitter.ApiClient,
126
+ ) -> TwitterOpenapiPythonClient:
127
+ http = urllib3.PoolManager()
128
+ flag = http.request("GET", self.placeholder_url.format(hash=self.hash))
129
+ ct = get_tid()
130
+ return TwitterOpenapiPythonClient(api, json.loads(flag.data), ct)
131
+
132
+ def get_client_from_cookies(
133
+ self,
134
+ cookies: dict[str, str],
135
+ ) -> TwitterOpenapiPythonClient:
136
+ api_key = self.kebab_to_upper_camel(self.get_header()[0])
137
+
138
+ if cookies.get("ct0"):
139
+ api_key.update({"AuthType": "OAuth2Session"})
140
+ api_key.update({"CsrfToken": cookies["ct0"]})
141
+
142
+ if cookies.get("gt"):
143
+ api_key.update({"GuestToken": cookies["gt"]})
144
+
145
+ api_conf = conf.Configuration(api_key=api_key)
146
+ api_conf.access_token = self.access_token
147
+ api_client = twitter.ApiClient(
148
+ configuration=api_conf,
149
+ cookie=self.cookie_to_str(cookies),
150
+ )
151
+ api_client.user_agent = api_key["UserAgent"]
152
+ return self.get_twitter_openapi_python_client(api_client)
153
+
154
+ def get_guest_client(self) -> TwitterOpenapiPythonClient:
155
+ http = urllib3.PoolManager()
156
+ session = {}
157
+
158
+ header = self.get_header()
159
+
160
+ res_1 = http.request(
161
+ "GET",
162
+ self.twitter_url,
163
+ redirect=False,
164
+ headers=header[1],
165
+ )
166
+ cookie = res_1.headers._container["set-cookie"][1:]
167
+ session.update(self.cookie_normalize(cookie))
168
+ res_2 = http.request(
169
+ "GET",
170
+ self.twitter_url,
171
+ redirect=False,
172
+ headers=header[1],
173
+ )
174
+
175
+ find = re.findall(r'document.cookie="(.*?)";', res_2.data.decode())
176
+ session.update(self.cookie_normalize(find))
177
+
178
+ session.pop("ct0")
179
+
180
+ if not session.get("gt"):
181
+ activate_header = header[0] | {
182
+ "cookie": self.cookie_to_str(session),
183
+ }
184
+ res_3 = http.request(
185
+ "POST",
186
+ "https://api.x.com/1.1/guest/activate.json",
187
+ headers=activate_header,
188
+ )
189
+ gt = json.loads(res_3.data.decode())["guest_token"]
190
+ session.update({"gt": gt})
191
+
192
+ # ct0 = cookies.get("ct0", "".join(random.choices("0123456789abcdef", k=32)))
193
+
194
+ return self.get_client_from_cookies(session)