Skip to content

pyrsql

A compiler-oriented RSQL query engine for safe, typed, and extensible filtering, sorting, and pagination in Python APIs.

pyrsql compiles RSQL query strings into ORM-specific statement objects through a multi-stage pipeline - making it easy to expose complex query capabilities in your API without coupling to a specific ORM or framework.

Install

pip install pyrsql[fastapi,sqlalchemy]
from typing import Annotated, Any

from fastapi import Depends, FastAPI

from pyrsql.integrations.fastapi import FastAPISQLAlchemyIntegration

app = FastAPI()
integration = FastAPISQLAlchemyIntegration()
users = integration.resource(
    User,
    filterable_fields={"id", "name"},
    sortable_fields={"name"},
    default_sort="name,asc",
)

@app.get("/users")
def list_users(
    stmt: Annotated[Any, Depends(users.select_dependency())],
):
    return {"sql": str(stmt)}

The integration parses request criteria, applies SQLAlchemy filters/sorting/ pagination, and exposes a route-ready dependency. It does not execute database I/O.

Key features

  • ORM-neutral core - Query, Sort, PageRequest have zero ORM dependencies
  • Pluggable backends - SQLAlchemy 2.0 today, Django ORM / SQLModel planned
  • Pluggable adapters - FastAPI today, Flask planned
  • 20+ built-in operators - ==, =like=, =in=, =bt=, =nn=, etc.
  • Custom operators - define your own RSQL operators with per-ORM lowering
  • Field policies - whitelist, blacklist, aliases (global + per-model)
  • JSON / JSONB - PostgreSQL jsonpath with structured values and datetime support
  • Type-safe - strict mypy, Google-style docstrings, immutable value objects
  • Async-compatible execution - generated SQLAlchemy statements work with both Session and AsyncSession
  • Free-threaded-safe shared caches - integration and ORM helper caches are guarded for concurrent access
  • Security-oriented request handling - parser/sort limits, structural allowlists/blocklists, and sanitized FastAPI error payloads

Integration options

  • FastAPI + SQLAlchemy integration - route-ready dependencies, declarative resource() helpers, count/paginated bundles, and normalized backend error translation
  • FastAPI adapter - parse filter, sort, page, and size into RequestCriteria when you need criteria without SQLAlchemy integration

Next steps