Skip to content

Pagination

The RTLS server uses three pagination conventions across endpoints. The SDK unifies them behind two surfaces: an iterator (iter_*) and a page-by-page view (.pages()).

Iterator

For most callers, this is what you want:

for event in client.events.iter_pws(trackable_uid="t-1", start=start, end=end):
    process(event)

The SDK fetches pages on demand. Memory stays bounded.

Page-by-page

If you need page metadata (page number, total count when the server reports it), use .pages():

paginator = client.events._build_pws_paginator(trackable_uid="t-1", start=start, end=end)
for page in paginator.pages():
    print(f"page {page.page_number}: {len(page.items)} events")
    if page.total_count is not None:
        print(f"total: {page.total_count}")

The internal paginator builder is a low-level surface; iterator methods are the public way to walk pages.

When to materialize

If the result set fits in memory and you want one return value, use the reports.* aggregate methods:

report = client.reports.pws(trackable_uid="t-1", start=start, end=end)
print(len(report.events))

This materializes every page into a single PwsReport. The tradeoff is memory — for a year-long window with millions of events, prefer the iterator.

Server-side details (for the curious)

Three styles the SDK abstracts over:

  • Header cursor — server emits content-next-positions-page; SDK feeds it back as page= on the next request.
  • Body URL — server emits nextPage (a full URL); SDK fetches it verbatim.
  • Page + limit — server has no metadata; SDK drives via page=/limit= until a short page comes back.

You don't have to know which style any given endpoint uses — the iterator surface is identical.