The XDK provides a powerful Cursor class for handling paginated API responses. The Cursor enables elegant iteration over large result sets using .pages() and .items() methods with automatic pagination token management.
Use .pages() to iterate over complete API responses:
from xdk import cursorclient = Client(bearer_token="your_token")# Create cursor for post searchsearch_cursor = cursor( client.posts.search_recent, "python", max_results=50)# Iterate over pages (up to 5 pages)for page in search_cursor.pages(limit=5): print(f"Got {len(page.data)} posts") for post in page.data: print(f"- {post.text}") # Access metadata if hasattr(page, 'meta') and page.meta: print(f"Next token: {page.meta.next_token}")
Use .items() to iterate over individual items across all pages:
from xdk import cursor# Get user's followersfollowers_cursor = cursor( client.users.get_users_followers, "user_id", max_results=100 # 100 per page)# Iterate over individual users (up to 250 total)for user in followers_cursor.items(limit=250): print(f"{user.name} (@{user.username})")
from xdk.paginator import PaginationErrortry: # This will fail if the method doesn't support pagination invalid_cursor = Cursor(client.users.find_user_by_id, "user_id")except PaginationError as e: print(f"Error: {e}") # Error: Method 'find_user_by_id' does not support pagination. # Paginatable methods must accept 'pagination_token', # 'next_token', and/or 'max_results' parameters.
# Search for recent posts about Pythonsearch = cursor( client.posts.search_recent, "python programming", max_results=100)# Get first 500 matching postsfor post in search.items(limit=500): print(f"{post.author_id}: {post.text}")
# Get all followers in batchesfollowers = cursor( client.users.get_users_followers, "783214", # Twitter's user ID max_results=1000)total = 0for page in followers.pages(): batch_size = len(page.data) total += batch_size print(f"Processed {batch_size} followers (total: {total})")
# Get list members with user fieldslist_members = cursor( client.lists.get_list_members, "list_id", max_results=100, user_fields=["created_at", "description", "public_metrics"])for user in list_members.items(limit=1000): print(f"{user.username}: {user.public_metrics.followers_count} followers")
The Cursor preserves the return type of the wrapped method:
from xdk import cursor# Type is inferred as Cursor[GetUsersResponse]users_cursor = cursor( client.users.get_blocking, "user_id", max_results=100)# page is typed as GetUsersResponsefor page in users_cursor.pages(5): print(len(page.data)) # Type checker knows page has .data# user is typed based on response.data itemsfor user in users_cursor.items(100): print(user.username) # Type checker knows user has .username
from xdk.paginator import PaginationErrortry: search = cursor( client.posts.search_recent, "query", max_results=100 ) for post in search.items(limit=1000): print(post.text)except PaginationError as e: print(f"Pagination error: {e}")except Exception as e: print(f"API error: {e}")