Paginator¶
Offset-based REST API pagination helpers with response-size enforcement.
- scamander.api.paginator.fetch_all_pages(session: OAuth2Session, url: str, extra_params: dict | None = None, page_size: int = 500, size_param: str = 'limit', cursor_param: str = 'offset', cursor_mode: Literal['offset', 'page_number'] = 'offset', cursor_start: int = 0, timeout_secs: int = 120, max_size_mb: float = 5.0) list[dict]¶
Paginate through a REST endpoint until all records are retrieved.
Uses offset-family pagination: a page-size query parameter plus a cursor query parameter that advances each request. The query parameter names and the cursor’s advance semantics are both configurable to match whatever convention the target API uses. Stops when a page returns fewer records than
page_size.Mount a
ThrottledHTTPAdapteron the session before calling to honour vendor-specified rate and bandwidth limits automatically.- Parameters:
session – Authenticated
OAuth2Session.url – Full URL of the endpoint to paginate.
extra_params – Additional query parameters merged into every request.
page_size – Records per page. Must stay below the API’s per-call record ceiling. Defaults to
500.size_param – Query parameter name carrying the page size. Defaults to
"limit".cursor_param – Query parameter name carrying the position cursor. Defaults to
"offset".cursor_mode – How the cursor advances each request.
"offset"(default) advances bypage_sizerecords per page, matchingoffset-style APIs."page_number"advances by1per page, matching APIs that take an ordinal page number instead of a record offset.cursor_start – Initial cursor value sent on the first request. Defaults to
0. Use1for a 1-indexedpage_numberAPI.timeout_secs – Request timeout per page in seconds. Defaults to
120.max_size_mb – Maximum allowed response body per page in MB. Defaults to
5.
- Returns:
Flat list of all records across all pages.
- Raises:
requests.HTTPError – On a non-2xx response.
RuntimeError – When a response body exceeds
max_size_mb.ValueError – When a response JSON has no recognisable records envelope, or when
cursor_modeis not"offset"or"page_number".
Example:
from scamander.api import ( BandwidthGuard, OAuth2Session, RateLimiter, ThrottledHTTPAdapter, fetch_all_pages, ) session = OAuth2Session(token_url=..., client_id=..., client_secret=...) adapter = ThrottledHTTPAdapter( rate_limiter=RateLimiter(max_calls=300, period_secs=60), bw_guard=BandwidthGuard(limit_mb=350, window_secs=300), ) session.mount("https://", adapter) # Default limit/offset convention records = fetch_all_pages(session, "https://api.example.com/v1/resources") # Renamed keys, same offset semantics (offset = page * page_size) records = fetch_all_pages( session, "https://api.other.com/v1/resources", size_param="pageSize", cursor_param="pageStart", ) # A 1-indexed page_size/page_number convention (cursor advances by 1, # not by page_size, per request) records = fetch_all_pages( session, "https://api.other.com/v1/resources", size_param="page_size", cursor_param="page_number", cursor_mode="page_number", cursor_start=1, ) # Static filters sent on every page alongside the pagination params records = fetch_all_pages( session, "https://api.example.com/v1/resources", extra_params={"status": "active"}, ) # Smaller pages with a shorter per-request timeout and a lower # response-size ceiling, e.g. for a slow or rate-sensitive vendor API records = fetch_all_pages( session, "https://api.example.com/v1/resources", page_size=100, timeout_secs=30, max_size_mb=2.0, )
- scamander.api.paginator.fetch_page(session: OAuth2Session, url: str, params: dict, timeout_secs: int = 120, max_size_mb: float = 5.0) list[dict]¶
Fetch a single page from a REST API and enforce the response-size limit.
- Parameters:
session – Authenticated
OAuth2Session.url – Full request URL.
params – Query parameters (pagination offsets, filters, etc.).
timeout_secs – Request timeout in seconds. Defaults to
120.max_size_mb – Maximum allowed response body in MB. Defaults to
5.
- Returns:
Normalised list of record dicts from the response body.
- Raises:
requests.HTTPError – On a non-2xx response.
RuntimeError – When the response body exceeds
max_size_mb.ValueError – When the response JSON has no recognisable records envelope.
Example:
records = fetch_page(session, url, params={"offset": 0, "limit": 500})