twitter-openapi-python 0.0.23__tar.gz → 0.0.26__tar.gz

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 (36) hide show
  1. twitter_openapi_python-0.0.26/PKG-INFO +102 -0
  2. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/README.md +39 -3
  3. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/pyproject.toml +2 -2
  4. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/setup.py +15 -5
  5. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/post_api.py +25 -6
  6. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/client.py +62 -46
  7. twitter_openapi_python-0.0.26/twitter_openapi_python.egg-info/PKG-INFO +102 -0
  8. twitter_openapi_python-0.0.26/twitter_openapi_python.egg-info/requires.txt +2 -0
  9. twitter_openapi_python-0.0.23/PKG-INFO +0 -15
  10. twitter_openapi_python-0.0.23/twitter_openapi_python.egg-info/PKG-INFO +0 -15
  11. twitter_openapi_python-0.0.23/twitter_openapi_python.egg-info/requires.txt +0 -2
  12. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/LICENSE +0 -0
  13. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/LICENSE.AGPL +0 -0
  14. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/setup.cfg +0 -0
  15. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/__init__.py +0 -0
  16. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/__init__.py +0 -0
  17. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/default_api.py +0 -0
  18. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/initial_state_api.py +0 -0
  19. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/tweet_api.py +0 -0
  20. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/user_api.py +0 -0
  21. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/user_list_api.py +0 -0
  22. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/users_api.py +0 -0
  23. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/v11_get_api.py +0 -0
  24. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/api/v11_post_api.py +0 -0
  25. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/models/__init__.py +0 -0
  26. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/models/base.py +0 -0
  27. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/models/header.py +0 -0
  28. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/models/initial_state.py +0 -0
  29. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/models/response.py +0 -0
  30. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/models/timeline.py +0 -0
  31. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/py.typed +0 -0
  32. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/utils/__init__.py +0 -0
  33. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python/utils/api.py +0 -0
  34. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python.egg-info/SOURCES.txt +0 -0
  35. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python.egg-info/dependency_links.txt +0 -0
  36. {twitter_openapi_python-0.0.23 → twitter_openapi_python-0.0.26}/twitter_openapi_python.egg-info/top_level.txt +0 -0
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.1
2
+ Name: twitter_openapi_python
3
+ Version: 0.0.26
4
+ Summary: Twitter OpenAPI
5
+ Home-page: https://github.com/fa0311/twitter_openapi_python
6
+ Author: fa0311
7
+ Author-email: yuki@yuki0311.com
8
+ License: proprietary or AGPL-3.0-or-later
9
+ Keywords: OpenAPI,OpenAPI-Generator,Twitter OpenAPI
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ License-File: LICENSE.AGPL
13
+
14
+ # twitter_openapi_python
15
+
16
+ Twitter scraping with data validation by pydantic.
17
+
18
+ ![1691572735537](https://raw.githubusercontent.com/fa0311/twitter_openapi_python/refs/heads/master/twitter_openapi_python/docs/image/README/1691572735537.png)
19
+
20
+ ## Setup
21
+
22
+ ```shell
23
+ pip install twitter-openapi-python
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ import json
30
+ import datetime
31
+
32
+ from pathlib import Path
33
+ from tweepy_authlib import CookieSessionUserHandler
34
+ from twitter_openapi_python import TwitterOpenapiPython
35
+
36
+ # login by tweepy_authlib
37
+ if Path("cookie.json").exists():
38
+ with open("cookie.json", "r") as f:
39
+ cookies_dict = json.load(f)
40
+ if isinstance(cookies_dict, list):
41
+ cookies_dict = {k["name"]: k["value"] for k in cookies_dict}
42
+ else:
43
+ auth_handler = CookieSessionUserHandler(
44
+ screen_name=input("screen_name: "),
45
+ password=input("password: "),
46
+ )
47
+ cookies_dict = auth_handler.get_cookies().get_dict()
48
+
49
+ # To extract cookies from Windows (Linux by default)
50
+ # If you use tweepy_authlib, you must be on Windows
51
+ client = TwitterOpenapiPython()
52
+ client.additional_api_headers = {
53
+ "sec-ch-ua-platform": '"Windows"',
54
+ }
55
+ client.additional_browser_headers = {
56
+ "sec-ch-ua-platform": '"Windows"',
57
+ }
58
+
59
+ # get client from cookies
60
+ 撫 = client.get_client_from_cookies(cookies=cookies_dict)
61
+
62
+ # tweet "Hello World!!" with current time
63
+ time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
64
+ 撫.get_post_api().post_create_tweet(tweet_text=f"Hello World!!{time}")
65
+
66
+ # get user info
67
+ response = 撫.get_user_api().get_user_by_screen_name("elonmusk")
68
+ ```
69
+
70
+ ### Login
71
+
72
+ ```python
73
+ from twitter_openapi_python import TwitterOpenapiPython
74
+
75
+ # guest client
76
+ 撫 = TwitterOpenapiPython().get_guest_client()
77
+ tweet = 撫.get_default_api().get_tweet_result_by_rest_id("1349129669258448897")
78
+ assert tweet.data is not None
79
+ assert tweet.data.tweet.legacy is not None
80
+ print(tweet.data.tweet.legacy.full_text)
81
+ ```
82
+
83
+ ### Multiple OS
84
+
85
+ The Token can only be used on the same OS that issued the Token
86
+ In other words, if the sec-ch-ua-platform does not match, the Token cannot be used.
87
+ This library uses the Linux Chrome header by default.
88
+ To use Token issued by Windows, do the following.
89
+
90
+ ```python
91
+ client = TwitterOpenapiPython()
92
+ client.additional_api_headers = {
93
+ "sec-ch-ua-platform": '"Windows"',
94
+ };
95
+ ```
96
+
97
+ ## License
98
+
99
+ This project is dual licensed. You can choose one of the following licenses:
100
+
101
+ - [Custom License](./LICENSE)
102
+ - [GNU Affero General Public License v3.0](./LICENSE.AGPL)
@@ -1,14 +1,17 @@
1
-
2
1
  # twitter_openapi_python
3
2
 
4
3
  Twitter scraping with data validation by pydantic.
5
4
 
6
5
  ![1691572735537](docs/image/README/1691572735537.png)
7
6
 
7
+ ## Setup
8
+
8
9
  ```shell
9
10
  pip install twitter-openapi-python
10
11
  ```
11
12
 
13
+ ## Usage
14
+
12
15
  ```python
13
16
  import json
14
17
  import datetime
@@ -30,8 +33,18 @@ else:
30
33
  )
31
34
  cookies_dict = auth_handler.get_cookies().get_dict()
32
35
 
36
+ # To extract cookies from Windows (Linux by default)
37
+ # If you use tweepy_authlib, you must be on Windows
38
+ client = TwitterOpenapiPython()
39
+ client.additional_api_headers = {
40
+ "sec-ch-ua-platform": '"Windows"',
41
+ }
42
+ client.additional_browser_headers = {
43
+ "sec-ch-ua-platform": '"Windows"',
44
+ }
45
+
33
46
  # get client from cookies
34
- 𝕏 = TwitterOpenapiPython().get_client_from_cookies(cookies=cookies_dict)
47
+ 𝕏 = client.get_client_from_cookies(cookies=cookies_dict)
35
48
 
36
49
  # tweet "Hello World!!" with current time
37
50
  time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
@@ -41,6 +54,8 @@ time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
41
54
  response = 𝕏.get_user_api().get_user_by_screen_name("elonmusk")
42
55
  ```
43
56
 
57
+ ### Login
58
+
44
59
  ```python
45
60
  from twitter_openapi_python import TwitterOpenapiPython
46
61
 
@@ -50,4 +65,25 @@ tweet = 𝕏.get_default_api().get_tweet_result_by_rest_id("1349129669258448897"
50
65
  assert tweet.data is not None
51
66
  assert tweet.data.tweet.legacy is not None
52
67
  print(tweet.data.tweet.legacy.full_text)
53
- ``````
68
+ ```
69
+
70
+ ### Multiple OS
71
+
72
+ The Token can only be used on the same OS that issued the Token
73
+ In other words, if the sec-ch-ua-platform does not match, the Token cannot be used.
74
+ This library uses the Linux Chrome header by default.
75
+ To use Token issued by Windows, do the following.
76
+
77
+ ```python
78
+ client = TwitterOpenapiPython()
79
+ client.additional_api_headers = {
80
+ "sec-ch-ua-platform": '"Windows"',
81
+ };
82
+ ```
83
+
84
+ ## License
85
+
86
+ This project is dual licensed. You can choose one of the following licenses:
87
+
88
+ - [Custom License](./LICENSE)
89
+ - [GNU Affero General Public License v3.0](./LICENSE.AGPL)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "twitter_openapi_python"
3
- version = "0.0.23"
3
+ version = "0.0.26"
4
4
  description = "Twitter OpenAPI"
5
5
  authors = ["fa0311 <yuki@yuki0311.com>"]
6
6
  license = "proprietary" # or "AGPL-3.0-only"
@@ -14,7 +14,7 @@ include = ["twitter_openapi_python/py.typed"]
14
14
  python = "^3.7"
15
15
  pydantic = ">=2.6"
16
16
 
17
- twitter-openapi-python-generated = "0.0.20"
17
+ twitter-openapi-python-generated = "0.0.24"
18
18
 
19
19
  [tool.poetry.dev-dependencies]
20
20
 
@@ -1,14 +1,26 @@
1
1
  # coding: utf-8
2
2
 
3
+ import re
4
+
3
5
  from setuptools import find_packages, setup
4
6
 
5
7
  NAME = "twitter_openapi_python"
6
- VERSION = "0.0.23"
8
+ VERSION = "0.0.26"
7
9
  PYTHON_REQUIRES = ">=3.7"
8
10
  REQUIRES = [
9
- "twitter_openapi_python_generated == 0.0.20",
11
+ "twitter_openapi_python_generated == 0.0.24",
10
12
  "pydantic >= 2.6",
11
13
  ]
14
+ GITHUB_RAW_URL = "https://raw.githubusercontent.com/fa0311/twitter_openapi_python/refs/heads/master/twitter_openapi_python/"
15
+
16
+
17
+ def image_replace(text: str, url: str):
18
+ return re.sub(
19
+ r"!\[(.*?)\]\((.*?)\)",
20
+ r"![\1](" + url + r"\2)",
21
+ text,
22
+ )
23
+
12
24
 
13
25
  setup(
14
26
  name=NAME,
@@ -23,8 +35,6 @@ setup(
23
35
  include_package_data=True,
24
36
  license="proprietary or AGPL-3.0-or-later",
25
37
  long_description_content_type="text/markdown",
26
- long_description="""\
27
- Twitter scraping with data validation by pydantic.
28
- """, # noqa: E501
38
+ long_description=image_replace(open("README.md").read(), GITHUB_RAW_URL),
29
39
  package_data={"twitter_openapi_python": ["py.typed"]},
30
40
  )
@@ -31,6 +31,10 @@ class PostApiUtils:
31
31
  self,
32
32
  tweet_text: str,
33
33
  media_ids: Optional[list[str]] = None,
34
+ tagged_users: Optional[list[list[str]]] = None,
35
+ in_reply_to_tweet_id: Optional[str] = None,
36
+ attachment_url: Optional[str] = None,
37
+ conversation_control: Optional[str] = None,
34
38
  ) -> ResponseType[models.CreateTweetResponse]:
35
39
  variables = non_nullable(
36
40
  twitter.PostCreateTweetRequestVariables.from_dict(
@@ -43,13 +47,28 @@ class PostApiUtils:
43
47
  )
44
48
  )
45
49
  variables.tweet_text = tweet_text
46
- variables.media.media_entities = [
47
- twitter.PostCreateTweetRequestVariablesMediaMediaEntitiesInner(
48
- media_id=media_id,
49
- tagged_users=[],
50
+ if media_ids:
51
+ tagged_or = tagged_users or []
52
+ variables.media.media_entities = [
53
+ twitter.PostCreateTweetRequestVariablesMediaMediaEntitiesInner(
54
+ media_id=media_id,
55
+ tagged_users=tagged_or[idx] if len(tagged_or) > idx else [],
56
+ )
57
+ for idx, media_id in enumerate(media_ids)
58
+ ]
59
+ variables.attachment_url = attachment_url
60
+ if conversation_control:
61
+ variables.conversation_control = (
62
+ twitter.PostCreateTweetRequestVariablesConversationControl(
63
+ mode=conversation_control
64
+ )
65
+ )
66
+
67
+ if in_reply_to_tweet_id:
68
+ variables.reply = twitter.PostCreateTweetRequestVariablesReply(
69
+ exclude_reply_user_ids=[],
70
+ in_reply_to_tweet_id=in_reply_to_tweet_id,
50
71
  )
51
- for media_id in media_ids or []
52
- ]
53
72
 
54
73
  res = self.api.post_create_tweet_with_http_info(
55
74
  path_query_id=self.flag["CreateTweet"]["queryId"],
@@ -58,43 +58,60 @@ class TwitterOpenapiPythonClient:
58
58
 
59
59
 
60
60
  class TwitterOpenapiPython:
61
- hash: str = "a18a24e4fd96967314c452a6ec2fe6e54f112351"
61
+ hash: str = "4b27150977e1bdd807de8969dc0ddd7918ac9923"
62
62
  placeholder_url = "https://raw.githubusercontent.com/fa0311/twitter-openapi/{hash}/src/config/placeholder.json"
63
- placeholder: ParamType
64
- user_agent: str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
63
+ header = "https://raw.githubusercontent.com/fa0311/latest-user-agent/refs/heads/main/header.json"
65
64
  access_token: str = "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA"
65
+ twitter_url: str = "https://x.com/home"
66
+ additional_browser_headers = {}
67
+ additional_api_headers = {}
68
+
69
+ def get_header(self) -> tuple[dict[str, str], dict[str, str]]:
70
+ http = urllib3.PoolManager()
71
+ res = http.request("GET", self.header)
72
+ data = json.loads(res.data)
73
+ ignore = ["host", "connection"]
66
74
 
67
- api_key = {
68
- "Accept": "*/*",
69
- # "AcceptEncoding": "gzip, deflate, br",
70
- # "AcceptEncoding": "deflate, br",
71
- "AcceptLanguage": "en-US,en;q=0.9",
72
- "CacheControl": "no-cache",
73
- "Pragma": "no-cache",
74
- "SecChUa": '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',
75
- "SecChUaMobile": "?0",
76
- "SecChUaPlatform": '"Windows"',
77
- "SecFetchDest": "empty",
78
- "SecFetchMode": "cors",
79
- "SecFetchSite": "same-origin",
80
- "ClientLanguage": "en",
81
- "ActiveUser": "yes",
82
- }
83
-
84
- browser_headers = {
85
- "accept": "text/plain, */*; q=0.01",
86
- "accept-encoding": "gzip, deflate, br",
87
- "accept-language": "en-US,en;q=0.9",
88
- "cache-control": "no-cache",
89
- "pragma": "no-cache",
90
- "sec-ch-ua": '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',
91
- "sec-ch-ua-mobile": "?0",
92
- "sec-ch-ua-platform": '"Windows"',
93
- "sec-fetch-dest": "empty",
94
- "sec-fetch-mode": "cors",
95
- "sec-fetch-site": "same-site",
96
- "user-agent": user_agent,
97
- }
75
+ def getHader(name: str) -> dict[str, str]:
76
+ return {
77
+ key: value for key, value in data[name].items() if key not in ignore
78
+ }
79
+
80
+ return (
81
+ {
82
+ **getHader("chrome-fetch"),
83
+ "accept-encoding": "identity",
84
+ "referer": self.twitter_url,
85
+ "priority": "u=1, i",
86
+ "x-twitter-client-language": "en",
87
+ "x-twitter-active-user": "yes",
88
+ # 'x-twitter-auth-type': 'xxxx'
89
+ # 'x-csrf-token': 'xxxx',
90
+ # 'x-guest-token': 'xxxx',
91
+ "authorization": f"Bearer {self.access_token}",
92
+ **self.additional_api_headers,
93
+ },
94
+ {
95
+ **getHader("chrome"),
96
+ **self.additional_browser_headers,
97
+ },
98
+ )
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
+
107
+ def kebab_to_upper_camel(self, text: dict[str, Any]) -> dict[str, Any]:
108
+ res = {}
109
+ for key, value in text.items():
110
+ new_key = "".join(
111
+ [x.capitalize() for x in self.remove_prefix(key).split("-")]
112
+ )
113
+ res[new_key] = value
114
+ return res
98
115
 
99
116
  def cookie_normalize(self, cookie: list[str]) -> dict[str, str]:
100
117
  return {
@@ -117,7 +134,7 @@ class TwitterOpenapiPython:
117
134
  self,
118
135
  cookies: dict[str, str],
119
136
  ) -> TwitterOpenapiPythonClient:
120
- api_key = self.api_key.copy()
137
+ api_key = self.kebab_to_upper_camel(self.get_header()[0])
121
138
 
122
139
  if cookies.get("ct0"):
123
140
  api_key.update({"AuthType": "OAuth2Session"})
@@ -132,27 +149,28 @@ class TwitterOpenapiPython:
132
149
  configuration=api_conf,
133
150
  cookie=self.cookie_to_str(cookies),
134
151
  )
135
- api_client.user_agent = self.user_agent
152
+ api_client.user_agent = api_key["UserAgent"]
136
153
  return self.get_twitter_openapi_python_client(api_client)
137
154
 
138
155
  def get_guest_client(self) -> TwitterOpenapiPythonClient:
139
156
  http = urllib3.PoolManager()
140
157
  session = {}
141
158
 
159
+ header = self.get_header()
160
+
142
161
  res_1 = http.request(
143
162
  "GET",
144
- "https://x.com",
163
+ self.twitter_url,
145
164
  redirect=False,
146
- headers=self.browser_headers.copy(),
165
+ headers=header[1],
147
166
  )
148
167
  cookie = res_1.headers._container["set-cookie"][1:]
149
168
  session.update(self.cookie_normalize(cookie))
150
169
  res_2 = http.request(
151
170
  "GET",
152
- "https://x.com",
171
+ self.twitter_url,
153
172
  redirect=False,
154
- headers=self.browser_headers.copy()
155
- | {"Cookie": self.cookie_to_str(session)},
173
+ headers=header[1],
156
174
  )
157
175
 
158
176
  find = re.findall(r'document.cookie="(.*?)";', res_2.data.decode())
@@ -161,15 +179,13 @@ class TwitterOpenapiPython:
161
179
  session.pop("ct0")
162
180
 
163
181
  if not session.get("gt"):
164
- activate_header = self.browser_headers.copy() | {
165
- "authorization": "Bearer {}".format(self.access_token),
166
- "x-twitter-active-user": "yes",
167
- "x-twitter-client-language": "en",
182
+ activate_header = header[0] | {
183
+ "cookie": self.cookie_to_str(session),
168
184
  }
169
185
  res_3 = http.request(
170
186
  "POST",
171
187
  "https://api.x.com/1.1/guest/activate.json",
172
- headers=activate_header | {"Cookie": self.cookie_to_str(session)},
188
+ headers=activate_header,
173
189
  )
174
190
  gt = json.loads(res_3.data.decode())["guest_token"]
175
191
  session.update({"gt": gt})
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.1
2
+ Name: twitter-openapi-python
3
+ Version: 0.0.26
4
+ Summary: Twitter OpenAPI
5
+ Home-page: https://github.com/fa0311/twitter_openapi_python
6
+ Author: fa0311
7
+ Author-email: yuki@yuki0311.com
8
+ License: proprietary or AGPL-3.0-or-later
9
+ Keywords: OpenAPI,OpenAPI-Generator,Twitter OpenAPI
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ License-File: LICENSE.AGPL
13
+
14
+ # twitter_openapi_python
15
+
16
+ Twitter scraping with data validation by pydantic.
17
+
18
+ ![1691572735537](https://raw.githubusercontent.com/fa0311/twitter_openapi_python/refs/heads/master/twitter_openapi_python/docs/image/README/1691572735537.png)
19
+
20
+ ## Setup
21
+
22
+ ```shell
23
+ pip install twitter-openapi-python
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```python
29
+ import json
30
+ import datetime
31
+
32
+ from pathlib import Path
33
+ from tweepy_authlib import CookieSessionUserHandler
34
+ from twitter_openapi_python import TwitterOpenapiPython
35
+
36
+ # login by tweepy_authlib
37
+ if Path("cookie.json").exists():
38
+ with open("cookie.json", "r") as f:
39
+ cookies_dict = json.load(f)
40
+ if isinstance(cookies_dict, list):
41
+ cookies_dict = {k["name"]: k["value"] for k in cookies_dict}
42
+ else:
43
+ auth_handler = CookieSessionUserHandler(
44
+ screen_name=input("screen_name: "),
45
+ password=input("password: "),
46
+ )
47
+ cookies_dict = auth_handler.get_cookies().get_dict()
48
+
49
+ # To extract cookies from Windows (Linux by default)
50
+ # If you use tweepy_authlib, you must be on Windows
51
+ client = TwitterOpenapiPython()
52
+ client.additional_api_headers = {
53
+ "sec-ch-ua-platform": '"Windows"',
54
+ }
55
+ client.additional_browser_headers = {
56
+ "sec-ch-ua-platform": '"Windows"',
57
+ }
58
+
59
+ # get client from cookies
60
+ 撫 = client.get_client_from_cookies(cookies=cookies_dict)
61
+
62
+ # tweet "Hello World!!" with current time
63
+ time = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")
64
+ 撫.get_post_api().post_create_tweet(tweet_text=f"Hello World!!{time}")
65
+
66
+ # get user info
67
+ response = 撫.get_user_api().get_user_by_screen_name("elonmusk")
68
+ ```
69
+
70
+ ### Login
71
+
72
+ ```python
73
+ from twitter_openapi_python import TwitterOpenapiPython
74
+
75
+ # guest client
76
+ 撫 = TwitterOpenapiPython().get_guest_client()
77
+ tweet = 撫.get_default_api().get_tweet_result_by_rest_id("1349129669258448897")
78
+ assert tweet.data is not None
79
+ assert tweet.data.tweet.legacy is not None
80
+ print(tweet.data.tweet.legacy.full_text)
81
+ ```
82
+
83
+ ### Multiple OS
84
+
85
+ The Token can only be used on the same OS that issued the Token
86
+ In other words, if the sec-ch-ua-platform does not match, the Token cannot be used.
87
+ This library uses the Linux Chrome header by default.
88
+ To use Token issued by Windows, do the following.
89
+
90
+ ```python
91
+ client = TwitterOpenapiPython()
92
+ client.additional_api_headers = {
93
+ "sec-ch-ua-platform": '"Windows"',
94
+ };
95
+ ```
96
+
97
+ ## License
98
+
99
+ This project is dual licensed. You can choose one of the following licenses:
100
+
101
+ - [Custom License](./LICENSE)
102
+ - [GNU Affero General Public License v3.0](./LICENSE.AGPL)
@@ -0,0 +1,2 @@
1
+ twitter_openapi_python_generated==0.0.24
2
+ pydantic>=2.6
@@ -1,15 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: twitter_openapi_python
3
- Version: 0.0.23
4
- Summary: Twitter OpenAPI
5
- Home-page: https://github.com/fa0311/twitter_openapi_python
6
- Author: fa0311
7
- Author-email: yuki@yuki0311.com
8
- License: proprietary or AGPL-3.0-or-later
9
- Keywords: OpenAPI,OpenAPI-Generator,Twitter OpenAPI
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- License-File: LICENSE.AGPL
13
-
14
- Twitter scraping with data validation by pydantic.
15
-
@@ -1,15 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: twitter-openapi-python
3
- Version: 0.0.23
4
- Summary: Twitter OpenAPI
5
- Home-page: https://github.com/fa0311/twitter_openapi_python
6
- Author: fa0311
7
- Author-email: yuki@yuki0311.com
8
- License: proprietary or AGPL-3.0-or-later
9
- Keywords: OpenAPI,OpenAPI-Generator,Twitter OpenAPI
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- License-File: LICENSE.AGPL
13
-
14
- Twitter scraping with data validation by pydantic.
15
-
@@ -1,2 +0,0 @@
1
- twitter_openapi_python_generated==0.0.20
2
- pydantic>=2.6