Pagination
The Zscaler SDK handles pagination transparently. The resource layer exposes chainable methods (.all(), .pages(), .limit(), .page_size(), .filter(), and .search()) that work irrespective of whether the underlying endpoint paginates server-side or returns all items in one response.
Each paginated API defines its own per-request default (typically 50–500 items per request, chosen by the product team). The SDK uses whatever the API returns by default; you only need to call .page_size(n) if you want to override it for a specific use case (e.g., smaller pages to reduce memory usage or larger pages to reduce the number of requests).
Iterating Items with .all()
Use .all() for the common case: read every item and let the SDK handle paging for you.
import zssdk
session = zssdk.Session(profile_name="beta")
# Paginated collection (firewall_filtering_rules paginates server-side in ZIA)
for rule in session.zia.firewall_filtering_rules.all():
print(rule.id, rule.name)
# Simple collection (admin_roles returns all rows in one response)
for role in session.zia.admin_roles.all():
print(role.id, role.name)
# Materialize the full list when you need the count or indexing
all_rules = list(session.zia.firewall_filtering_rules.all())
print(f"Total rules: {len(all_rules)}")
Iterating Page by Page with .pages()
Use .pages() when you want to work with batches explicitly — for example, to log progress, stream to a downstream sink, or cap memory usage.
# Works on simple collections too — yields a single page
for page in session.zia.url_categories().pages():
for cat in page:
print(cat.name)
# On a paginated collection, yields each server page
for page in session.zia.firewall_filtering_rules.pages():
print(f"Got page with {len(page)} rules")
for rule in page:
process(rule)
Tuning Page Size and Limiting Total Results
In the following example,
.page_size(n)sets the per-request batch size (passed as the configuredlimit_key, e.g.pageSize)..limit(n)caps the total number of yielded items across pages.
# Fetch 50 per API request, cap total yielded items at 100
for rule in session.zia.firewall_filtering_rules.page_size(50).limit(100):
print(rule.name)
On simple collections, both methods are effectively no-operations with respect to server-side pagination: page_size is ignored; .limit() just slices the single response.
Server-Side Filtering vs. Client-Side Search
These are two distinct operations.
# Server-side: keywords are passed to the API as query parameters
for user in session.zia.admin_users.filter(search="SDWAN"):
print(user.name)
# Client-side: JMESPath expression applied to each page after it arrives
for user in session.zia.admin_users.search("[?contains(name, 'SilverPeak')]"):
print(user.name)
# Chain: reduce on the server, then refine on the client
for user in session.zia.admin_users.filter(search="SDWAN").search("[?contains(name, 'VeloCloud')]"):
print(user.name)
Low-Level Paginator (Core Layer)
Use the core client's paginator if you need direct control — for example, custom pagination configuration or an operation that is not modeled in the resource layer.
client = session.client("zia")
paginator = client.get_paginator("list_firewall_filtering_rules")
for page in paginator.paginate(PaginationConfig={"PageSize": 100}):
for rule in page:
print(rule["id"], rule["name"])
This is equivalent to the resource layer .pages() iterator, but it returns raw dictionary objects (dict) instead of resource objects.
Memory Tips for Large Datasets
- Prefer
.all()or.pages()iteration overlist(...)to avoid loading everything into memory at once. - Use
.page_size(n)to trade off request count vs. per-response memory usage on paginated endpoints. - Use
.limit(n)to impose a hard limit on very large result sets while exploring. - Avoid tight inner loops that re-iterate the same collection. Cache what you need instead.