tweepy-self 1.6.3__py3-none-any.whl → 1.10.0b9__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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,,