Pagination helpers for HawkAPI — cursor + offset, Page[T] response model, SQLAlchemy integration
Project description
hawkapi-pagination
Pagination helpers for HawkAPI. Offset and cursor strategies. Page[T] / CursorPage[T] response envelopes. SQLAlchemy integration. In-memory iterable pagination.
Install
pip install hawkapi-pagination
pip install 'hawkapi-pagination[sqlalchemy]' # adds SQLAlchemy + hawkapi-sqlalchemy helpers
Offset pagination
from hawkapi import Depends, HawkAPI
from hawkapi_sqlalchemy import get_session
from hawkapi_pagination import Page, OffsetParams, pagination_params, paginate_query
from sqlalchemy import select
@app.get("/items")
async def list_items(
params: OffsetParams = Depends(pagination_params),
session = Depends(get_session),
) -> Page[Item]:
return await paginate_query(session, select(Item), params)
The route accepts ?page=N&size=M. Defaults: page=1, size=50, max_size=200. Out-of-range values are clamped (size > max_size → max_size) or rejected (page < 1 raises 400).
Page[T] shape:
{ "items": [...], "total": 137, "page": 1, "size": 50, "pages": 3 }
Skipping the COUNT
For large tables where SELECT COUNT(*) is expensive:
page = await paginate_query(session, stmt, params, include_total=False)
# page.total == -1, page.pages == -1
Clients can detect "more pages" by comparing len(items) to size.
Cursor pagination
Cursor pagination is the right choice for large tables that change under you (offset pages skip/duplicate rows when items are inserted/deleted between requests). The cursor is an HMAC-signed opaque token bound to:
- the endpoint path (replay across routes rejected),
- a TTL (default 1 hour),
- a direction (
asc/desc).
from hawkapi_pagination import CursorPage, CursorParams, cursor_params, paginate_cursor
@app.get("/items")
async def list_items(
params: CursorParams = Depends(cursor_params),
session = Depends(get_session),
) -> CursorPage[Item]:
return await paginate_cursor(
session,
select(Item),
order_by=Item.id, # MUST be unique + sortable (PK is the usual choice)
params=params,
cursor_secret="stable secret, ≥32 chars",
endpoint="/items",
direction="asc",
)
CursorPage[T] shape:
{ "items": [...], "next_cursor": "eyJrI...", "prev_cursor": "" }
When next_cursor is "", there are no more pages. Send the cursor back as ?cursor=... for the next call.
In-memory iterables
from hawkapi_pagination import paginate_iterable
page = await paginate_iterable(some_list, params)
# Works with sync iterables AND async generators.
Security notes
- Cursor signing — HMAC-SHA256 over the JSON payload +
hmac.compare_digestfor verification. - Endpoint binding — a cursor minted for
/api/itemscannot be used at/api/users. Always pass anendpointstring that is stable across requests for the same route. - TTL — default 1 hour. Override per route via
ttl=topaginate_cursor. max_sizecap — every params class enforces it; clients cannot ask for an unbounded page. Default 200.- Negative-int guard —
page < 1andsize < 1raiseValueError(which HawkAPI surfaces as 400).
Development
git clone https://github.com/Hawk-API/hawkapi-pagination.git
cd hawkapi-pagination
uv sync --extra dev
uv run pytest -q
uv run ruff check . && uv run ruff format --check .
uv run pyright src/
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hawkapi_pagination-0.1.0.tar.gz.
File metadata
- Download URL: hawkapi_pagination-0.1.0.tar.gz
- Upload date:
- Size: 34.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1743f89384271f39f045261a502014eddc85b65c365e3d2d90495e78b6095a1
|
|
| MD5 |
367040bd9428f351f482f5f4ae526d93
|
|
| BLAKE2b-256 |
080a69a51fe058aaa3b71f184714e8eca1ad69debfce8b4506abff9f9668b3c7
|
Provenance
The following attestation bundles were made for hawkapi_pagination-0.1.0.tar.gz:
Publisher:
release.yml on Hawk-API/hawkapi-pagination
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hawkapi_pagination-0.1.0.tar.gz -
Subject digest:
a1743f89384271f39f045261a502014eddc85b65c365e3d2d90495e78b6095a1 - Sigstore transparency entry: 1560252140
- Sigstore integration time:
-
Permalink:
Hawk-API/hawkapi-pagination@da60ecac27dca697ed6922c910c023eb98617714 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Hawk-API
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@da60ecac27dca697ed6922c910c023eb98617714 -
Trigger Event:
release
-
Statement type:
File details
Details for the file hawkapi_pagination-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hawkapi_pagination-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31bf347ec0573b84e36d051edc953d9fd952658a230a9f895c0674d46c6b7563
|
|
| MD5 |
5e8d32e4b212c299d3f034adf0bb9ac2
|
|
| BLAKE2b-256 |
3aa6dc7794a57f019966d331b956ef0842e0962c6ec3ddc0875834398948153f
|
Provenance
The following attestation bundles were made for hawkapi_pagination-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Hawk-API/hawkapi-pagination
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hawkapi_pagination-0.1.0-py3-none-any.whl -
Subject digest:
31bf347ec0573b84e36d051edc953d9fd952658a230a9f895c0674d46c6b7563 - Sigstore transparency entry: 1560252242
- Sigstore integration time:
-
Permalink:
Hawk-API/hawkapi-pagination@da60ecac27dca697ed6922c910c023eb98617714 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Hawk-API
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@da60ecac27dca697ed6922c910c023eb98617714 -
Trigger Event:
release
-
Statement type: