Skip to main content

fast-pager

PyPI version CI Docs

Turn your Pydantic models into filterable, sortable, paginated FastAPI query parameters — automatically.

fast-pager reads the Pydantic models you already use in your FastAPI routes and generates type-safe query parameters for filtering, sorting and pagination. Those parameters show up in your OpenAPI docs for free, and compile down to a real database query (MongoDB first, more backends later).

class User(BaseModel):
    name: str
    age: int

@app.get("/users")
async def list_users(q: FilterQuery[User] = FilterDepends(User)):
    return await db.users.find(q.to_mongo()).to_list(None)

A request to:

GET /users?name__contains=ana&age__gte=21&age__lt=65&sort=-age&limit=20

…compiles to:

{"name": {"$regex": "ana"}, "age": {"$gte": 21, "$lt": 65}}
# sort=[("age", -1)], skip=0, limit=20
# (values in `contains` filters are regex-escaped before compilation)

…and every one of those parameters is documented, validated and typed in /docs.

Want the classic "items + total" response? Page[T] and paginate() are the one-line opt-in — correct OpenAPI schema included, works with motor and pymongo alike (duck-typed, no driver dependency):

@app.get("/users", response_model=Page[User])
async def list_users(q: FilterQuery[User] = FilterDepends(User)):
    return await q.paginate(db.users)   # {"items": [...], "total": 137, "limit": 20, "offset": 0}

Need a curated public surface? Declare an allow-list FilterSet — anything not listed is not filterable — and the call site doesn't change:

class UserFilter(FilterSet):
    class Meta:
        model  = User
        fields = {"name": ["contains"], "age": ["gte", "lte"]}

@app.get("/users")
async def list_users(q: FilterQuery[User] = FilterDepends(UserFilter)): ...

Running on SQL instead of Mongo? The same q compiles to SQLAlchemy 2.0 (pip install 'fast-pager[sqlalchemy]') — only the backend swaps:

@app.get("/users")
def list_users(q: FilterQuery[User] = FilterDepends(User)):
    stmt = q.apply_sqlalchemy(select(UserRow))   # WHERE + ORDER BY + LIMIT/OFFSET
    return session.execute(stmt).scalars().all()

Built with AI

This project is designed and developed with the assistance of AI (Anthropic's Claude Code). Design documents and code are AI-generated and human-reviewed.


Status

fast-pager is under active development. Everything shown above is shipped: the zero-config filtering pipeline over the full type surface (scalars, arrays, nested models, elem element-matching, gated maps), the Mongo compiler, per-field Filterable(...) control, allow-list FilterSets, and the Page[T]/paginate() response envelope. The project is still pre-1.0: per SemVer, breaking changes bump the minor version and are called out in release notes. See the changelog for exactly what each version shipped.

Documentation

The full documentation site — getting started, tutorials, operator reference, and the design documents below — lives at fast-pager.eytanohana.com. It's built with Zensical from docs/; see docs/contributing/docs-site.md for how it's configured and how to preview it locally.

Contributing

Dev setup, quality gates, and conventions live in CONTRIBUTING.md. The short version: uv sync --all-groups, make ruff + mypy + pytest happy (CI enforces all three plus a coverage floor and an oldest-supported-dependencies job), and keep commits small.

Releasing (maintainers)

Releases are fully automated. From a clean main:

./scripts/release.sh patch     # or minor / major

The script bumps the version in pyproject.toml (via uv version --bump), commits, tags v<version>, and pushes. The tag triggers release.yml, which:

  1. verifies the tag matches the pyproject.toml version,
  2. runs the full CI matrix,
  3. builds with uv build and publishes to PyPI via Trusted Publishing (OIDC — no API tokens),
  4. creates the GitHub Release with generated notes.

fast_pager.__version__ reads from package metadata, so the version lives in exactly one place.


Design documents

These are the product-design documents the implementation is built from. Read them in order:

# Document What it covers
00 Overview & Vision The problem, goals, non-goals, naming, guiding principles
01 Developer Experience API surface options explored, the recommended ergonomics
02 Type & Operator System Which Python types we support, their operators, compound types, per-field configurability
03 Architecture The layered pipeline, the filter AST, the FastAPI signature trick
04 Backend Roadmap Mongo today, generalizing to any database tomorrow
05 Roadmap & Release Plan Phased path to a clean 1.0 on PyPI

Start with 00-overview.md.

Release files for fast-pager 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fast-pager 0.4.0
File Size Uploaded
fast_pager-0.4.0.tar.gz 49.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fast-pager 0.4.0
File Interpreter ABI Platform
fast_pager-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 111.0 kB

Release files / fast_pager-0.4.0.tar.gz

Download URL fast_pager-0.4.0.tar.gz
Size 49.9 kB
Tags Source
SHA-256 checksum
How to use checksums
dab3cdd868a75ebb63bfe9f71080c204253080294cf8bd6a51307a0e00b067c6
BLAKE2b-256 checksum
How to use checksums
4fd42d56a7b3789df83d6c0453ba11b5cf7a29e4affe840217d82b34517dfb11
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / fast_pager-0.4.0-py3-none-any.whl

Download URL fast_pager-0.4.0-py3-none-any.whl
Size 61.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
283ed426f0c107b05757e9537066a2ef8ef190657555b18cc643cdd74ea203c6
BLAKE2b-256 checksum
How to use checksums
c3e283255ac5c06bb4a07c3808b07a403f63c2e625f490e76bfa60ad020a17dd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page