tweetapi 2.2.0__tar.gz → 2.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {tweetapi-2.2.0 → tweetapi-2.2.1}/PKG-INFO +49 -58
  2. {tweetapi-2.2.0 → tweetapi-2.2.1}/README.md +47 -56
  3. {tweetapi-2.2.0 → tweetapi-2.2.1}/pyproject.toml +2 -2
  4. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/__init__.py +1 -1
  5. {tweetapi-2.2.0 → tweetapi-2.2.1}/.gitignore +0 -0
  6. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/client.py +0 -0
  7. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/errors.py +0 -0
  8. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/pagination.py +0 -0
  9. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/py.typed +0 -0
  10. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/__init__.py +0 -0
  11. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/auth.py +0 -0
  12. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/community.py +0 -0
  13. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/explore.py +0 -0
  14. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/interaction.py +0 -0
  15. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/list_.py +0 -0
  16. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/post.py +0 -0
  17. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/profile.py +0 -0
  18. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/space.py +0 -0
  19. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/tweet.py +0 -0
  20. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/unencrypted_dm.py +0 -0
  21. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/user.py +0 -0
  22. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/resources/xchat.py +0 -0
  23. {tweetapi-2.2.0 → tweetapi-2.2.1}/tweetapi/types.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: tweetapi
3
- Version: 2.2.0
4
- Summary: Official Python SDK for TweetAPI — Twitter/X Data API for developers and researchers
3
+ Version: 2.2.1
4
+ Summary: Python SDK for TweetAPI's Twitter/X data and account API
5
5
  Project-URL: Homepage, https://tweetapi.com?utm_source=pypi&utm_medium=readme&utm_campaign=python-sdk
6
6
  Project-URL: Documentation, https://tweetapi.com/docs?utm_source=pypi&utm_medium=readme&utm_campaign=python-sdk
7
7
  Project-URL: Repository, https://github.com/tweetapi/python
@@ -30,9 +30,7 @@ Description-Content-Type: text/markdown
30
30
 
31
31
  # TweetAPI Python SDK
32
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.
33
+ `tweetapi` is the Python SDK for [TweetAPI](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk). It provides methods for users, tweets, posts, profiles, interactions, lists, communities, Spaces, search, authentication, and direct messages.
36
34
 
37
35
  ## Install
38
36
 
@@ -40,7 +38,7 @@ Access tweets, user profiles, followers, analytics, and full interaction capabil
40
38
  pip install tweetapi
41
39
  ```
42
40
 
43
- ## Quick Start
41
+ ## Quick start
44
42
 
45
43
  ```python
46
44
  from tweetapi import TweetAPI
@@ -49,7 +47,7 @@ client = TweetAPI(api_key="YOUR_API_KEY")
49
47
 
50
48
  # Get a user profile
51
49
  user = client.user.get_by_username(username="elonmusk")
52
- print(user["data"]["followerCount"]) # 180000000
50
+ print(user["data"]["followerCount"])
53
51
 
54
52
  # Search tweets
55
53
  results = client.explore.search(query="bitcoin", type="Latest")
@@ -62,21 +60,18 @@ next_page = client.user.get_followers(
62
60
  )
