tweepy-self 1.0.0b1__py3-none-any.whl → 1.0.0b2__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.
@@ -0,0 +1,218 @@
1
+ Metadata-Version: 2.1
2
+ Name: tweepy-self
3
+ Version: 1.0.0b2
4
+ Summary: Twitter (selfbot) for Python!
5
+ Author: Alen
6
+ Author-email: alen.kimov@gmail.com
7
+ Requires-Python: >=3.9,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Dist: beautifulsoup4 (>=4,<5)
14
+ Requires-Dist: better-proxy (==0.5.0)
15
+ Requires-Dist: curl_cffi (==0.6.0b9)
16
+ Requires-Dist: lxml (>=5,<6)
17
+ Requires-Dist: pydantic (>=2,<3)
18
+ Requires-Dist: pyotp (>=2,<3)
19
+ Requires-Dist: python3-capsolver (>=0.9,<0.10)
20
+ Requires-Dist: yarl (>=1,<2)
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
+
28
+ A modern, easy to use, feature-rich, and async ready API wrapper for Twitter's user API written in Python.
29
+
30
+ - Docs (soon)
31
+
32
+ More libraries of the family:
33
+ - [better-web3](https://github.com/alenkimov/better_web3)
34
+ - [better-proxy](https://github.com/alenkimov/better_proxy)
35
+ - [better-automation](https://github.com/alenkimov/better_automation)
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")
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
+ ```
@@ -0,0 +1,16 @@
1
+ twitter/__init__.py,sha256=ydA6wuWhW7-0sYmaJyl5_7wIaekKdaBaN7aO6elywLk,465
2
+ twitter/account.py,sha256=vXPd3ag3lmYbSblAnHJLm6t42SyFNbULpjWkRPiDhT0,1787
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=6-gLhdSCaTCd_zv3YgUtVRGbfiAawXuDRBoo7s5bGSs,2234
6
+ twitter/client.py,sha256=v2ebGB3NxmEmStePAddNR5XX7oqBCn0Fm86wf0l7MVI,53004
7
+ twitter/errors.py,sha256=U6kGyNp_5tEq-RwxLjm61muJLEp5BYBq9vrPBkCxr_g,4088
8
+ twitter/models.py,sha256=3-Lft160msCqOjRPubOmxMqWUkmjlTSzHSGsvZK91nU,1817
9
+ twitter/utils/__init__.py,sha256=2sjQEu5jJgUEpGYT_arwNVhaboywCbYLB00eiD0mZCk,743
10
+ twitter/utils/accounts.py,sha256=lp7c4GyScAsY65V52V5Buquj8OZgWFyi-54YloRpOfE,1556
11
+ twitter/utils/file.py,sha256=-6n8I8KWDlntfciJJsfIeOi0gmqoHRIe1ldIx1ynGUE,1118
12
+ twitter/utils/html.py,sha256=Cs55MxVyZLSKiCEj11ALUrnCW9ADZ4CEDCE0gKESzO0,1627
13
+ twitter/utils/other.py,sha256=4NaGd2CIJVrDiW17shcrDlJRqFkQNbBSTiiH7kNWcww,559
14
+ tweepy_self-1.0.0b2.dist-info/METADATA,sha256=0rOKLx8U1hRVeRKk9T6qnRHu_RAP3sqbOFV5qSajmKA,9230
15
+ tweepy_self-1.0.0b2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
16
+ tweepy_self-1.0.0b2.dist-info/RECORD,,
twitter/__init__.py CHANGED
@@ -5,9 +5,9 @@ Twitter API Wrapper
5
5
  A basic wrapper for the Twitter user API.
6
6
  """
7
7
 
8
- from ._twitter_client import Client
9
- from ._account import Account, AccountStatus
10
- from ._models import Tweet, UserData
8
+ from .client import Client
9
+ from .account import Account, AccountStatus
10
+ from .models import Tweet, UserData
11
11
  from . import errors, utils
12
12
 
13
13
  __all__ = [
@@ -1,14 +1,10 @@
1
1
  import enum
2
2
 
3
+ from pydantic import BaseModel, Field
3
4
  import pyotp
4
5
 
5
6
  from .utils import hidden_value
6
7
 
7
- # TODO Валидация
8
- # AUTH_TOKEN_PATTERN = r"^[a-f0-9]{40}$"
9
- # BACKUP_CODE_PATTERN = r"^[a-z0-9]{12}$"
10
- # KEY_2FA_PATTERN = r"^[A-Z0-9]{16}$"
11
-
12
8
 
13
9
  class AccountStatus(enum.StrEnum):
14
10
  BAD_TOKEN = "BAD_TOKEN" # (401) 32
@@ -21,38 +17,17 @@ class AccountStatus(enum.StrEnum):
21
17
  return self.value
22
18
 
23
19
 
24
- class Account:
25
- auth_token: str | None
20
+ class Account(BaseModel):
21
+ auth_token: str | None = Field(default=None, pattern=r"^[a-f0-9]{40}$")
26
22
  ct0: str | None
27
23
  id: int | None
28
24
  name: str | None
29
25
  username: str | None
30
26
  password: str | None
31
27
  email: str | None
32
- key2fa: str | None
33
- backup_code: str | None
34
- status: AccountStatus
35
-
36
- def __init__(
37
- self,
38
- auth_token: str = None,
39
- *,
40
- username: str = None,
41
- password: str = None,
42
- email: str = None,
43
- key2fa: str = None,
44
- backup_code: str = None,
45
- ):
46
- self.auth_token = auth_token
47
- self.ct0 = None
48
- self.id = None
49
- self.name = None
50
- self.username = username
51
- self.password = password
52
- self.email = email
53
- self.key2fa = key2fa
54
- self.backup_code = backup_code
55
- self.status = AccountStatus.UNKNOWN
28
+ key2fa: str | None = Field(default=None, pattern=r"^[a-f0-9]{12}$")
29
+ backup_code: str | None = Field(default=None, pattern=r"^[A-Z0-9]{16}$")
30
+ status: AccountStatus = AccountStatus.UNKNOWN
56
31
 
57
32
  @property
58
33
  def hidden_auth_token(self) -> str | None:
@@ -0,0 +1,7 @@
1
+ from .client import BaseClient
2
+ from .session import BaseAsyncSession
3
+
4
+ __all__ = [
5
+ "BaseClient",
6
+ "BaseAsyncSession",
7
+ ]
@@ -1,4 +1,4 @@
1
- from ._session import BaseAsyncSession
1
+ from .session import BaseAsyncSession
2
2
 
3
3
 
4
4
  class BaseClient:
@@ -23,10 +23,10 @@ from .errors import (
23
23
  Locked,
24
24
  Suspended,
25
25
  )
26
- from ._file_utils import to_json
27
- from ._client import BaseClient
28
- from ._account import Account, AccountStatus
29
- from ._models import UserData, Tweet
26
+ from .utils import to_json
27
+ from .base import BaseClient
28
+ from .account import Account, AccountStatus
29
+ from .models import UserData, Tweet
30
30
  from .utils import remove_at_sign, parse_oauth_html, parse_unlock_html
31
31
 
32
32
 
twitter/errors.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from curl_cffi import requests
2
2
 
3
- from ._account import Account
3
+ from .account import Account
4
4
 
5
5
  __all__ = [
6
6
  "TwitterException",
@@ -0,0 +1,42 @@
1
+ from .file import (
2
+ copy_file,
3
+ load_lines,
4
+ load_json,
5
+ load_toml,
6
+ write_lines,
7
+ write_json,
8
+ to_json,
9
+ )
10
+ from .accounts import (
11
+ load_accounts_from_file,
12
+ extract_accounts_to_file,
13
+ )
14
+ from .html import (
15
+ parse_unlock_html,
16
+ parse_oauth_html,
17
+ )
18
+ from .other import (
19
+ remove_at_sign,
20
+ tweet_url,
21
+ to_datetime,
22
+ hidden_value,
23
+ )
24
+
25
+
26
+ __all__ = [
27
+ "copy_file",
28
+ "load_lines",
29
+ "load_json",
30
+ "load_toml",
31
+ "write_lines",
32
+ "write_json",
33
+ "to_json",
34
+ "load_accounts_from_file",
35
+ "extract_accounts_to_file",
36
+ "parse_unlock_html",
37
+ "parse_oauth_html",
38
+ "remove_at_sign",
39
+ "tweet_url",
40
+ "to_datetime",
41
+ "hidden_value",
42
+ ]
@@ -0,0 +1,43 @@
1
+ from pathlib import Path
2
+ from typing import Sequence, Iterable
3
+
4
+ from .file import load_lines, write_lines
5
+ from ..account import Account
6
+
7
+
8
+ def load_accounts_from_file(
9
+ filepath: Path | str,
10
+ *,
11
+ separator: str = ":",
12
+ fields: Sequence[str] = ("auth_token", "password", "email", "username"),
13
+ ) -> list[Account]:
14
+ """
15
+ :param filepath: Путь до файла с данными об аккаунтах.
16
+ :param separator: Разделитель между данными в строке.
17
+ :param fields: Кортеж, содержащий имена полей в порядке их появления в строке.
18
+ :return: Список Twitter аккаунтов.
19
+ """
20
+ accounts = []
21
+ for line in load_lines(filepath):
22
+ data = dict(zip(fields, line.split(separator)))
23
+ data.update({key: None for key in data if not data[key]})
24
+ accounts.append(Account(**data))
25
+ return accounts
26
+
27
+
28
+ def extract_accounts_to_file(
29
+ filepath: Path | str,
30
+ accounts: Iterable[Account],
31
+ *,
32
+ separator: str = ":",
33
+ fields: Sequence[str] = ("auth_token", "password", "email", "username"),
34
+ ):
35
+ lines = []
36
+ for account in accounts:
37
+ account_data = []
38
+ for field_name in fields:
39
+ field = getattr(account, field_name)
40
+ field = field if field is not None else ""
41
+ account_data.append(field)
42
+ lines.append(separator.join(account_data))
43
+ write_lines(filepath, lines)
twitter/utils/file.py ADDED
@@ -0,0 +1,41 @@
1
+ import json
2
+ import shutil
3
+ import tomllib
4
+ from pathlib import Path
5
+ from typing import Iterable
6
+
7
+
8
+ def copy_file(source_path: Path | str, destination_path: Path | str):
9
+ destination_path = Path(destination_path)
10
+ if destination_path.exists():
11
+ return
12
+ shutil.copy2(str(source_path), str(destination_path))
13
+
14
+
15
+ def load_toml(filepath: Path | str) -> dict:
16
+ with open(filepath, "rb") as file:
17
+ return tomllib.load(file)
18
+
19
+
20
+ def load_lines(filepath: Path | str) -> list[str]:
21
+ with open(filepath, "r") as file:
22
+ return [line.strip() for line in file.readlines() if line != "\n"]
23
+
24
+
25
+ def write_lines(filepath: Path | str, lines: Iterable[str]):
26
+ with open(filepath, "w") as file:
27
+ file.write("\n".join(lines))
28
+
29
+
30
+ def load_json(filepath: Path | str) -> dict:
31
+ with open(filepath, "r") as file:
32
+ return json.load(file)
33
+
34
+
35
+ def write_json(filepath: Path | str, data):
36
+ with open(filepath, "w") as file:
37
+ json.dump(data, file, indent=4)
38
+
39
+
40
+ def to_json(obj) -> str:
41
+ return json.dumps(obj, separators=(',', ':'), ensure_ascii=True)
@@ -1,5 +1,3 @@
1
- from datetime import datetime
2
-
3
1
  from bs4 import BeautifulSoup
4
2
 
5
3
 
@@ -29,26 +27,3 @@ def parse_unlock_html(html: str) -> tuple[str | None, str | None, bool]:
29
27
  verification_string = soup.find('input', id='verification_string')
30
28
  needs_unlock = bool(verification_string)
31
29
  return authenticity_token, assignment_token, needs_unlock
32
-
33
-
34
- def remove_at_sign(username: str) -> str:
35
- if username.startswith("@"):
36
- return username[1:]
37
- return username
38
-
39
-
40
- def tweet_url(username: str, tweet_id: int) -> str:
41
- """
42
- :return: Tweet URL
43
- """
44
- return f"https://x.com/{username}/status/{tweet_id}"
45
-
46
-
47
- def to_datetime(twitter_datetime: str):
48
- return datetime.strptime(twitter_datetime, '%a %b %d %H:%M:%S +0000 %Y')
49
-
50
-
51
- def hidden_value(value: str) -> str:
52
- start = value[:3]
53
- end = value[-3:]
54
- return f"{start}**{end}"
twitter/utils/other.py ADDED
@@ -0,0 +1,24 @@
1
+ from datetime import datetime
2
+
3
+
4
+ def remove_at_sign(username: str) -> str:
5
+ if username.startswith("@"):
6
+ return username[1:]
7
+ return username
8
+
9
+
10
+ def tweet_url(username: str, tweet_id: int) -> str:
11
+ """
12
+ :return: Tweet URL
13
+ """
14
+ return f"https://x.com/{username}/status/{tweet_id}"
15
+
16
+
17
+ def to_datetime(twitter_datetime: str):
18
+ return datetime.strptime(twitter_datetime, '%a %b %d %H:%M:%S +0000 %Y')
19
+
20
+
21
+ def hidden_value(value: str) -> str:
22
+ start = value[:3]
23
+ end = value[-3:]
24
+ return f"{start}**{end}"
@@ -1,63 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: tweepy-self
3
- Version: 1.0.0b1
4
- Summary: Twitter (selfbot) for Python!
5
- Author: Alen
6
- Author-email: alen.kimov@gmail.com
7
- Requires-Python: >=3.9,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.9
10
- Classifier: Programming Language :: Python :: 3.10
11
- Classifier: Programming Language :: Python :: 3.11
12
- Classifier: Programming Language :: Python :: 3.12
13
- Requires-Dist: beautifulsoup4 (>=4,<5)
14
- Requires-Dist: better-proxy (==0.5.0)
15
- Requires-Dist: curl_cffi (==0.6.0b9)
16
- Requires-Dist: lxml (>=5,<6)
17
- Requires-Dist: pydantic (>=2,<3)
18
- Requires-Dist: pyotp (>=2,<3)
19
- Requires-Dist: python3-capsolver (>=0.9,<0.10)
20
- Requires-Dist: yarl (>=1,<2)
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
-
28
- A modern, easy to use, feature-rich, and async ready API wrapper for Twitter's user API written in Python.
29
-
30
- - Docs (soon)
31
-
32
- More libraries of the family:
33
- - [better-web3](https://github.com/alenkimov/better_web3)
34
- - [better-proxy](https://github.com/alenkimov/better_proxy)
35
-
36
- Отдельное спасибо [Кузнице Ботов](https://t.me/bots_forge), как соавторам! Подписывайтесь на их Telegram :)
37
-
38
- ## Key Features
39
- - Modern Pythonic API using async and await.
40
- - Prevents user account automation detection.
41
-
42
- ## Installing
43
- ```bash
44
- pip install tweepy-self
45
- ```
46
-
47
- ## Example
48
- ```python
49
- import asyncio
50
- import twitter
51
-
52
- account = twitter.Account("auth_token")
53
-
54
- async def main():
55
- async with twitter.Client(account) as twitter_client:
56
- await twitter_client.tweet("Hello, tweepy-self! <3")
57
-
58
- asyncio.run(main())
59
- ```
60
-
61
- ## More
62
- 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
63
-
@@ -1,12 +0,0 @@
1
- twitter/__init__.py,sha256=nC-rEZfRkk8Bp26yWtlzciR7mdOrfcI_KXHcnkW4hyk,476
2
- twitter/_account.py,sha256=dTNHdYhAJgznrXp6nRRtswuWMR5LjohrtwmPf53SSDU,2382
3
- twitter/_client.py,sha256=3QUfb5uH-erDt2STx9BELSB6u_5U1p_oyPs6As0tIOo,479
4
- twitter/_file_utils.py,sha256=ePgsHMlGmegBBMK5ZhCZVeJp58WRQ7kaArPDAgjSu-c,495
5
- twitter/_models.py,sha256=3-Lft160msCqOjRPubOmxMqWUkmjlTSzHSGsvZK91nU,1817
6
- twitter/_session.py,sha256=6-gLhdSCaTCd_zv3YgUtVRGbfiAawXuDRBoo7s5bGSs,2234
7
- twitter/_twitter_client.py,sha256=l0fztx0sk03ojWStDe0oovQpKWqCj-vNZzLK05b_E-Y,53015
8
- twitter/errors.py,sha256=7BzHnm3iinbkQrW38PqEqpZNwJCk41l57qQ2hhOV59I,4089
9
- twitter/utils.py,sha256=AlE1Z7Vxgm9i6vWi8rUso9gPobKnZh-ZFiDBT90YNA8,2188
10
- tweepy_self-1.0.0b1.dist-info/METADATA,sha256=jb6otKQVeG13qg53hbt4iUdVr1VtPi44gpn1p1qQFaI,2192
11
- tweepy_self-1.0.0b1.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
12
- tweepy_self-1.0.0b1.dist-info/RECORD,,
twitter/_file_utils.py DELETED
@@ -1,17 +0,0 @@
1
- import json
2
- from pathlib import Path
3
- from typing import Iterable
4
-
5
-
6
- def load_lines(filepath: Path | str) -> list[str]:
7
- with open(filepath, "r") as file:
8
- return [line.strip() for line in file.readlines() if line != "\n"]
9
-
10
-
11
- def write_lines(filepath: Path | str, lines: Iterable[str]):
12
- with open(filepath, "w") as file:
13
- file.write("\n".join(lines))
14
-
15
-
16
- def to_json(obj) -> str:
17
- return json.dumps(obj, separators=(',', ':'), ensure_ascii=True, default=str)
File without changes
File without changes