Pagination¶
For endpoints returning a paginated response, the list of items are wrapped in a PaginatedList class which makes working with pagination more Pythonic while doing the necessary API calls transparently.
Controlling Results¶
The limit Parameter¶
The limit parameter controls the maximum total number of items to fetch across all pages:
# Fetch at most 50 players
players = client.leaderboards.get(leaderboard_id, limit=50)
for player in players: # Safe: will only iterate over 50 players max
print(player.name)
Without a limit, iteration will fetch all available items (potentially thousands):
# ⚠️ Warning: No limit = fetches ALL pages!
players = client.leaderboards.get(leaderboard_id)
for player in players: # Could make hundreds of API requests!
print(player.name)
Recommendation: Always set a limit unless you genuinely need all results.
The page_size Parameter¶
The page_size parameter controls how many items are fetched per API request (default: 100):
# Fetch 500 players using pages of 250 items (2 API requests)
players = client.leaderboards.get(leaderboard_id, limit=500, page_size=250)
When to adjust page_size:
Large result sets (500+ items): Increase to 250-1000 to reduce API calls
Need first result fast: Decrease to 10-50 to get initial results quickly
Iterating over Elements¶
The class is an iterator, meaning you can go through instances in the list with a for loop, or by calling next() to get the following item:
players = client.leaderboards.get(leaderboard_id, limit=100)
# Iterable style
for player in players:
print(player.name)
# Iterator
player_1 = next(players)
player_2 = next(players)
player_3 = next(players)
This will take care of fetching extra pages if needed. Once all the elements have been fetched (or the limit is reached), no further network calls will happen. This will work if you iterate over the same paginated response again:
# No API calls: players is reused from above
for player in players:
print(player.name)
However, API calls would be repeated if you get a fresh paginated response:
# New API calls: get() returns a fresh paginated list
for player in client.leaderboards.get(leaderboard_id, limit=100):
print(player.name)
Be mindful of that when writing your code otherwise you’ll consume your API quota quickly!
Total Number¶
To get the total number of items fetched (respecting the limit), use the built-in len() on the materialized list:
players = client.leaderboards.get(leaderboard_id, limit=50)
player_list = list(players)
print(len(player_list)) # 50 (or fewer if less available)
Note: The Clash Royale API does not provide a total count in advance, so you must fetch items to know how many there are.
Indexing¶
You can access elements by index:
players = client.leaderboards.get(leaderboard_id, limit=100)
second_player = players[1]
tenth_player = players[9]
Beware that accessing a large index may produce extra network calls to the Clash Royale API as pages preceding the given index will be fetched. For example, assuming the page size is 100, this will perform 2 API calls:
players = client.leaderboards.get(leaderboard_id)
players[150] # Fetches first 2 pages
If the index exceeds the limit or available items, an IndexError will be raised, as if it were a list. Unlike list, this feature doesn’t support negative values at the time.
Slicing¶
Slicing is supported and provides an easy way to get a specific range of results:
players = client.leaderboards.get(leaderboard_id)
# With start & end
players[2:5] # Players at positions 2, 3, 4
# Without start (get first N)
players[:10] # Top 10 players
# Without end (get from position onwards)
players[10:] # All players from position 10 onwards
# With start, end & step
players[0:20:2] # Every other player in top 20
Tip: Slicing without an end (e.g., players[10:]) will fetch all remaining items, which could produce many API calls. Consider setting a limit first:
# Safe: limit total results first, then slice
players = client.leaderboards.get(leaderboard_id, limit=100)
top_10 = players[:10]
Best Practices¶
✅ DO¶
# Set explicit limits
players = client.leaderboards.get(lb_id, limit=50)
# Use slicing for subsets
top_10 = players[:10]
# Use slicing for exact counts
top_50 = client.clans.search(name="Legend", limit=50)[:50]
# Break early in loops
for player in players:
if player.score > 5000:
break
❌ DON’T¶
# Don't fetch everything without a limit
players = client.leaderboards.get(lb_id)
all_players = list(players) # Danger: could be thousands!
# Don't use tiny page sizes for large fetches
players = client.leaderboards.get(lb_id, limit=1000, page_size=10) # 100 API requests!
# Don't ignore pagination when you only need a few items
for i, player in enumerate(client.leaderboards.get(lb_id)):
if i >= 10:
break
# Better: players = client.leaderboards.get(lb_id, limit=10)
Performance Considerations¶
The number of API requests is calculated as: ceil(limit / page_size)
# Examples:
# limit=50, page_size=100 → 1 request
# limit=150, page_size=100 → 2 requests
# limit=500, page_size=250 → 2 requests
# limit=1000, page_size=100 → 10 requests
Optimize by:
Setting appropriate
limitvalues (don’t fetch more than you need)Increasing
page_sizefor large bulk operationsUsing slicing to get exact counts
Reusing paginated lists instead of re-fetching
Complete Example¶
import clash_royale
client = clash_royale.Client(api_key="your_api_key")
# Get top 50 players efficiently
players = client.leaderboards.get(
leaderboard_id=170000008,
limit=50,
page_size=50 # Single API request
)
# Work with top 10
top_10 = players[:10]
for i, player in enumerate(top_10, 1):
print(f"{i}. {player.name} - {player.score} points")
# Or use slicing
next_10 = players[10:20]
print(f"Players 11-20: {[p.name for p in next_10]}")
# Search clans with limit
clans = client.clans.search(name="Legend", min_members=40, limit=25)
for clan in clans:
print(f"{clan.name} - {clan.members} members")