tweetapi 1.0.0__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.
- tweetapi-1.0.0/.claude/settings.local.json +3 -0
- tweetapi-1.0.0/.gitignore +12 -0
- tweetapi-1.0.0/PKG-INFO +277 -0
- tweetapi-1.0.0/README.md +247 -0
- tweetapi-1.0.0/examples/create_post.py +37 -0
- tweetapi-1.0.0/examples/get_user.py +31 -0
- tweetapi-1.0.0/examples/search_tweets.py +20 -0
- tweetapi-1.0.0/pyproject.toml +63 -0
- tweetapi-1.0.0/tests/__init__.py +0 -0
- tweetapi-1.0.0/tests/test_client.py +245 -0
- tweetapi-1.0.0/tweetapi/__init__.py +37 -0
- tweetapi-1.0.0/tweetapi/client.py +146 -0
- tweetapi-1.0.0/tweetapi/errors.py +122 -0
- tweetapi-1.0.0/tweetapi/py.typed +0 -0
- tweetapi-1.0.0/tweetapi/resources/__init__.py +0 -0
- tweetapi-1.0.0/tweetapi/resources/auth.py +18 -0
- tweetapi-1.0.0/tweetapi/resources/community.py +68 -0
- tweetapi-1.0.0/tweetapi/resources/explore.py +21 -0
- tweetapi-1.0.0/tweetapi/resources/interaction.py +86 -0
- tweetapi-1.0.0/tweetapi/resources/list_.py +27 -0
- tweetapi-1.0.0/tweetapi/resources/post.py +52 -0
- tweetapi-1.0.0/tweetapi/resources/space.py +19 -0
- tweetapi-1.0.0/tweetapi/resources/tweet.py +31 -0
- tweetapi-1.0.0/tweetapi/resources/unencrypted_dm.py +63 -0
- tweetapi-1.0.0/tweetapi/resources/user.py +75 -0
- tweetapi-1.0.0/tweetapi/resources/xchat.py +44 -0
- tweetapi-1.0.0/tweetapi/types.py +484 -0
tweetapi-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tweetapi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for TweetAPI — Twitter/X Data API for developers and researchers
|
|
5
|
+
Project-URL: Homepage, https://tweetapi.com?utm_source=pypi&utm_medium=readme&utm_campaign=python-sdk
|
|
6
|
+
Project-URL: Documentation, https://tweetapi.com/docs?utm_source=pypi&utm_medium=readme&utm_campaign=python-sdk
|
|
7
|
+
Project-URL: Repository, https://github.com/tweetapi/tweetapi-python
|
|
8
|
+
Project-URL: Issues, https://github.com/tweetapi/tweetapi-python/issues
|
|
9
|
+
Author-email: TweetAPI <support@tweetapi.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
Keywords: social media api,tweet api,tweetapi,tweets,twitter,twitter api,twitter client,twitter data,twitter library,twitter sdk,twitter wrapper,x api
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Requires-Dist: requests>=2.28.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: responses>=0.23.0; extra == 'dev'
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# TweetAPI Python SDK
|
|
32
|
+
|
|
33
|
+
Official Python SDK for [TweetAPI](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk) — the Twitter/X Data API for developers and researchers.
|
|
34
|
+
|
|
35
|
+
Access tweets, user profiles, followers, analytics, and full interaction capabilities. 70+ endpoints with built-in error handling and type hints.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install tweetapi
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from tweetapi import TweetAPI
|
|
47
|
+
|
|
48
|
+
client = TweetAPI(api_key="YOUR_API_KEY")
|
|
49
|
+
|
|
50
|
+
# Get a user profile
|
|
51
|
+
user = client.user.get_by_username(username="elonmusk")
|
|
52
|
+
print(user["data"]["followerCount"]) # 180000000
|
|
53
|
+
|
|
54
|
+
# Search tweets
|
|
55
|
+
results = client.explore.search(query="bitcoin", type="Latest")
|
|
56
|
+
|
|
57
|
+
# Get followers with pagination
|
|
58
|
+
followers = client.user.get_followers(user_id="123456")
|
|
59
|
+
next_page = client.user.get_followers(
|
|
60
|
+
user_id="123456",
|
|
61
|
+
cursor=followers["pagination"]["nextCursor"],
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> **Get your free API key** — [100 requests, no credit card required](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
66
|
+
|
|
67
|
+
## Features
|
|
68
|
+
|
|
69
|
+
- **70+ endpoints** covering users, tweets, posts, interactions, DMs, communities, spaces, and search
|
|
70
|
+
- **Full type hints** with TypedDict definitions for IDE autocomplete
|
|
71
|
+
- **Solid error handling** with typed exceptions (`RateLimitError`, `NotFoundError`, etc.)
|
|
72
|
+
- **Single dependency** — `requests` only
|
|
73
|
+
- **Pagination support** with cursor-based navigation
|
|
74
|
+
- **Python 3.9+** compatible
|
|
75
|
+
|
|
76
|
+
## API Reference
|
|
77
|
+
|
|
78
|
+
### User
|
|
79
|
+
|
|
80
|
+
| Method | Description |
|
|
81
|
+
|--------|-------------|
|
|
82
|
+
| `client.user.get_by_username(username=...)` | Get user profile by username |
|
|
83
|
+
| `client.user.get_by_usernames(usernames=...)` | Get multiple users (comma-separated) |
|
|
84
|
+
| `client.user.get_by_user_id(user_id=...)` | Get user profile by ID |
|
|
85
|
+
| `client.user.get_by_user_ids(user_ids=...)` | Get multiple users by IDs |
|
|
86
|
+
| `client.user.get_tweets(user_id=...)` | Get a user's tweets |
|
|
87
|
+
| `client.user.get_tweets_and_replies(user_id=...)` | Get tweets and replies |
|
|
88
|
+
| `client.user.get_following(user_id=...)` | Get who a user follows |
|
|
89
|
+
| `client.user.get_followers(user_id=...)` | Get a user's followers |
|
|
90
|
+
| `client.user.get_verified_followers(user_id=...)` | Get verified followers |
|
|
91
|
+
| `client.user.get_subscriptions(user_id=...)` | Get subscriptions |
|
|
92
|
+
| `client.user.get_following_v1(user_id=...)` | Get following (v1, supports count) |
|
|
93
|
+
| `client.user.get_followers_v1(user_id=...)` | Get followers (v1, supports count) |
|
|
94
|
+
| `client.user.get_following_ids(user_id=...)` | Get following user IDs |
|
|
95
|
+
| `client.user.get_followers_ids(user_id=...)` | Get follower user IDs |
|
|
96
|
+
| `client.user.check_follow(subject_id=..., target_id=...)` | Check follow relationship |
|
|
97
|
+
| `client.user.about_account(username=...)` | Get account transparency info |
|
|
98
|
+
|
|
99
|
+
### Tweet
|
|
100
|
+
|
|
101
|
+
| Method | Description |
|
|
102
|
+
|--------|-------------|
|
|
103
|
+
| `client.tweet.get_details_and_conversation(tweet_id=...)` | Get tweet details and replies |
|
|
104
|
+
| `client.tweet.get_details_by_ids(ids=...)` | Get multiple tweets (max 200) |
|
|
105
|
+
| `client.tweet.get_retweets(tweet_id=...)` | Get who retweeted |
|
|
106
|
+
| `client.tweet.get_quotes(tweet_id=...)` | Get quote tweets |
|
|
107
|
+
| `client.tweet.translate(tweet_id=..., dst_lang=...)` | Translate a tweet |
|
|
108
|
+
|
|
109
|
+
### Post
|
|
110
|
+
|
|
111
|
+
| Method | Description |
|
|
112
|
+
|--------|-------------|
|
|
113
|
+
| `client.post.create_post(auth_token=..., text=..., proxy=...)` | Create a tweet |
|
|
114
|
+
| `client.post.create_post_quote(auth_token=..., text=..., attachment_url=..., proxy=...)` | Quote tweet |
|
|
115
|
+
| `client.post.create_post_with_media(auth_token=..., text=..., media=..., proxy=...)` | Tweet with media |
|
|
116
|
+
| `client.post.reply_post(auth_token=..., text=..., tweet_id=..., proxy=...)` | Reply to a tweet |
|
|
117
|
+
| `client.post.reply_post_with_media(...)` | Reply with media |
|
|
118
|
+
| `client.post.delete_post(auth_token=..., tweet_id=...)` | Delete a tweet |
|
|
119
|
+
|
|
120
|
+
### Interaction
|
|
121
|
+
|
|
122
|
+
| Method | Description |
|
|
123
|
+
|--------|-------------|
|
|
124
|
+
| `client.interaction.favorite_post(auth_token=..., tweet_id=...)` | Like a tweet |
|
|
125
|
+
| `client.interaction.unfavorite_post(auth_token=..., tweet_id=...)` | Unlike a tweet |
|
|
126
|
+
| `client.interaction.retweet(auth_token=..., tweet_id=...)` | Retweet |
|
|
127
|
+
| `client.interaction.delete_retweet(auth_token=..., tweet_id=...)` | Remove retweet |
|
|
128
|
+
| `client.interaction.bookmark(auth_token=..., tweet_id=...)` | Bookmark a tweet |
|
|
129
|
+
| `client.interaction.delete_bookmark(auth_token=..., tweet_id=...)` | Remove bookmark |
|
|
130
|
+
| `client.interaction.follow(auth_token=..., user_id=...)` | Follow a user |
|
|
131
|
+
| `client.interaction.unfollow(auth_token=..., user_id=...)` | Unfollow a user |
|
|
132
|
+
| `client.interaction.add_member_to_list(auth_token=..., list_id=..., user_id=...)` | Add to list |
|
|
133
|
+
| `client.interaction.remove_member_from_list(auth_token=..., list_id=..., user_id=...)` | Remove from list |
|
|
134
|
+
| `client.interaction.get_notifications(auth_token=...)` | Get notifications |
|
|
135
|
+
| `client.interaction.get_user_analytics(auth_token=...)` | Get analytics |
|
|
136
|
+
|
|
137
|
+
### List
|
|
138
|
+
|
|
139
|
+
| Method | Description |
|
|
140
|
+
|--------|-------------|
|
|
141
|
+
| `client.list.get_details(list_id=...)` | Get list details |
|
|
142
|
+
| `client.list.get_tweets(list_id=...)` | Get tweets in a list |
|
|
143
|
+
| `client.list.get_members(list_id=...)` | Get list members |
|
|
144
|
+
| `client.list.get_followers(list_id=...)` | Get list followers |
|
|
145
|
+
|
|
146
|
+
### Community
|
|
147
|
+
|
|
148
|
+
| Method | Description |
|
|
149
|
+
|--------|-------------|
|
|
150
|
+
| `client.community.get_details(community_id=...)` | Get community details |
|
|
151
|
+
| `client.community.get_tweets(community_id=..., sort_by=...)` | Get community tweets |
|
|
152
|
+
| `client.community.get_members(community_id=...)` | Get members |
|
|
153
|
+
| `client.community.search(query=...)` | Search communities |
|
|
154
|
+
| `client.community.create_post(auth_token=..., text=..., community_id=..., proxy=...)` | Post in community |
|
|
155
|
+
| `client.community.create_post_with_media(...)` | Post with media |
|
|
156
|
+
| `client.community.reply_post(...)` | Reply to community post |
|
|
157
|
+
| `client.community.reply_post_with_media(...)` | Reply with media |
|
|
158
|
+
| `client.community.join(auth_token=..., community_id=...)` | Join |
|
|
159
|
+
| `client.community.leave(auth_token=..., community_id=...)` | Leave |
|
|
160
|
+
|
|
161
|
+
### Space
|
|
162
|
+
|
|
163
|
+
| Method | Description |
|
|
164
|
+
|--------|-------------|
|
|
165
|
+
| `client.space.get_by_id(space_id=...)` | Get Space details |
|
|
166
|
+
| `client.space.get_stream_url(media_key=...)` | Get HLS stream URL |
|
|
167
|
+
|
|
168
|
+
### Explore
|
|
169
|
+
|
|
170
|
+
| Method | Description |
|
|
171
|
+
|--------|-------------|
|
|
172
|
+
| `client.explore.search(query=..., type=...)` | Search tweets/users/photos/videos |
|
|
173
|
+
|
|
174
|
+
### Auth
|
|
175
|
+
|
|
176
|
+
| Method | Description |
|
|
177
|
+
|--------|-------------|
|
|
178
|
+
| `client.auth.login(username=..., password=..., proxy=...)` | Log in, get auth tokens |
|
|
179
|
+
|
|
180
|
+
### X Chat (Encrypted DMs)
|
|
181
|
+
|
|
182
|
+
| Method | Description |
|
|
183
|
+
|--------|-------------|
|
|
184
|
+
| `client.xchat.setup(auth_token=..., user_id=..., pin=...)` | Initialize encrypted DMs |
|
|
185
|
+
| `client.xchat.get_conversations(auth_token=...)` | List conversations |
|
|
186
|
+
| `client.xchat.send(auth_token=..., recipient_id=..., message=...)` | Send message |
|
|
187
|
+
| `client.xchat.get_history(auth_token=..., conversation_id=...)` | Get history |
|
|
188
|
+
| `client.xchat.can_dm(auth_token=..., user_ids=...)` | Check DM availability |
|
|
189
|
+
|
|
190
|
+
### Unencrypted DMs
|
|
191
|
+
|
|
192
|
+
| Method | Description |
|
|
193
|
+
|--------|-------------|
|
|
194
|
+
| `client.dm.send_dm(auth_token=..., conversation_id=..., text=..., proxy=...)` | Send DM |
|
|
195
|
+
| `client.dm.get_dm_permissions(auth_token=..., recipient_ids=...)` | Check permissions |
|
|
196
|
+
| `client.dm.get_inbox_initial_state(auth_token=...)` | Get inbox state |
|
|
197
|
+
| `client.dm.get_inbox_trusted(auth_token=..., cursor=...)` | Trusted inbox |
|
|
198
|
+
| `client.dm.get_inbox_untrusted(auth_token=..., cursor=...)` | Message requests |
|
|
199
|
+
| `client.dm.get_conversation(auth_token=..., conversation_id=...)` | Get messages |
|
|
200
|
+
| `client.dm.get_dm_user_updates(auth_token=..., cursor=...)` | DM user updates |
|
|
201
|
+
| `client.dm.accept_conversation(auth_token=..., conversation_id=...)` | Accept request |
|
|
202
|
+
|
|
203
|
+
## Error Handling
|
|
204
|
+
|
|
205
|
+
The SDK throws typed exceptions you can catch and handle:
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
import time
|
|
209
|
+
from tweetapi import (
|
|
210
|
+
TweetAPI,
|
|
211
|
+
TweetAPIError,
|
|
212
|
+
AuthenticationError,
|
|
213
|
+
RateLimitError,
|
|
214
|
+
NotFoundError,
|
|
215
|
+
ValidationError,
|
|
216
|
+
ServerError,
|
|
217
|
+
NetworkError,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
client = TweetAPI(api_key="YOUR_API_KEY")
|
|
221
|
+
|
|
222
|
+
try:
|
|
223
|
+
user = client.user.get_by_username(username="elonmusk")
|
|
224
|
+
except RateLimitError as e:
|
|
225
|
+
# Wait and retry
|
|
226
|
+
print(f"Rate limited. Retry in {e.retry_after}s")
|
|
227
|
+
time.sleep(e.retry_after)
|
|
228
|
+
except NotFoundError:
|
|
229
|
+
print("User not found")
|
|
230
|
+
except AuthenticationError:
|
|
231
|
+
print("Invalid API key")
|
|
232
|
+
except ValidationError as e:
|
|
233
|
+
print(f"Bad request: {e.message}")
|
|
234
|
+
except ServerError:
|
|
235
|
+
print("API is having issues, try again later")
|
|
236
|
+
except NetworkError:
|
|
237
|
+
print("Network error — check your connection")
|
|
238
|
+
except TweetAPIError as e:
|
|
239
|
+
# Catch-all for any other API error
|
|
240
|
+
print(f"Error [{e.code}]: {e.message}")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Every error includes:
|
|
244
|
+
- `code` — API error code (e.g., `"ACCOUNT_SUSPENDED"`, `"RATE_LIMIT"`)
|
|
245
|
+
- `status_code` — HTTP status code
|
|
246
|
+
- `message` — Human-readable error message
|
|
247
|
+
- `details` — Additional context (field, reason, retry_after, etc.)
|
|
248
|
+
|
|
249
|
+
## Configuration
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
client = TweetAPI(
|
|
253
|
+
api_key="YOUR_API_KEY", # Required
|
|
254
|
+
base_url="https://...", # Optional (default: https://api.tweetapi.com)
|
|
255
|
+
timeout=30, # Optional (default: 30 seconds)
|
|
256
|
+
)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Requirements
|
|
260
|
+
|
|
261
|
+
- Python 3.9+
|
|
262
|
+
- `requests` library
|
|
263
|
+
|
|
264
|
+
## Links
|
|
265
|
+
|
|
266
|
+
- [Full Documentation](https://tweetapi.com/docs?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
267
|
+
- [Get API Key (Free)](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
268
|
+
- [Dashboard](https://tweetapi.com/dashboard?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
269
|
+
- [Node.js SDK](https://github.com/tweetapi/tweetapi-node)
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
*TweetAPI is a third-party service and is not affiliated with X Corp.*
|
tweetapi-1.0.0/README.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# TweetAPI Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python SDK for [TweetAPI](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk) — the Twitter/X Data API for developers and researchers.
|
|
4
|
+
|
|
5
|
+
Access tweets, user profiles, followers, analytics, and full interaction capabilities. 70+ endpoints with built-in error handling and type hints.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install tweetapi
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from tweetapi import TweetAPI
|
|
17
|
+
|
|
18
|
+
client = TweetAPI(api_key="YOUR_API_KEY")
|
|
19
|
+
|
|
20
|
+
# Get a user profile
|
|
21
|
+
user = client.user.get_by_username(username="elonmusk")
|
|
22
|
+
print(user["data"]["followerCount"]) # 180000000
|
|
23
|
+
|
|
24
|
+
# Search tweets
|
|
25
|
+
results = client.explore.search(query="bitcoin", type="Latest")
|
|
26
|
+
|
|
27
|
+
# Get followers with pagination
|
|
28
|
+
followers = client.user.get_followers(user_id="123456")
|
|
29
|
+
next_page = client.user.get_followers(
|
|
30
|
+
user_id="123456",
|
|
31
|
+
cursor=followers["pagination"]["nextCursor"],
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
> **Get your free API key** — [100 requests, no credit card required](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **70+ endpoints** covering users, tweets, posts, interactions, DMs, communities, spaces, and search
|
|
40
|
+
- **Full type hints** with TypedDict definitions for IDE autocomplete
|
|
41
|
+
- **Solid error handling** with typed exceptions (`RateLimitError`, `NotFoundError`, etc.)
|
|
42
|
+
- **Single dependency** — `requests` only
|
|
43
|
+
- **Pagination support** with cursor-based navigation
|
|
44
|
+
- **Python 3.9+** compatible
|
|
45
|
+
|
|
46
|
+
## API Reference
|
|
47
|
+
|
|
48
|
+
### User
|
|
49
|
+
|
|
50
|
+
| Method | Description |
|
|
51
|
+
|--------|-------------|
|
|
52
|
+
| `client.user.get_by_username(username=...)` | Get user profile by username |
|
|
53
|
+
| `client.user.get_by_usernames(usernames=...)` | Get multiple users (comma-separated) |
|
|
54
|
+
| `client.user.get_by_user_id(user_id=...)` | Get user profile by ID |
|
|
55
|
+
| `client.user.get_by_user_ids(user_ids=...)` | Get multiple users by IDs |
|
|
56
|
+
| `client.user.get_tweets(user_id=...)` | Get a user's tweets |
|
|
57
|
+
| `client.user.get_tweets_and_replies(user_id=...)` | Get tweets and replies |
|
|
58
|
+
| `client.user.get_following(user_id=...)` | Get who a user follows |
|
|
59
|
+
| `client.user.get_followers(user_id=...)` | Get a user's followers |
|
|
60
|
+
| `client.user.get_verified_followers(user_id=...)` | Get verified followers |
|
|
61
|
+
| `client.user.get_subscriptions(user_id=...)` | Get subscriptions |
|
|
62
|
+
| `client.user.get_following_v1(user_id=...)` | Get following (v1, supports count) |
|
|
63
|
+
| `client.user.get_followers_v1(user_id=...)` | Get followers (v1, supports count) |
|
|
64
|
+
| `client.user.get_following_ids(user_id=...)` | Get following user IDs |
|
|
65
|
+
| `client.user.get_followers_ids(user_id=...)` | Get follower user IDs |
|
|
66
|
+
| `client.user.check_follow(subject_id=..., target_id=...)` | Check follow relationship |
|
|
67
|
+
| `client.user.about_account(username=...)` | Get account transparency info |
|
|
68
|
+
|
|
69
|
+
### Tweet
|
|
70
|
+
|
|
71
|
+
| Method | Description |
|
|
72
|
+
|--------|-------------|
|
|
73
|
+
| `client.tweet.get_details_and_conversation(tweet_id=...)` | Get tweet details and replies |
|
|
74
|
+
| `client.tweet.get_details_by_ids(ids=...)` | Get multiple tweets (max 200) |
|
|
75
|
+
| `client.tweet.get_retweets(tweet_id=...)` | Get who retweeted |
|
|
76
|
+
| `client.tweet.get_quotes(tweet_id=...)` | Get quote tweets |
|
|
77
|
+
| `client.tweet.translate(tweet_id=..., dst_lang=...)` | Translate a tweet |
|
|
78
|
+
|
|
79
|
+
### Post
|
|
80
|
+
|
|
81
|
+
| Method | Description |
|
|
82
|
+
|--------|-------------|
|
|
83
|
+
| `client.post.create_post(auth_token=..., text=..., proxy=...)` | Create a tweet |
|
|
84
|
+
| `client.post.create_post_quote(auth_token=..., text=..., attachment_url=..., proxy=...)` | Quote tweet |
|
|
85
|
+
| `client.post.create_post_with_media(auth_token=..., text=..., media=..., proxy=...)` | Tweet with media |
|
|
86
|
+
| `client.post.reply_post(auth_token=..., text=..., tweet_id=..., proxy=...)` | Reply to a tweet |
|
|
87
|
+
| `client.post.reply_post_with_media(...)` | Reply with media |
|
|
88
|
+
| `client.post.delete_post(auth_token=..., tweet_id=...)` | Delete a tweet |
|
|
89
|
+
|
|
90
|
+
### Interaction
|
|
91
|
+
|
|
92
|
+
| Method | Description |
|
|
93
|
+
|--------|-------------|
|
|
94
|
+
| `client.interaction.favorite_post(auth_token=..., tweet_id=...)` | Like a tweet |
|
|
95
|
+
| `client.interaction.unfavorite_post(auth_token=..., tweet_id=...)` | Unlike a tweet |
|
|
96
|
+
| `client.interaction.retweet(auth_token=..., tweet_id=...)` | Retweet |
|
|
97
|
+
| `client.interaction.delete_retweet(auth_token=..., tweet_id=...)` | Remove retweet |
|
|
98
|
+
| `client.interaction.bookmark(auth_token=..., tweet_id=...)` | Bookmark a tweet |
|
|
99
|
+
| `client.interaction.delete_bookmark(auth_token=..., tweet_id=...)` | Remove bookmark |
|
|
100
|
+
| `client.interaction.follow(auth_token=..., user_id=...)` | Follow a user |
|
|
101
|
+
| `client.interaction.unfollow(auth_token=..., user_id=...)` | Unfollow a user |
|
|
102
|
+
| `client.interaction.add_member_to_list(auth_token=..., list_id=..., user_id=...)` | Add to list |
|
|
103
|
+
| `client.interaction.remove_member_from_list(auth_token=..., list_id=..., user_id=...)` | Remove from list |
|
|
104
|
+
| `client.interaction.get_notifications(auth_token=...)` | Get notifications |
|
|
105
|
+
| `client.interaction.get_user_analytics(auth_token=...)` | Get analytics |
|
|
106
|
+
|
|
107
|
+
### List
|
|
108
|
+
|
|
109
|
+
| Method | Description |
|
|
110
|
+
|--------|-------------|
|
|
111
|
+
| `client.list.get_details(list_id=...)` | Get list details |
|
|
112
|
+
| `client.list.get_tweets(list_id=...)` | Get tweets in a list |
|
|
113
|
+
| `client.list.get_members(list_id=...)` | Get list members |
|
|
114
|
+
| `client.list.get_followers(list_id=...)` | Get list followers |
|
|
115
|
+
|
|
116
|
+
### Community
|
|
117
|
+
|
|
118
|
+
| Method | Description |
|
|
119
|
+
|--------|-------------|
|
|
120
|
+
| `client.community.get_details(community_id=...)` | Get community details |
|
|
121
|
+
| `client.community.get_tweets(community_id=..., sort_by=...)` | Get community tweets |
|
|
122
|
+
| `client.community.get_members(community_id=...)` | Get members |
|
|
123
|
+
| `client.community.search(query=...)` | Search communities |
|
|
124
|
+
| `client.community.create_post(auth_token=..., text=..., community_id=..., proxy=...)` | Post in community |
|
|
125
|
+
| `client.community.create_post_with_media(...)` | Post with media |
|
|
126
|
+
| `client.community.reply_post(...)` | Reply to community post |
|
|
127
|
+
| `client.community.reply_post_with_media(...)` | Reply with media |
|
|
128
|
+
| `client.community.join(auth_token=..., community_id=...)` | Join |
|
|
129
|
+
| `client.community.leave(auth_token=..., community_id=...)` | Leave |
|
|
130
|
+
|
|
131
|
+
### Space
|
|
132
|
+
|
|
133
|
+
| Method | Description |
|
|
134
|
+
|--------|-------------|
|
|
135
|
+
| `client.space.get_by_id(space_id=...)` | Get Space details |
|
|
136
|
+
| `client.space.get_stream_url(media_key=...)` | Get HLS stream URL |
|
|
137
|
+
|
|
138
|
+
### Explore
|
|
139
|
+
|
|
140
|
+
| Method | Description |
|
|
141
|
+
|--------|-------------|
|
|
142
|
+
| `client.explore.search(query=..., type=...)` | Search tweets/users/photos/videos |
|
|
143
|
+
|
|
144
|
+
### Auth
|
|
145
|
+
|
|
146
|
+
| Method | Description |
|
|
147
|
+
|--------|-------------|
|
|
148
|
+
| `client.auth.login(username=..., password=..., proxy=...)` | Log in, get auth tokens |
|
|
149
|
+
|
|
150
|
+
### X Chat (Encrypted DMs)
|
|
151
|
+
|
|
152
|
+
| Method | Description |
|
|
153
|
+
|--------|-------------|
|
|
154
|
+
| `client.xchat.setup(auth_token=..., user_id=..., pin=...)` | Initialize encrypted DMs |
|
|
155
|
+
| `client.xchat.get_conversations(auth_token=...)` | List conversations |
|
|
156
|
+
| `client.xchat.send(auth_token=..., recipient_id=..., message=...)` | Send message |
|
|
157
|
+
| `client.xchat.get_history(auth_token=..., conversation_id=...)` | Get history |
|
|
158
|
+
| `client.xchat.can_dm(auth_token=..., user_ids=...)` | Check DM availability |
|
|
159
|
+
|
|
160
|
+
### Unencrypted DMs
|
|
161
|
+
|
|
162
|
+
| Method | Description |
|
|
163
|
+
|--------|-------------|
|
|
164
|
+
| `client.dm.send_dm(auth_token=..., conversation_id=..., text=..., proxy=...)` | Send DM |
|
|
165
|
+
| `client.dm.get_dm_permissions(auth_token=..., recipient_ids=...)` | Check permissions |
|
|
166
|
+
| `client.dm.get_inbox_initial_state(auth_token=...)` | Get inbox state |
|
|
167
|
+
| `client.dm.get_inbox_trusted(auth_token=..., cursor=...)` | Trusted inbox |
|
|
168
|
+
| `client.dm.get_inbox_untrusted(auth_token=..., cursor=...)` | Message requests |
|
|
169
|
+
| `client.dm.get_conversation(auth_token=..., conversation_id=...)` | Get messages |
|
|
170
|
+
| `client.dm.get_dm_user_updates(auth_token=..., cursor=...)` | DM user updates |
|
|
171
|
+
| `client.dm.accept_conversation(auth_token=..., conversation_id=...)` | Accept request |
|
|
172
|
+
|
|
173
|
+
## Error Handling
|
|
174
|
+
|
|
175
|
+
The SDK throws typed exceptions you can catch and handle:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
import time
|
|
179
|
+
from tweetapi import (
|
|
180
|
+
TweetAPI,
|
|
181
|
+
TweetAPIError,
|
|
182
|
+
AuthenticationError,
|
|
183
|
+
RateLimitError,
|
|
184
|
+
NotFoundError,
|
|
185
|
+
ValidationError,
|
|
186
|
+
ServerError,
|
|
187
|
+
NetworkError,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
client = TweetAPI(api_key="YOUR_API_KEY")
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
user = client.user.get_by_username(username="elonmusk")
|
|
194
|
+
except RateLimitError as e:
|
|
195
|
+
# Wait and retry
|
|
196
|
+
print(f"Rate limited. Retry in {e.retry_after}s")
|
|
197
|
+
time.sleep(e.retry_after)
|
|
198
|
+
except NotFoundError:
|
|
199
|
+
print("User not found")
|
|
200
|
+
except AuthenticationError:
|
|
201
|
+
print("Invalid API key")
|
|
202
|
+
except ValidationError as e:
|
|
203
|
+
print(f"Bad request: {e.message}")
|
|
204
|
+
except ServerError:
|
|
205
|
+
print("API is having issues, try again later")
|
|
206
|
+
except NetworkError:
|
|
207
|
+
print("Network error — check your connection")
|
|
208
|
+
except TweetAPIError as e:
|
|
209
|
+
# Catch-all for any other API error
|
|
210
|
+
print(f"Error [{e.code}]: {e.message}")
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Every error includes:
|
|
214
|
+
- `code` — API error code (e.g., `"ACCOUNT_SUSPENDED"`, `"RATE_LIMIT"`)
|
|
215
|
+
- `status_code` — HTTP status code
|
|
216
|
+
- `message` — Human-readable error message
|
|
217
|
+
- `details` — Additional context (field, reason, retry_after, etc.)
|
|
218
|
+
|
|
219
|
+
## Configuration
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
client = TweetAPI(
|
|
223
|
+
api_key="YOUR_API_KEY", # Required
|
|
224
|
+
base_url="https://...", # Optional (default: https://api.tweetapi.com)
|
|
225
|
+
timeout=30, # Optional (default: 30 seconds)
|
|
226
|
+
)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Requirements
|
|
230
|
+
|
|
231
|
+
- Python 3.9+
|
|
232
|
+
- `requests` library
|
|
233
|
+
|
|
234
|
+
## Links
|
|
235
|
+
|
|
236
|
+
- [Full Documentation](https://tweetapi.com/docs?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
237
|
+
- [Get API Key (Free)](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
238
|
+
- [Dashboard](https://tweetapi.com/dashboard?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
|
|
239
|
+
- [Node.js SDK](https://github.com/tweetapi/tweetapi-node)
|
|
240
|
+
|
|
241
|
+
## License
|
|
242
|
+
|
|
243
|
+
MIT
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
*TweetAPI is a third-party service and is not affiliated with X Corp.*
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from tweetapi import TweetAPI, AuthenticationError, TweetAPIError
|
|
2
|
+
|
|
3
|
+
client = TweetAPI(api_key="YOUR_API_KEY")
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
# First, log in to get an auth token
|
|
7
|
+
login_result = client.auth.login(
|
|
8
|
+
username="your_twitter_username",
|
|
9
|
+
password="your_twitter_password",
|
|
10
|
+
proxy="hostname:port@username:password",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
auth_token = login_result["data"]["cookies"]["auth_token"]
|
|
14
|
+
print(f'Logged in as @{login_result["data"]["user"]["username"]}')
|
|
15
|
+
|
|
16
|
+
# Create a tweet
|
|
17
|
+
post = client.post.create_post(
|
|
18
|
+
auth_token=auth_token,
|
|
19
|
+
text="Hello from TweetAPI! 🚀",
|
|
20
|
+
proxy="hostname:port@username:password",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
print(f'Tweet created: {post["data"]["metadata"]["tweet_id"]}')
|
|
24
|
+
print(f'URL: {post["data"]["metadata"]["url"]}')
|
|
25
|
+
|
|
26
|
+
# Like the tweet we just created
|
|
27
|
+
client.interaction.favorite_post(
|
|
28
|
+
auth_token=auth_token,
|
|
29
|
+
tweet_id=post["data"]["id"],
|
|
30
|
+
proxy="hostname:port@username:password",
|
|
31
|
+
)
|
|
32
|
+
print("Liked the tweet!")
|
|
33
|
+
|
|
34
|
+
except AuthenticationError:
|
|
35
|
+
print("Authentication failed. Check your credentials.")
|
|
36
|
+
except TweetAPIError as e:
|
|
37
|
+
print(f"API error [{e.code}]: {e.message}")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from tweetapi import TweetAPI, NotFoundError, RateLimitError, TweetAPIError
|
|
2
|
+
|
|
3
|
+
client = TweetAPI(api_key="YOUR_API_KEY")
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
# Get a single user by username
|
|
7
|
+
user = client.user.get_by_username(username="elonmusk")
|
|
8
|
+
data = user["data"]
|
|
9
|
+
print(f'{data["name"]} (@{data["username"]})')
|
|
10
|
+
print(f'Followers: {data["followerCount"]:,}')
|
|
11
|
+
print(f'Tweets: {data["tweetCount"]:,}')
|
|
12
|
+
print(f'Verified: {data["isBlueVerified"]}')
|
|
13
|
+
|
|
14
|
+
# Get first page of followers
|
|
15
|
+
followers = client.user.get_followers(user_id=data["id"])
|
|
16
|
+
print(f"\nFirst {len(followers['data'])} followers:")
|
|
17
|
+
for follower in followers["data"][:5]:
|
|
18
|
+
print(f' - @{follower["username"]} ({follower["followerCount"]} followers)')
|
|
19
|
+
|
|
20
|
+
# Paginate to next page
|
|
21
|
+
next_cursor = followers["pagination"]["nextCursor"]
|
|
22
|
+
if next_cursor:
|
|
23
|
+
next_page = client.user.get_followers(user_id=data["id"], cursor=next_cursor)
|
|
24
|
+
print(f"\nNext page: {len(next_page['data'])} more followers")
|
|
25
|
+
|
|
26
|
+
except NotFoundError:
|
|
27
|
+
print("User not found")
|
|
28
|
+
except RateLimitError as e:
|
|
29
|
+
print(f"Rate limited. Retry in {e.retry_after} seconds")
|
|
30
|
+
except TweetAPIError as e:
|
|
31
|
+
print(f"API error [{e.code}]: {e.message}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from tweetapi import TweetAPI
|
|
2
|
+
|
|
3
|
+
client = TweetAPI(api_key="YOUR_API_KEY")
|
|
4
|
+
|
|
5
|
+
# Search for latest tweets about Bitcoin
|
|
6
|
+
results = client.explore.search(query="bitcoin", type="Latest")
|
|
7
|
+
|
|
8
|
+
print(f'Found {results["meta"]["resultCount"]} results in {results["meta"]["completedIn"]}ms\n')
|
|
9
|
+
|
|
10
|
+
for item in results["data"]:
|
|
11
|
+
if "text" in item and "author" in item:
|
|
12
|
+
author = item["author"]
|
|
13
|
+
print(f'@{author["username"]}: {item["text"][:100]}')
|
|
14
|
+
print(f' ♥ {item["likeCount"]} 🔁 {item["retweetCount"]} 💬 {item["replyCount"]}\n')
|
|
15
|
+
|
|
16
|
+
# Paginate if more results exist
|
|
17
|
+
next_cursor = results["pagination"]["nextCursor"]
|
|
18
|
+
if next_cursor:
|
|
19
|
+
print(f'More results available. Use cursor to paginate:')
|
|
20
|
+
print(f' cursor="{next_cursor}"')
|