63
61
  ```
64
62
 
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)
63
+ [Create an API key](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk) with 100 included requests. No credit card is required.
66
64
 
67
- ## Features
65
+ ## SDK behavior
68
66
 
69
- - **70+ endpoints** covering users, tweets, posts, interactions, DMs, communities, spaces, and search
70
- - **Full type hints** with TypedDict response types for IDE autocomplete
71
- - **Automatic retry with backoff** on rate limits (429) and server errors (5xx)
72
- - **Auto-pagination helpers** — iterate all pages with a simple `for` loop
73
- - **Solid error handling** with typed exceptions (`RateLimitError`, `NotFoundError`, etc.)
74
- - **Rate limit awareness** — `retry_after` respected automatically, state exposed via `client.rate_limit_info`
75
- - **Split timeouts** — separate connect and read timeouts
76
- - **Single dependency** — `requests` only
77
- - **Python 3.9+** compatible
67
+ - Public methods have type annotations, and response models use `TypedDict`.
68
+ - The client retries rate limits, server errors, timeouts, and connection failures.
69
+ - `paginate()` yields items from cursor-based responses; `paginate_pages()` yields full response pages.
70
+ - HTTP errors map to exception classes such as `RateLimitError` and `NotFoundError`.
71
+ - Timeouts can use one value or separate connect and read values.
72
+ - The package supports Python 3.9+ and depends on `requests`.
78
73
 
79
- ## API Reference
74
+ ## API reference
80
75
 
81
76
  ### User
82
77
 
@@ -105,7 +100,7 @@ next_page = client.user.get_followers(
105
100
  |--------|-------------|
106
101
  | `client.tweet.get_details_and_conversation(tweet_id=...)` | Get tweet details and replies |
107
102
  | `client.tweet.get_details_by_ids(ids=...)` | Get multiple tweets (max 200) |
108
- | `client.tweet.get_retweets(tweet_id=...)` | Get who retweeted |
103
+ | `client.tweet.get_retweets(tweet_id=...)` | Get users who retweeted |
109
104
  | `client.tweet.get_quotes(tweet_id=...)` | Get quote tweets |
110
105
  | `client.tweet.translate(tweet_id=..., dst_lang=...)` | Translate a tweet |
111
106
 
@@ -173,8 +168,8 @@ next_page = client.user.get_followers(
173
168
  | `client.community.create_quote_with_media(...)` | Quote post with media |
174
169
  | `client.community.reply_post(...)` | Reply to community post |
175
170
  | `client.community.reply_post_with_media(...)` | Reply with media |
176
- | `client.community.join(auth_token=..., community_id=...)` | Join |
177
- | `client.community.leave(auth_token=..., community_id=...)` | Leave |
171
+ | `client.community.join(auth_token=..., community_id=...)` | Join a community |
172
+ | `client.community.leave(auth_token=..., community_id=...)` | Leave a community |
178
173
 
179
174
  ### Space
180
175
 
@@ -187,24 +182,24 @@ next_page = client.user.get_followers(
187
182
 
188
183
  | Method | Description |
189
184
  |--------|-------------|
190
- | `client.explore.search(query=..., type=...)` | Search tweets/users/photos/videos |
185
+ | `client.explore.search(query=..., type=...)` | Search tweets, users, photos, or videos |
191
186
 
192
187
  ### Auth
193
188
 
194
189
  | Method | Description |
195
190
  |--------|-------------|
196
- | `client.auth.login(username=..., password=..., proxy=..., country=...)` | Log in, get auth tokens |
191
+ | `client.auth.login(username=..., password=..., proxy=..., country=...)` | Log in and return auth tokens |
197
192
 
198
193
  `country` is the ISO 3166-1 alpha-2 code for the proxy's public egress IP (for example, `"US"`). It must match the IP used for the complete login attempt. Pass `two_factor_secret` when the account uses TOTP-based 2FA.
199
194
 
200
- ### X Chat (Encrypted DMs)
195
+ ### X Chat (encrypted DMs)
201
196
 
202
197
  | Method | Description |
203
198
  |--------|-------------|
204
199
  | `client.xchat.setup(auth_token=..., user_id=..., pin=...)` | Initialize encrypted DMs |
205
200
  | `client.xchat.get_conversations(auth_token=...)` | List conversations |
206
201
  | `client.xchat.send(auth_token=..., recipient_id=..., message=...)` | Send message |
207
- | `client.xchat.get_history(auth_token=..., conversation_id=...)` | Get history |
202
+ | `client.xchat.get_history(auth_token=..., conversation_id=...)` | Get conversation history |
208
203
  | `client.xchat.can_dm(auth_token=..., user_ids=...)` | Check DM availability |
209
204
 
210
205
  ### Unencrypted DMs
@@ -214,13 +209,13 @@ next_page = client.user.get_followers(
214
209
  | `client.dm.send_dm(auth_token=..., conversation_id=..., text=..., proxy=...)` | Send DM |
215
210
  | `client.dm.get_dm_permissions(auth_token=..., recipient_ids=...)` | Check permissions |
216
211
  | `client.dm.get_inbox_initial_state(auth_token=...)` | Get inbox state |
217
- | `client.dm.get_inbox_trusted(auth_token=..., cursor=...)` | Trusted inbox |
218
- | `client.dm.get_inbox_untrusted(auth_token=..., cursor=...)` | Message requests |
212
+ | `client.dm.get_inbox_trusted(auth_token=..., cursor=...)` | Get the trusted inbox |
213
+ | `client.dm.get_inbox_untrusted(auth_token=..., cursor=...)` | Get message requests |
219
214
  | `client.dm.get_conversation(auth_token=..., conversation_id=...)` | Get messages |
220
- | `client.dm.get_dm_user_updates(auth_token=..., cursor=...)` | DM user updates |
221
- | `client.dm.accept_conversation(auth_token=..., conversation_id=...)` | Accept request |
215
+ | `client.dm.get_dm_user_updates(auth_token=..., cursor=...)` | Get DM user updates |
216
+ | `client.dm.accept_conversation(auth_token=..., conversation_id=...)` | Accept a conversation request |
222
217
 
223
- ## Posting and Profile Media
218
+ ## Posting and profile media
224
219
 
225
220
  Tweet media accepts an existing TweetAPI media ID, a URL, or inline base64 data:
226
221
 
@@ -260,7 +255,7 @@ client.profile.remove_banner(auth_token="AUTH_TOKEN")
260
255
  client.profile.set_privacy(auth_token="AUTH_TOKEN", is_private=True)
261
256
  ```
