Skip to main content

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.

You usually don't need to set page_size

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 configured limit_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 over list(...) 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.