tweepy-self 1.6.3__py3-none-any.whl → 1.10.0b9__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.
twitter/errors.py CHANGED
@@ -61,12 +61,17 @@ class HTTPException(TwitterException):
61
61
  self.api_codes: list[int] = []
62
62
  self.api_messages: list[str] = []
63
63
  self.detail: str | None = None
64
+ self.html: str | None = None
64
65
 
65
66
  # Если ответ — строка, то это html
66
67
  if isinstance(data, str):
67
- exception_message = (
68
- f"(response status: {response.status_code}) HTML Response:\n{data}"
69
- )
68
+ if not data:
69
+ exception_message = (
70
+ f"(response status: {response.status_code}) Empty response body."
71
+ )
72
+ else:
73
+ self.html = data
74
+ exception_message = f"(response status: {response.status_code}) HTML Response:\n{self.html}"
70
75
  if response.status_code == 429:
71
76
  exception_message = (
72
77
  f"(response status: {response.status_code}) Rate limit exceeded."
@@ -75,7 +80,7 @@ class HTTPException(TwitterException):
75
80
  super().__init__(exception_message)
76
81
  return
77
82
 
78
- self.api_errors = data.get("errors", [])
83
+ self.api_errors = data.get("errors", [data])
79
84
  self.detail = data.get("detail")
80
85
 
81
86
  for error in self.api_errors:
@@ -146,7 +151,9 @@ class BadAccount(TwitterException):
146
151
 
147
152
  class BadToken(BadAccount):
148
153
  def __init__(self, http_exception: "HTTPException", account: Account):
149
- exception_message = "Bad Twitter account's auth_token."
154
+ exception_message = (
155
+ "Bad Twitter account's auth_token. Relogin to get new token."
156
+ )
150
157
  super().__init__(http_exception, account, exception_message)
151
158
 
152
159
 
@@ -154,14 +161,14 @@ class Locked(BadAccount):
154
161
  def __init__(self, http_exception: "HTTPException", account: Account):
155
162
  exception_message = (
156
163
  f"Twitter account is locked."
157
- f" Set CapSolver API key (capsolver_api_key) to autounlock."
164
+ f" Set CapSolver API key (capsolver_api_key) to auto-unlock."
158
165
  )
159
166
  super().__init__(http_exception, account, exception_message)
160
167
 
161
168
 
162
169
  class ConsentLocked(BadAccount):
163
170
  def __init__(self, http_exception: "HTTPException", account: Account):
164
- exception_message = f"Twitter account is consent locked. Relogin to unlock."
171
+ exception_message = f"Twitter account is locked."
165
172
  super().__init__(http_exception, account, exception_message)
166
173
 
167
174
 
twitter/models.py CHANGED
@@ -1,26 +1,53 @@
1
- from datetime import datetime
1
+ from typing import Optional, Any
2
+ from datetime import datetime, timedelta
2
3
 
3
- from pydantic import BaseModel
4
+ from pydantic import BaseModel, Field, field_validator
4
5
 
5
- from .utils import to_datetime
6
+ from .utils import to_datetime, tweet_url
6
7
 
7
8
 
8
- class UserData(BaseModel):
9
- id: int
10
- username: str
11
- name: str
12
- created_at: datetime
13
- description: str
14
- location: str
15
- followers_count: int
16
- friends_count: int
17
- raw_data: dict
9
+ class Image(BaseModel):
10
+ type: str = Field(..., alias="image_type")
11
+ width: int = Field(..., alias="w")
12
+ height: int = Field(..., alias="h")
13
+
14
+
15
+ class Media(BaseModel):
16
+ id: int = Field(..., alias="media_id")
17
+ image: Image
18
+ size: int
19
+ expires_at: datetime = Field(..., alias="expires_after_secs")
20
+
21
+ @field_validator("expires_at", mode="before")
22
+ @classmethod
23
+ def set_expires_at(cls, v):
24
+ return datetime.now() + timedelta(seconds=v)
18
25
 
19
26
  def __str__(self):
20
- return f"({self.id}) @{self.username}"
27
+ return str(self.id)
28
+
29
+
30
+ class User(BaseModel):
31
+ # fmt: off
32
+ id: int | None = None
33
+ username: str | None = None
34
+ name: str | None = None # 50
35
+ created_at: datetime | None = None
36
+ description: str | None = None # 160
37
+ location: str | None = None # 30
38
+ followers_count: int | None = None
39
+ friends_count: int | None = None
40
+ raw_data: dict | None = None
41
+ # fmt: on
42
+
43
+ def __str__(self):
44
+ return str(self.id)
45
+
46
+ def __repr__(self):
47
+ return f"{self.__class__.__name__}(id={self.id}, username={self.username})"
21
48
 
22
49
  @classmethod
23
- def from_raw_user_data(cls, data: dict):
50
+ def from_raw_data(cls, data: dict):
24
51
  legacy = data["legacy"]
25
52
  keys = ("name", "description", "location", "followers_count", "friends_count")
26
53
  values = {key: legacy[key] for key in keys}
@@ -36,44 +63,114 @@ class UserData(BaseModel):
36
63
 
37
64
 
38
65
  class Tweet(BaseModel):
39
- user_id: int
40
- id: int
41
- created_at: datetime
42
- full_text: str
43
- lang: str
44
- favorite_count: int
45
- quote_count: int
46
- reply_count: int
47
- retweet_count: int
48
- retweeted: bool
49
- raw_data: dict
50
- url: str | None = None
66
+ # fmt: off
67
+ id: int
68
+ text: str
69
+ language: str
70
+ created_at: datetime
71
+
72
+ conversation_id: int
73
+
74
+ quoted: bool
75
+ retweeted: bool
76
+ bookmarked: bool
77
+ favorited: bool
78
+
79
+ quote_count: int
80
+ retweet_count: int
81
+ bookmark_count: int
82
+ favorite_count: int
83
+ reply_count: int
84
+
85
+ quoted_tweet: Optional["Tweet"] = None
86
+ retweeted_tweet: Optional["Tweet"] = None
87
+
88
+ user: User
89
+ url: str
90
+
91
+ raw_data: dict
92
+
93
+ # TODO hashtags
94
+ # TODO media
95
+ # TODO symbols
96
+ # TODO timestamps
97
+ # TODO urls
98
+ # TODO user_mentions
99
+ # TODO views
100
+ # fmt: on
51
101
 
52
102
  def __str__(self):
53
- short_text = (
54
- f"{self.full_text[:32]}..." if len(self.full_text) > 16 else self.full_text
55
- )
56
- return f"({self.id}) {short_text}"
103
+ return str(self.id)
104
+
105
+ def __repr__(self):
106
+ return f"{self.__class__.__name__}(id={self.id}, user_id={self.user.id})"
107
+
108
+ @property
109
+ def short_text(self) -> str:
110
+ return f"{self.text[:32]}..." if len(self.text) > 16 else self.text
57
111
 
58
112
  @classmethod
59
113
  def from_raw_data(cls, data: dict):
60
- legacy = data["legacy"]
61
- keys = (
62
- "full_text",
63
- "lang",
64
- "favorite_count",
65
- "quote_count",
66
- "reply_count",
67
- "retweet_count",
68
- "retweeted",
69
- )
70
- values = {key: legacy[key] for key in keys}
71
- values.update(
72
- {
73
- "user_id": int(legacy["user_id_str"]),
74
- "id": int(legacy["id_str"]),
75
- "created_at": to_datetime(legacy["created_at"]),
76
- "raw_data": data,
77
- }
78
- )
114
+ legacy_data = data["legacy"]
115
+
116
+ user_data = data["core"]["user_results"]["result"]
117
+ user = User.from_raw_data(user_data)
118
+
119
+ id = int(legacy_data["id_str"])
120
+ url = tweet_url(user.username, id)
121
+
122
+ retweeted_tweet = None
123
+ if "retweeted_status_result" in legacy_data:
124
+ retweeted_tweet_data = legacy_data["retweeted_status_result"]["result"]
125
+ retweeted_tweet = cls.from_raw_data(retweeted_tweet_data)
126
+
127
+ quoted_tweet = None
128
+ if "quoted_status_result" in data:
129
+ quoted_tweet_data = data["quoted_status_result"]["result"]
130
+ quoted_tweet = cls.from_raw_data(quoted_tweet_data)
131
+
132
+ values = {
133
+ "id": id,
134
+ "text": legacy_data["full_text"],
135
+ "language": legacy_data["lang"],
136
+ "created_at": to_datetime(legacy_data["created_at"]),
137
+ "conversation_id": int(legacy_data["conversation_id_str"]),
138
+ "quoted": legacy_data["is_quote_status"],
139
+ "retweeted": legacy_data["retweeted"],
140
+ "bookmarked": legacy_data["bookmarked"],
141
+ "favorited": legacy_data["favorited"],
142
+ "quote_count": legacy_data["quote_count"],
143
+ "retweet_count": legacy_data["retweet_count"],
144
+ "bookmark_count": legacy_data["bookmark_count"],
145
+ "favorite_count": legacy_data["favorite_count"],
146
+ "reply_count": legacy_data["reply_count"],
147
+ "user": user.model_dump(),
148
+ "quoted_tweet": quoted_tweet.model_dump() if quoted_tweet else None,
149
+ "retweeted_tweet": (
150
+ retweeted_tweet.model_dump() if retweeted_tweet else None
151
+ ),
152
+ "url": url,
153
+ "raw_data": data,
154
+ }
79
155
  return cls(**values)
156
+
157
+
158
+ class Subtask(BaseModel):
159
+ id: str
160
+ primary_text: Optional[str] = None
161
+ secondary_text: Optional[str] = None
162
+ detail_text: Optional[str] = None
163
+ raw_data: dict
164
+
165
+ @classmethod
166
+ def from_raw_data(cls, data: dict) -> "Subtask":
167
+ task = {"id": data["subtask_id"]}
168
+ if enter_text := data.get("enter_text"):
169
+ if header := enter_text.get("header"):
170
+ if primary_text := header.get("primary_text"):
171
+ task["primary_text"] = primary_text["text"]
172
+ if secondary_text := header.get("secondary_text"):
173
+ task["secondary_text"] = secondary_text["text"]
174
+ if detail_text := header.get("detail_text"):
175
+ task["detail_text"] = detail_text["text"]
176
+ return cls(**task, raw_data=data)
twitter/utils/__init__.py CHANGED
@@ -16,6 +16,7 @@ from .other import (
16
16
  tweet_url,
17
17
  to_datetime,
18
18
  hidden_value,
19
+ tweets_data_from_instructions,
19
20
  )
20
21
 
21
22
 
@@ -33,4 +34,5 @@ __all__ = [
33
34
  "tweet_url",
34
35
  "to_datetime",
35
36
  "hidden_value",
37
+ "tweets_data_from_instructions",
36
38
  ]
twitter/utils/html.py CHANGED
@@ -21,9 +21,11 @@ def parse_oauth_html(html: str) -> tuple[str | None, str | None, str | None]:
21
21
  return authenticity_token, redirect_url, redirect_after_login_url
22
22
 
23
23
 
24
- def parse_unlock_html(html: str) -> tuple[str | None, str | None, bool, bool, bool]:
24
+ def parse_unlock_html(
25
+ html: str,
26
+ ) -> tuple[str | None, str | None, bool, bool, bool, bool]:
25
27
  """
26
- :return: authenticity_token, assignment_token, needs_unlock, start_button, finish_button
28
+ :return: authenticity_token, assignment_token, needs_unlock, start_button, finish_button, delete_button
27
29
  """
28
30
  soup = BeautifulSoup(html, "lxml")
29
31
  authenticity_token_element = soup.find("input", {"name": "authenticity_token"})
@@ -38,10 +40,12 @@ def parse_unlock_html(html: str) -> tuple[str | None, str | None, bool, bool, bo
38
40
  needs_unlock = bool(verification_string)
39
41
  start_button = bool(soup.find("input", value="Start"))
40
42
  finish_button = bool(soup.find("input", value="Continue to X"))
43
+ delete_button = bool(soup.find("input", value="Delete"))
41
44
  return (
42
45
  authenticity_token,
43
46
  assignment_token,
44
47
  needs_unlock,
45
48
  start_button,
46
49
  finish_button,
50
+ delete_button,
47
51
  )
twitter/utils/other.py CHANGED
@@ -14,6 +14,19 @@ def tweet_url(username: str, tweet_id: int) -> str:
14
14
  return f"https://x.com/{username}/status/{tweet_id}"
15
15
 
16
16
 
17
+ def tweets_data_from_instructions(instructions: dict) -> list[dict]:
18
+ tweets = []
19
+ for instruction in instructions:
20
+ if instruction["type"] == "TimelineAddEntries":
21
+ for entry in instruction["entries"]:
22
+ if entry["entryId"].startswith("tweet-"):
23
+ tweet_data = entry["content"]["itemContent"]["tweet_results"][
24
+ "result"
25
+ ]
26
+ tweets.append(tweet_data)
27
+ return tweets
28
+
29
+
17
30
  def to_datetime(twitter_datetime: str):
18
31
  return datetime.strptime(twitter_datetime, "%a %b %d %H:%M:%S +0000 %Y")
19
32
 
@@ -1,218 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: tweepy-self
3
- Version: 1.6.3
4
- Summary: Twitter (selfbot) for Python!
5
- Home-page: https://github.com/alenkimov/tweepy-self
6
- Author: Alen
7
- Author-email: alen.kimov@gmail.com
8
- Requires-Python: >=3.11,<4.0
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: Programming Language :: Python :: 3.11
11
- Classifier: Programming Language :: Python :: 3.12
12
- Requires-Dist: beautifulsoup4 (>=4,<5)
13
- Requires-Dist: better-proxy (==1.1.1)
14
- Requires-Dist: curl_cffi (==0.6.0b9)
15
- Requires-Dist: lxml (>=5,<6)
16
- Requires-Dist: pydantic (>=1)
17
- Requires-Dist: pyotp (>=2,<3)
18
- Requires-Dist: python3-capsolver (>=0.9,<0.10)
19
- Requires-Dist: yarl (>=1,<2)
20
- Project-URL: Repository, https://github.com/alenkimov/tweepy-self
21
- Description-Content-Type: text/markdown
22
-
23
- # Tweepy-self
24
- [![Telegram channel](https://img.shields.io/endpoint?url=https://runkit.io/damiankrawczyk/telegram-badge/branches/master?url=https://t.me/cum_insider)](https://t.me/cum_insider)
25
- [![PyPI version info](https://img.shields.io/pypi/v/tweepy-self.svg)](https://pypi.python.org/pypi/tweepy-self)
26
- [![PyPI supported Python versions](https://img.shields.io/pypi/pyversions/tweepy-self.svg)](https://pypi.python.org/pypi/tweepy-self)
27
- [![PyPI downloads per month](https://img.shields.io/pypi/dm/tweepy-self.svg)](https://pypi.python.org/pypi/tweepy-self)
28
-
29
- A modern, easy to use, feature-rich, and async ready API wrapper for Twitter's user API written in Python.
30
-
31
- - Docs (soon)
32
-
33
- More libraries of the family:
34
- - [better-proxy](https://github.com/alenkimov/better_proxy)
35
- - [better-web3](https://github.com/alenkimov/better_web3)
36
-
37
- Отдельное спасибо [Кузнице Ботов](https://t.me/bots_forge) за код для авторизации и разморозки! Подписывайтесь на их Telegram :)
38
-
39
- ## Key Features
40
- - Modern Pythonic API using async and await.
41
- - Prevents user account automation detection.
42
-
43
- ## Installing
44
- ```bash
45
- pip install tweepy-self
46
- ```
47
-
48
- ## Example
49
- ```python
50
- import asyncio
51
- import twitter
52
-
53
- account = twitter.Account(auth_token="auth_token")
54
-
55
- async def main():
56
- async with twitter.Client(account) as twitter_client:
57
- await twitter_client.tweet("Hello, tweepy-self! <3")
58
-
59
- asyncio.run(main())
60
- ```
61
-
62
- ## More
63
- Automating user accounts is against the Twitter ToS. This library is a proof of concept and I cannot recommend using it. Do so at your own risk
64
-
65
- ## Документация (устаревшая)
66
- `Код ушел немного дальше, чем эта документация.`
67
-
68
- Библиотека позволяет работать с неофициальным API Twitter, а именно:
69
- - Логин
70
- - Анлок
71
- - Привязывать сервисы (приложения).
72
- - Устанавливать статус аккаунта (бан, лок).
73
- - Загружать изображения на сервер и изменять баннер и аватарку.
74
- - Изменять данные о пользователе: имя, описание профиля и другое.
75
- - Изменять имя пользователя и пароль.
76
- - Запрашивать информацию о подписчиках.
77
- - Запрашивать некоторую информацию о пользователе (количество подписчиков и другое).
78
- - Голосовать.
79
- - Подписываться и отписываться.
80
- - Лайкать и дизлайкать.
81
- - Твиттить, ретвиттить с изображением и без.
82
- - Закреплять твиты.
83
- - Запрашивать твиты пользователей.
84
- - Удалять твиты.
85
- - И другое.
86
-
87
- #### Статус аккаунта
88
- После любого взаимодействия с Twitter устанавливается статус аккаунта:
89
- - `BAD_TOKEN` - Неверный токен.
90
- - `UNKNOWN` - Статус аккаунта не установлен.
91
- - `SUSPENDED` - Действие учетной записи приостановлено (бан).
92
- - `LOCKED` - Учетная запись заморожена (лок) (требуется прохождение капчи).
93
- - `GOOD` - Аккаунт в порядке.
94
-
95
- Не каждое взаимодействие с Twitter достоверно определяет статус аккаунта.
96
- Например, простой запрос данных об аккаунте честно вернет данные, даже если ваш аккаунт заморожен.
97
-
98
- Для достоверной установки статуса аккаунта используйте метод `establish_status()`
99
-
100
- ### Примеры работы
101
- Запрос информации о пользователе:
102
- ```python
103
- # Запрос информации о текущем пользователе:
104
- me = await twitter_client.request_user_data()
105
- print(f"[{account.short_auth_token}] {me}")
106
- print(f"Аккаунт создан: {me.created_at}")
107
- print(f"Following (подписан ты): {me.followings_count}")
108
- print(f"Followers (подписаны на тебя): {me.followers_count}")
109
- print(f"Прочая информация: {me.raw_data}")
110
-
111
- # Запрос информации об ином пользователе:
112
- elonmusk = await twitter.request_user_data("@elonmusk")
113
- print(elonmusk)
114
- ```
115
-
116
- Смена имени пользователя и пароля:
117
- ```python
118
- account = twitter.Account("auth_token", password="password")
119
- ...
120
- await twitter_client.change_username("new_username")
121
- await twitter_client.request_user_data()
122
- print(f"New username: {account.data.username}")
123
-
124
- await twitter_client.change_password("new_password")
125
- print(f"New password: {account.password}")
126
- print(f"New auth_token: {account.auth_token}")
127
- ```
128
-
129
- Смена данных профиля:
130
- ```python
131
- await twitter_client.update_birthdate(day=1, month=12, year=2000)
132
- await twitter_client.update_profile( # Locks account!
133
- name="New Name",
134
- description="New description",
135
- location="New York",
136
- website="https://github.com/alenkimov/better_automation",
137
- )
138
- ```
139
-
140
- Загрузка изображений и смена аватара и баннера:
141
- ```python
142
- image = open(f"image.png", "rb").read()
143
- media_id = await twitter_client.upload_image(image)
144
- avatar_image_url = await twitter_client.update_profile_avatar(media_id)
145
- banner_image_url = await twitter_client.update_profile_banner(media_id)
146
- ```
147
-
148
- Привязка сервиса (приложения):
149
-
150
- ```python
151
- # Изучите запросы сервиса и найдите подобные данные для авторизации (привязки):
152
- bind_data = {
153
- 'response_type': 'code',
154
- 'client_id': 'TjFVQm52ZDFGWEtNT0tKaktaSWU6MTpjaQ',
155
- 'redirect_uri': 'https://waitlist.lens.xyz/tw/',
156
- 'scope': 'users.read tweet.read offline.access',
157
- 'state': 'state', # Может быть как статичным, так и динамическим.
158
- 'code_challenge': 'challenge',
159
- 'code_challenge_method': 'plain'
160
- }
161
-
162
- bind_code = await twitter_client.oauth_2(**bind_data)
163
- # Передайте код авторизации (привязки) сервису.
164
- # Сервис также может потребовать state, если он динамический.
165
- ```
166
-
167
- Отправка сообщения:
168
- ```python
169
- bro = await twitter_client.request_user_data("@username")
170
- await twitter_client.send_message(bro.id, "I love you!")
171
- ```
172
-
173
- Запрос входящих сообщений:
174
- ```python
175
- messages = await twitter_client.request_messages()
176
- for message in messages:
177
- message_data = message["message_data"]
178
- recipient_id = message_data["recipient_id"]
179
- sender_id = message_data["sender_id"]
180
- text = message_data["text"]
181
- print(f"[id {sender_id}] -> [id {recipient_id}]: {text}")
182
- ```
183
-
184
- Другие методы:
185
- ```python
186
- # Выражение любви через твит
187
- tweet_id = await twitter_client.tweet("I love YOU! !!!!1!1")
188
- print(f"Любовь выражена! Tweet id: {tweet_id}")
189
-
190
- print(f"Tweet is pined: {await twitter_client.pin_tweet(tweet_id)}")
191
-
192
- # Лайк
193
- print(f"Tweet {tweet_id} is liked: {await twitter_client.like(tweet_id)}")
194
-
195
- # Репост (ретвит)
196
- print(f"Tweet {tweet_id} is retweeted. Tweet id: {await twitter_client.repost(tweet_id)}")
197
-
198
- # Коммент (реплай)
199
- print(f"Tweet {tweet_id} is replied. Reply id: {await twitter_client.reply(tweet_id, 'tem razão')}")
200
-
201
- # Подписываемся на Илона Маска
202
- print(f"@{elonmusk.username} is followed: {await twitter_client.follow(elonmusk.id)}")
203
-
204
- # Отписываемся от Илона Маска
205
- print(f"@{elonmusk.username} is unfollowed: {await twitter_client.unfollow(elonmusk.id)}")
206
-
207
- tweet_url = 'https://twitter.com/CreamIce_Cone/status/1691735090529976489'
208
- # Цитата (Quote tweet)
209
- quote_tweet_id = await twitter_client.quote(tweet_url, 'oh....')
210
- print(f"Quoted! Tweet id: {quote_tweet_id}")
211
-
212
- # Запрашиваем первых трех подписчиков
213
- # (Параметр count по каким-то причинам работает некорректно)
214
- followers = await twitter_client.request_followers(count=20)
215
- print("Твои подписчики:")
216
- for follower in followers:
217
- print(follower)
218
- ```
@@ -1,16 +0,0 @@
1
- twitter/__init__.py,sha256=hdrsdbH_qFhx6ro1ct79qF9SpkgFhxgbYUw9A4RVuec,684
2
- twitter/account.py,sha256=tHzBdc34pEJI2SRbjLcmKtwAzjhzUFsa4vIQqtXAc1s,3015
3
- twitter/base/__init__.py,sha256=x0EHKv4q_FI6xEq2nL4V9s8P6VWr6IaHTqdH9sXB5d8,133
4
- twitter/base/client.py,sha256=7byb0Psai-dvg_ww6Y7uyE2hV1pfTU653hFgVdRiqXo,478
5
- twitter/base/session.py,sha256=JFPS-9Qae1iY3NfNcywxvWWmRDijaU_Rjs3WaQ00iFA,2071
6
- twitter/client.py,sha256=TXcIr-HnuqEtYOAiS5fmvY2P7KumlLE0lOAytMq89N8,61346
7
- twitter/enums.py,sha256=-OH6Ibxarq5qt4E2AhkProVawcEyIf5YG_h_G5xiV9Y,270
8
- twitter/errors.py,sha256=PsvGP3hps1HNWdKbUPhEkuDqLUmmqzhpAkRtVrJr5jc,5007
9
- twitter/models.py,sha256=ttSNuhY1knTdI-Yty54OCJF5YzARc8IaA11zKNHV9p0,2063
10
- twitter/utils/__init__.py,sha256=pyhQXwTdp0HFwV_UNF4dTyklLD9RtaefA16SrQXeNlg,589
11
- twitter/utils/file.py,sha256=Sz2KEF9DnL04aOP1XabuMYMMF4VR8dJ_KWMEVvQ666Y,1120
12
- twitter/utils/html.py,sha256=hVtIRFI2yRAdWEaShFNBG-_ZWxd16og8i8OVDnFy5Hc,1971
13
- twitter/utils/other.py,sha256=UnUxS3uDR4eggbNN16xiw96VC_MNt9tOgnBlNWvRBoY,559
14
- tweepy_self-1.6.3.dist-info/METADATA,sha256=Nl46Hi1yQY6s47FPLnT0bMjhWTYR7gM18SJsZaDxhJQ,9304
15
- tweepy_self-1.6.3.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
16
- tweepy_self-1.6.3.dist-info/RECORD,,