Library for accessing the X API (Twitter)
Tweepy provides utility classes for pagination, caching, error handling, and other common functionality to simplify API usage and improve application performance.
The Paginator class provides automatic pagination for Twitter API v2 endpoints that return paginated results.
class Paginator:
def __init__(self, method, *args, **kwargs):
"""
Initialize paginator for a Client method.
Parameters:
- method (callable): Client method that returns paginated results
- *args: Positional arguments for the method
- **kwargs: Keyword arguments for the method
"""
def flatten(self, limit=None):
"""
Flatten paginated results into a single iterator.
Parameters:
- limit (int, optional): Maximum number of items to return
Yields:
Individual items from paginated responses
"""
def get_next(self):
"""
Get the next page of results.
Returns:
Response object with next page data, or None if no more pages
"""
def get_previous(self):
"""
Get the previous page of results.
Returns:
Response object with previous page data, or None if no previous pages
"""import tweepy
client = tweepy.Client(bearer_token="your_bearer_token")
# Paginate through search results
paginator = tweepy.Paginator(
client.search_recent_tweets,
query="python programming",
max_results=100,
tweet_fields=["created_at", "public_metrics"]
)
# Get all results (flattened)
for tweet in paginator.flatten(limit=500):
print(f"{tweet.created_at}: {tweet.text}")
# Manual pagination
for page in paginator:
print(f"Page contains {len(page.data)} tweets")
for tweet in page.data:
print(f" - {tweet.text[:50]}...")
# Stop after 3 pages
if paginator.current_page >= 3:
break
# Paginate through user followers
follower_paginator = tweepy.Paginator(
client.get_users_followers,
id="783214", # Twitter's user ID
max_results=1000,
user_fields=["public_metrics", "verified"]
)
# Count followers with high follower counts
high_influence_followers = 0
for follower in follower_paginator.flatten(limit=10000):
if follower.public_metrics['followers_count'] > 1000:
high_influence_followers += 1
print(f"High-influence followers: {high_influence_followers}")The Cursor class provides pagination for Twitter API v1.1 endpoints with different pagination patterns.
class Cursor:
def __init__(self, method, *args, **kwargs):
"""
Initialize cursor for an API method.
Parameters:
- method (callable): API method that returns paginated results
- *args: Positional arguments for the method
- **kwargs: Keyword arguments for the method
"""
def items(self, limit=None):
"""
Iterate over individual items from paginated results.
Parameters:
- limit (int, optional): Maximum number of items to return
Yields:
Individual items (tweets, users, etc.)
"""
def pages(self, limit=None):
"""
Iterate over pages of results.
Parameters:
- limit (int, optional): Maximum number of pages to return
Yields:
Lists of items (one page at a time)
"""import tweepy
# Initialize API with authentication
auth = tweepy.OAuth1UserHandler(
consumer_key="your_consumer_key",
consumer_secret="your_consumer_secret",
access_token="your_access_token",
access_token_secret="your_access_token_secret"
)
api = tweepy.API(auth, wait_on_rate_limit=True)
# Paginate through user's timeline
cursor = tweepy.Cursor(api.user_timeline, screen_name="python", count=200)
# Get individual tweets
for tweet in cursor.items(limit=1000):
print(f"{tweet.created_at}: {tweet.text}")
# Process pages of results
for page in cursor.pages(limit=5):
print(f"Processing page with {len(page)} tweets")
for tweet in page:
# Process each tweet in the page
pass
# Paginate through followers
follower_cursor = tweepy.Cursor(api.get_followers, screen_name="python", count=200)
# Count followers by location
location_counts = {}
for follower in follower_cursor.items(limit=5000):
location = follower.location or "Unknown"
location_counts[location] = location_counts.get(location, 0) + 1
print("Top locations:")
for location, count in sorted(location_counts.items(), key=lambda x: x[1], reverse=True)[:10]:
print(f" {location}: {count}")Tweepy provides caching implementations to reduce API calls and improve performance.
class Cache:
"""Base cache interface."""
def get(self, key):
"""
Get cached value by key.
Parameters:
- key (str): Cache key
Returns:
Cached value or None if not found
"""
def store(self, key, value):
"""
Store value in cache.
Parameters:
- key (str): Cache key
- value: Value to cache
"""
def cleanup(self):
"""Clean up expired cache entries."""
class MemoryCache(Cache):
def __init__(self, timeout=60):
"""
Initialize in-memory cache.
Parameters:
- timeout (int): Cache entry timeout in seconds
"""
class FileCache(Cache):
def __init__(self, cache_dir, timeout=60):
"""
Initialize file-based cache.
Parameters:
- cache_dir (str): Directory to store cache files
- timeout (int): Cache entry timeout in seconds
"""import tweepy
# Use memory cache with API
cache = tweepy.MemoryCache(timeout=300) # 5 minute timeout
api = tweepy.API(auth, cache=cache)
# First call hits the API
user1 = api.get_user(screen_name="python")
# Second call uses cached result (if within timeout)
user2 = api.get_user(screen_name="python") # Cached!
# Use file cache for persistent caching
file_cache = tweepy.FileCache(cache_dir="/tmp/tweepy_cache", timeout=3600)
api_with_file_cache = tweepy.API(auth, cache=file_cache)
# Cached results persist between application runs
user = api_with_file_cache.get_user(screen_name="python")Tweepy uses structured response objects to organize API response data.
from collections import namedtuple
Response = namedtuple("Response", ("data", "includes", "errors", "meta"))
StreamResponse = namedtuple("StreamResponse", ("data",))# API v2 responses use Response namedtuple
response = client.search_recent_tweets(query="python", max_results=10)
# Access primary data
tweets = response.data
print(f"Found {len(tweets)} tweets")
# Access included data (related objects)
if response.includes:
users = response.includes.get('users', [])
media = response.includes.get('media', [])
# Access response metadata
if response.meta:
result_count = response.meta.get('result_count')
next_token = response.meta.get('next_token')
print(f"Total results: {result_count}")
# Handle errors
if response.errors:
for error in response.errors:
print(f"API Error: {error}")Tweepy provides structured exception classes for different types of API errors.
class TweepyException(Exception):
"""Base exception class for all Tweepy errors."""
class HTTPException(TweepyException):
"""HTTP-related exceptions with response information."""
def __init__(self, response):
self.response = response
self.api_errors = [] # API error details
self.api_codes = [] # API error codes
class BadRequest(HTTPException):
"""400 Bad Request - Invalid request parameters."""
class Unauthorized(HTTPException):
"""401 Unauthorized - Authentication failure."""
class Forbidden(HTTPException):
"""403 Forbidden - Access denied."""
class NotFound(HTTPException):
"""404 Not Found - Resource not found."""
class TooManyRequests(HTTPException):
"""429 Too Many Requests - Rate limit exceeded."""
class TwitterServerError(HTTPException):
"""500+ Server Error - Twitter server issues."""import tweepy
try:
# API call that might fail
tweet = client.create_tweet(text="Hello World!")
except tweepy.BadRequest as e:
print(f"Bad request: {e}")
if e.api_errors:
for error in e.api_errors:
print(f" - {error['title']}: {error['detail']}")
except tweepy.Unauthorized as e:
print("Authentication failed - check your credentials")
except tweepy.Forbidden as e:
print("Access denied - insufficient permissions")
except tweepy.TooManyRequests as e:
print("Rate limit exceeded - wait before retrying")
except tweepy.NotFound as e:
print("Resource not found")
except tweepy.TwitterServerError as e:
print(f"Twitter server error: {e.response.status_code}")
except tweepy.HTTPException as e:
print(f"HTTP error {e.response.status_code}: {e}")
except tweepy.TweepyException as e:
print(f"Tweepy error: {e}")Configure automatic rate limit handling in clients.
# API v2 Client with rate limit handling
client = tweepy.Client(
bearer_token="your_bearer_token",
wait_on_rate_limit=True # Automatically wait when rate limited
)
# API v1.1 with rate limit handling
api = tweepy.API(auth, wait_on_rate_limit=True)
# Manual rate limit checking (v1.1 only)
def check_rate_limit():
rate_limit_status = api.get_rate_limit_status()
# Check specific endpoint limits
search_limit = rate_limit_status['resources']['search']['/search/tweets']
remaining = search_limit['remaining']
reset_time = search_limit['reset']
print(f"Search API calls remaining: {remaining}")
print(f"Rate limit resets at: {reset_time}")
check_rate_limit()Configure global Tweepy settings and behavior.
# Configure global settings
tweepy.client.Client.DEFAULT_TIMEOUT = 30 # Default request timeout
tweepy.api.API.DEFAULT_RETRY_DELAY = 5 # Default retry delay
# Custom user agent
custom_client = tweepy.Client(
bearer_token="your_bearer_token",
user_agent="MyApp/1.0"
)
# Configure proxy settings
proxied_client = tweepy.Client(
bearer_token="your_bearer_token",
proxy="http://proxy.example.com:8080"
)Install with Tessl CLI
npx tessl i tessl/pypi-tweepy