Skip to main content

ORM-agnostic pagination toolkit for Python

Project description

pagi

A minimal, ORM-agnostic pagination toolkit for Python.

pagi lets you define pagination logic once and reuse it across different ORMs (SQLAlchemy, Django, etc.), returning consistent, typed responses powered by Pydantic.


Features

  • Offset/limit pagination with validation via Pydantic
  • Unified response model (PaginatedResponse)
  • SQLAlchemy support (sync and async)
  • Django ORM support
  • Strategy-based internal design for easy extensibility
  • ORM-agnostic public API

Installation

pip install pagi

Or with development dependencies:

pip install -e .[dev]

Basic Usage

Importing

The installable package name is pagi, but the Python module is paginator.

Recommended import:

from paginator.paginator import paginate, paginate_sync

SQLAlchemy (Synchronous)

from sqlalchemy import select
from sqlalchemy.orm import Session
from paginator import paginate_sync

def get_users(session: Session):
    return paginate_sync(
        session,
        lambda: select(User),
        offset=10,
        limit=5,
        backend="sqlalchemy",
    )

SQLAlchemy (Asynchronous)

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from paginator import paginate

async def get_users(session: AsyncSession):
    return await paginate(
        session,
        lambda: select(User),
        offset=10,
        limit=5,
        backend="sqlalchemy",
    )

The correct strategy (sync vs async) is selected automatically based on the session type.


Django ORM

from paginator import paginate_sync
from myapp.models import User

result = paginate_sync(
    connection=None,
    query_func=lambda: User.objects.all(),
    offset=20,
    limit=10,
    backend="django",
)

Notes:

  • query_func must return an unevaluated Django QuerySet
  • Django pagination is synchronous (async execution is not supported)

Design and Architecture

pagi is built around the Strategy pattern, allowing multiple ORMs to be supported while keeping a single, simple public API.

  • paginator.paginator exposes the public functions (paginate, paginate_sync)
  • Each ORM implements its own pagination strategy
  • A small factory selects the appropriate strategy at runtime based on the backend and connection type
  • Pagination logic is decoupled from data access, making new backends easy to add

SQLAlchemy Strategy Selection

For SQLAlchemy, pagi uses a factory-based approach:

  • Passing a Session enables synchronous pagination
  • Passing an AsyncSession enables asynchronous pagination
  • The correct strategy is chosen automatically without extra configuration

Roadmap

  • Cursor-based pagination (cursor tokens instead of offset/limit)
  • Tortoise ORM support
  • Optional total count for performance-sensitive queries

Development

Run tests with:

pytest

The test suite covers:

  • SQLAlchemy (sync)
  • SQLAlchemy (async, optional)
  • Django ORM

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pagi-0.2.0.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pagi-0.2.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file pagi-0.2.0.tar.gz.

File metadata

  • Download URL: pagi-0.2.0.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pagi-0.2.0.tar.gz
Algorithm Hash digest
SHA256 bf8e8907989ee87a5f3ee2b6628885b6d205206e8025d51710ca8aae7b7d5814
MD5 b7b8546b76ff88ca5c1d3fe5fdeda12b
BLAKE2b-256 28b7df6699f61385ff4e27829f7ec32a283ad445304ce9c5356ad65361dcecda

See more details on using hashes here.

File details

Details for the file pagi-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pagi-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 7.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for pagi-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5b5e7324186c2df8ba7f5054521d3e484f726fe9cfb4161460fbb2e5f95cc41d
MD5 c138039369a05061c6306434a3402e95
BLAKE2b-256 f8b010d629bc84f5a56e7aa5b037cae1079a39a2276e968ae2a707aafd9e8742

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page