262
257
 
263
- Canonical list mutations live under `client.list`; the legacy interaction list helpers remain available:
258
+ Use `client.list` for list mutations. The older helpers under `client.interaction` remain available:
264
259
 
265
260
  ```python
266
261
  created = client.list.create(
@@ -293,9 +288,9 @@ client.community.create_quote_with_media(
293
288
  )
294
289
  ```
295
290
 
296
- ## Auto-Pagination
291
+ ## Pagination
297
292
 
298
- Use the `paginate()` and `paginate_pages()` helpers to iterate through all pages automatically:
293
+ `paginate()` yields individual items. `paginate_pages()` yields each full response page:
299
294
 
300
295
  ```python
301
296
  from tweetapi import TweetAPI, paginate, paginate_pages
@@ -317,18 +312,16 @@ for page in paginate_pages(
317
312
  print(f"Next cursor: {page['pagination']['nextCursor']}")
318
313
  ```
319
314
 
320
- Works with any paginated endpoint — followers, tweets, search results, list members, community posts, etc.
315
+ Each helper accepts a callable that takes a cursor and returns a response with `data` and `pagination.nextCursor`. Use `max_pages` to limit the number of fetched pages.
321
316
 
322
- ## Automatic Retry with Backoff
317
+ ## Retries
323
318
 
324
- The SDK automatically retries on transient errors with exponential backoff:
319
+ The client retries these transient failures:
325
320
 
326
- - **429 (Rate Limit)** — waits the `retry_after` duration from the API, then retries
327
- - **5xx (Server Error)** — retries with exponential backoff + jitter
328
- - **Network errors** — retries on timeouts and connection failures
329
- - **4xx (Client Error)** — never retried (400, 401, 403, 404 fail immediately)
321
+ - For a 429 response, it waits for `RateLimitError.retry_after` seconds, up to `max_retry_delay`.
322
+ - For a 5xx response, timeout, or connection failure, it uses exponential backoff with up to 25% jitter.
330
323
 
331
- Default: 3 retries, 2x backoff, 1s initial delay, 30s max delay.
324
+ By default, the client makes up to 3 retries. Its base delay starts at 1 second, doubles after each attempt, and is capped at 30 seconds. Other 4xx responses are not retried.
332
325
 
333
326
  ```python
334
327
  # Customize retry behavior
@@ -344,18 +337,17 @@ client = TweetAPI(
344
337
  client = TweetAPI(api_key="YOUR_API_KEY", max_retries=0)
345
338
  ```
346
339
 
347
- ### Rate Limit Awareness
340
+ ### Rate-limit state
348
341
 
349
- After a 429 response, the SDK exposes the last known rate limit state:
342
+ After a 429 response, `client.rate_limit_info` records the retry delay and the time the response was received:
350
343
 
351
344
  ```python
352
345
  print(client.rate_limit_info)
353
- # {"retry_after": 30, "timestamp": 1712345678.0} — or None if no 429 encountered
354
346
  ```
355
347
 
356
- ## Error Handling
348
+ ## Error handling
357
349
 
358
- The SDK raises typed exceptions you can catch and handle. With automatic retries enabled (default), you'll only see these after all retry attempts are exhausted:
350
+ The client raises retryable errors after it exhausts the configured retries. It raises other errors from the first response:
359
351
 
360
352
  ```python
361
353
  from tweetapi import (
@@ -389,11 +381,12 @@ except TweetAPIError as e:
389
381
  print(f"Error [{e.code}]: {e.message}")
390
382
  ```
391
383
 
392
- Every error includes:
393
- - `code` — API error code (e.g., `"ACCOUNT_SUSPENDED"`, `"RATE_LIMIT"`)
394
- - `status_code` — HTTP status code
395
- - `message` — Human-readable error message
396
- - `details` — Additional context (field, reason, retry_after, etc.)
384
+ Every error includes these attributes:
385
+
386
+ - `code`: API error code, such as `"ACCOUNT_SUSPENDED"` or `"RATE_LIMIT"`
387
+ - `status_code`: HTTP status code
388
+ - `message`: human-readable error message
389
+ - `details`: response context such as a field, reason, or retry delay
397
390
 
398
391
  ## Configuration
399
392
 
@@ -401,7 +394,7 @@ Every error includes:
401
394
  client = TweetAPI(
402
395
  api_key="YOUR_API_KEY", # Required
403
396
  base_url="https://...", # Optional (default: https://api.tweetapi.com)
404
- timeout=30, # Optional — single value for both connect + read
397
+ timeout=30, # Optional; one value for connect and read
405
398
  connect_timeout=10.0, # Optional (default: 10s)
406
399
  read_timeout=30.0, # Optional (default: 30s)
407
400
  max_retries=3, # Optional (default: 3, set 0 to disable)
@@ -421,8 +414,8 @@ client = TweetAPI(api_key="YOUR_API_KEY", timeout=(5, 30)) # (connect, read)
421
414
 
422
415
  ## Links
423
416
 
424
- - [Full Documentation](https://tweetapi.com/docs?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
425
- - [Get API Key (Free)](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
417
+ - [Documentation](https://tweetapi.com/docs?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
418
+ - [Create an API key](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
426
419
  - [Dashboard](https://tweetapi.com/dashboard?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
427
420
  - [Node.js SDK](https://github.com/tweetapi/node)
428
421
 
@@ -430,6 +423,4 @@ client = TweetAPI(api_key="YOUR_API_KEY", timeout=(5, 30)) # (connect, read)
430
423
 
431
424
  MIT
432
425
 
433
- ---
434
-
435
- *TweetAPI is a third-party service and is not affiliated with X Corp.*
426
+ TweetAPI is a third-party service and is not affiliated with X Corp.
@@ -1,8 +1,6 @@
1
1
  # TweetAPI Python SDK
2
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.
3
+ `tweetapi` is the Python SDK for [TweetAPI](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk). It provides methods for users, tweets, posts, profiles, interactions, lists, communities, Spaces, search, authentication, and direct messages.
6
4
 
7
5
  ## Install
8
6
 
@@ -10,7 +8,7 @@ Access tweets, user profiles, followers, analytics, and full interaction capabil
10
8
  pip install tweetapi
11
9
  ```
12
10
 
13
- ## Quick Start
11
+ ## Quick start
14
12
 
15
13
  ```python
16
14
  from tweetapi import TweetAPI
@@ -19,7 +17,7 @@ client = TweetAPI(api_key="YOUR_API_KEY")
19
17
 
20
18
  # Get a user profile
21
19
  user = client.user.get_by_username(username="elonmusk")
22
- print(user["data"]["followerCount"]) # 180000000
20
+ print(user["data"]["followerCount"])
23
21
 
24
22
  # Search tweets
25
23
  results = client.explore.search(query="bitcoin", type="Latest")
@@ -32,21 +30,18 @@ next_page = client.user.get_followers(
32
30
  )
33
31
  ```
34
32
 
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)
33
+ [Create an API key](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk) with 100 included requests. No credit card is required.
36
34
 
37
- ## Features
35
+ ## SDK behavior
38
36
 
39
- - **70+ endpoints** covering users, tweets, posts, interactions, DMs, communities, spaces, and search
40
- - **Full type hints** with TypedDict response types for IDE autocomplete
41
- - **Automatic retry with backoff** on rate limits (429) and server errors (5xx)
42
- - **Auto-pagination helpers** — iterate all pages with a simple `for` loop
43
- - **Solid error handling** with typed exceptions (`RateLimitError`, `NotFoundError`, etc.)
44
- - **Rate limit awareness** — `retry_after` respected automatically, state exposed via `client.rate_limit_info`
45
- - **Split timeouts** — separate connect and read timeouts
46
- - **Single dependency** — `requests` only
47
- - **Python 3.9+** compatible
37
+ - Public methods have type annotations, and response models use `TypedDict`.
38
+ - The client retries rate limits, server errors, timeouts, and connection failures.
39
+ - `paginate()` yields items from cursor-based responses; `paginate_pages()` yields full response pages.
40
+ - HTTP errors map to exception classes such as `RateLimitError` and `NotFoundError`.
41
+ - Timeouts can use one value or separate connect and read values.
42
+ - The package supports Python 3.9+ and depends on `requests`.
48
43
 
49
- ## API Reference
44
+ ## API reference
50
45
 
51
46
  ### User
52
47
 
@@ -75,7 +70,7 @@ next_page = client.user.get_followers(
75
70
  |--------|-------------|
76
71
  | `client.tweet.get_details_and_conversation(tweet_id=...)` | Get tweet details and replies |
77
72
  | `client.tweet.get_details_by_ids(ids=...)` | Get multiple tweets (max 200) |
78
- | `client.tweet.get_retweets(tweet_id=...)` | Get who retweeted |
73
+ | `client.tweet.get_retweets(tweet_id=...)` | Get users who retweeted |
79
74
  | `client.tweet.get_quotes(tweet_id=...)` | Get quote tweets |
80
75
  | `client.tweet.translate(tweet_id=..., dst_lang=...)` | Translate a tweet |
81
76
 
@@ -143,8 +138,8 @@ next_page = client.user.get_followers(
143
138
  | `client.community.create_quote_with_media(...)` | Quote post with media |
144
139
  | `client.community.reply_post(...)` | Reply to community post |
145
140
  | `client.community.reply_post_with_media(...)` | Reply with media |
146
- | `client.community.join(auth_token=..., community_id=...)` | Join |
147
- | `client.community.leave(auth_token=..., community_id=...)` | Leave |
141
+ | `client.community.join(auth_token=..., community_id=...)` | Join a community |
142
+ | `client.community.leave(auth_token=..., community_id=...)` | Leave a community |
148
143
 
149
144
  ### Space
150
145
 
@@ -157,24 +152,24 @@ next_page = client.user.get_followers(
157
152
 
158
153
  | Method | Description |
159
154
  |--------|-------------|
160
- | `client.explore.search(query=..., type=...)` | Search tweets/users/photos/videos |
155
+ | `client.explore.search(query=..., type=...)` | Search tweets, users, photos, or videos |
161
156
 
162
157
  ### Auth
163
158
 
164
159
  | Method | Description |
165
160
  |--------|-------------|
166
- | `client.auth.login(username=..., password=..., proxy=..., country=...)` | Log in, get auth tokens |
161
+ | `client.auth.login(username=..., password=..., proxy=..., country=...)` | Log in and return auth tokens |
167
162
 
168
163
  `country` is the ISO 3166-1 alpha-2 code for the proxy's public egress IP (for example, `"US"`). It must match the IP used for the complete login attempt. Pass `two_factor_secret` when the account uses TOTP-based 2FA.
169
164
 
170
- ### X Chat (Encrypted DMs)
165
+ ### X Chat (encrypted DMs)
171
166
 
172
167
  | Method | Description |
173
168
  |--------|-------------|
174
169
  | `client.xchat.setup(auth_token=..., user_id=..., pin=...)` | Initialize encrypted DMs |
175
170
  | `client.xchat.get_conversations(auth_token=...)` | List conversations |
176
171
  | `client.xchat.send(auth_token=..., recipient_id=..., message=...)` | Send message |
177
- | `client.xchat.get_history(auth_token=..., conversation_id=...)` | Get history |
172
+ | `client.xchat.get_history(auth_token=..., conversation_id=...)` | Get conversation history |
178
173
  | `client.xchat.can_dm(auth_token=..., user_ids=...)` | Check DM availability |
179
174
 
180
175
  ### Unencrypted DMs
@@ -184,13 +179,13 @@ next_page = client.user.get_followers(
184
179
  | `client.dm.send_dm(auth_token=..., conversation_id=..., text=..., proxy=...)` | Send DM |
185
180
  | `client.dm.get_dm_permissions(auth_token=..., recipient_ids=...)` | Check permissions |
186
181
  | `client.dm.get_inbox_initial_state(auth_token=...)` | Get inbox state |
187
- | `client.dm.get_inbox_trusted(auth_token=..., cursor=...)` | Trusted inbox |
188
- | `client.dm.get_inbox_untrusted(auth_token=..., cursor=...)` | Message requests |
182
+ | `client.dm.get_inbox_trusted(auth_token=..., cursor=...)` | Get the trusted inbox |
183
+ | `client.dm.get_inbox_untrusted(auth_token=..., cursor=...)` | Get message requests |
189
184
  | `client.dm.get_conversation(auth_token=..., conversation_id=...)` | Get messages |
190
- | `client.dm.get_dm_user_updates(auth_token=..., cursor=...)` | DM user updates |
191
- | `client.dm.accept_conversation(auth_token=..., conversation_id=...)` | Accept request |
185
+ | `client.dm.get_dm_user_updates(auth_token=..., cursor=...)` | Get DM user updates |
186
+ | `client.dm.accept_conversation(auth_token=..., conversation_id=...)` | Accept a conversation request |
192
187
 
193
- ## Posting and Profile Media
188
+ ## Posting and profile media
194
189
 
195
190
  Tweet media accepts an existing TweetAPI media ID, a URL, or inline base64 data:
196
191
 
@@ -230,7 +225,7 @@ client.profile.remove_banner(auth_token="AUTH_TOKEN")
230
225
  client.profile.set_privacy(auth_token="AUTH_TOKEN", is_private=True)
231
226
  ```
232
227
 
233
- Canonical list mutations live under `client.list`; the legacy interaction list helpers remain available:
228
+ Use `client.list` for list mutations. The older helpers under `client.interaction` remain available:
234
229
 
235
230
  ```python
236
231
  created = client.list.create(
@@ -263,9 +258,9 @@ client.community.create_quote_with_media(
263
258
  )
264
259
  ```
265
260
 
266
- ## Auto-Pagination
261
+ ## Pagination
267
262
 
268
- Use the `paginate()` and `paginate_pages()` helpers to iterate through all pages automatically:
263
+ `paginate()` yields individual items. `paginate_pages()` yields each full response page:
269
264
 
270
265
  ```python
271
266
  from tweetapi import TweetAPI, paginate, paginate_pages
@@ -287,18 +282,16 @@ for page in paginate_pages(
287
282
  print(f"Next cursor: {page['pagination']['nextCursor']}")
288
283
  ```
289
284
 
290
- Works with any paginated endpoint — followers, tweets, search results, list members, community posts, etc.
285
+ Each helper accepts a callable that takes a cursor and returns a response with `data` and `pagination.nextCursor`. Use `max_pages` to limit the number of fetched pages.
291
286
 
292
- ## Automatic Retry with Backoff
287
+ ## Retries
293
288
 
294
- The SDK automatically retries on transient errors with exponential backoff:
289
+ The client retries these transient failures:
295
290
 
296
- - **429 (Rate Limit)** — waits the `retry_after` duration from the API, then retries
297
- - **5xx (Server Error)** — retries with exponential backoff + jitter
298
- - **Network errors** — retries on timeouts and connection failures
299
- - **4xx (Client Error)** — never retried (400, 401, 403, 404 fail immediately)
291
+ - For a 429 response, it waits for `RateLimitError.retry_after` seconds, up to `max_retry_delay`.
292
+ - For a 5xx response, timeout, or connection failure, it uses exponential backoff with up to 25% jitter.
300
293
 
301
- Default: 3 retries, 2x backoff, 1s initial delay, 30s max delay.
294
+ By default, the client makes up to 3 retries. Its base delay starts at 1 second, doubles after each attempt, and is capped at 30 seconds. Other 4xx responses are not retried.
302
295
 
303
296
  ```python
304
297
  # Customize retry behavior
@@ -314,18 +307,17 @@ client = TweetAPI(
314
307
  client = TweetAPI(api_key="YOUR_API_KEY", max_retries=0)
315
308
  ```
316
309
 
317
- ### Rate Limit Awareness
310
+ ### Rate-limit state
318
311
 
319
- After a 429 response, the SDK exposes the last known rate limit state:
312
+ After a 429 response, `client.rate_limit_info` records the retry delay and the time the response was received:
320
313
 
321
314
  ```python
322
315
  print(client.rate_limit_info)
323
- # {"retry_after": 30, "timestamp": 1712345678.0} — or None if no 429 encountered
324
316
  ```
325
317
 
326
- ## Error Handling
318
+ ## Error handling
327
319
 
328
- The SDK raises typed exceptions you can catch and handle. With automatic retries enabled (default), you'll only see these after all retry attempts are exhausted:
320
+ The client raises retryable errors after it exhausts the configured retries. It raises other errors from the first response:
329
321
 
330
322
  ```python
331
323
  from tweetapi import (
@@ -359,11 +351,12 @@ except TweetAPIError as e:
359
351
  print(f"Error [{e.code}]: {e.message}")
360
352
  ```
361
353
 
362
- Every error includes:
363
- - `code` — API error code (e.g., `"ACCOUNT_SUSPENDED"`, `"RATE_LIMIT"`)
364
- - `status_code` — HTTP status code
365
- - `message` — Human-readable error message
366
- - `details` — Additional context (field, reason, retry_after, etc.)
354
+ Every error includes these attributes:
355
+
356
+ - `code`: API error code, such as `"ACCOUNT_SUSPENDED"` or `"RATE_LIMIT"`
357
+ - `status_code`: HTTP status code
358
+ - `message`: human-readable error message
359
+ - `details`: response context such as a field, reason, or retry delay
367
360
 
368
361
  ## Configuration
369
362
 
@@ -371,7 +364,7 @@ Every error includes:
371
364
  client = TweetAPI(
372
365
  api_key="YOUR_API_KEY", # Required
373
366
  base_url="https://...", # Optional (default: https://api.tweetapi.com)
374
- timeout=30, # Optional — single value for both connect + read
367
+ timeout=30, # Optional; one value for connect and read
375
368
  connect_timeout=10.0, # Optional (default: 10s)
376
369
  read_timeout=30.0, # Optional (default: 30s)
377
370
  max_retries=3, # Optional (default: 3, set 0 to disable)
@@ -391,8 +384,8 @@ client = TweetAPI(api_key="YOUR_API_KEY", timeout=(5, 30)) # (connect, read)
391
384
 
392
385
  ## Links
393
386
 
394
- - [Full Documentation](https://tweetapi.com/docs?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
395
- - [Get API Key (Free)](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
387
+ - [Documentation](https://tweetapi.com/docs?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
388
+ - [Create an API key](https://tweetapi.com?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
396
389
  - [Dashboard](https://tweetapi.com/dashboard?utm_source=github&utm_medium=readme&utm_campaign=python-sdk)
397
390
  - [Node.js SDK](https://github.com/tweetapi/node)
398
391
 
@@ -400,6 +393,4 @@ client = TweetAPI(api_key="YOUR_API_KEY", timeout=(5, 30)) # (connect, read)
400
393
 
401
394
  MIT
402
395
 
403
- ---
404
-
405
- *TweetAPI is a third-party service and is not affiliated with X Corp.*
396
+ TweetAPI is a third-party service and is not affiliated with X Corp.
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tweetapi"
7
- version = "2.2.0"
8
- description = "Official Python SDK for TweetAPI — Twitter/X Data API for developers and researchers"
7
+ version = "2.2.1"
8
+ description = "Python SDK for TweetAPI's Twitter/X data and account API"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  requires-python = ">=3.9"
@@ -37,4 +37,4 @@ __all__ = [
37
37
  "paginate_pages",
38
38
  ]
39
39
 
40
- __version__ = "2.2.0"
40
+ __version__ = "2.2.1"
File without changes
File without changes
File without changes
File without changes
File without changes