/paginate-any

Primary LanguagePythonApache License 2.0Apache-2.0

python version formatter black Ruff

PaginateAny

Pagination primitives for any ORM and web-frameworks.

Known issues

  • Decode and Encode of a cursor values hardcoded with msgspec.msgpack module. You can't use timezone-naive datetime format, because it converts value to the str type. See spec and issue about supported types.

Code example

from typing import Annotated
from datetime import datetime, timezone

from fastapi import FastAPI, Depends
from paginate_any.cursor_pagination import InMemoryCursorPaginator
from paginate_any.ext.fastapi import (
    FastApiCursorPagination,
    PaginationDependProtocol,
    init_paginate_any_fastapi_app,
)
from paginate_any.rest_api import JsonPaginationResp
from pydantic import BaseModel

app = FastAPI()
init_paginate_any_fastapi_app(app)


class Car(BaseModel):
    id: int
    name: str
    factory_start: datetime


paginator = InMemoryCursorPaginator[Car](
    unq_field='id',
    sort_fields={
      'id': 'id',
      'factory_start': 'factory_start',
    },
    default_size=2,
)
store = [
    Car(id=1, name='BMW', factory_start=datetime(1916, 3, 7, tzinfo=timezone.utc)),
    Car(id=2, name='Audi', factory_start=datetime(1909, 7, 16, tzinfo=timezone.utc)),
    Car(id=3, name='Mercedes-Benz', factory_start=datetime(1926, 6, 28, tzinfo=timezone.utc)),
    Car(id=4, name='Volkswagen', factory_start=datetime(1937, 5, 28, tzinfo=timezone.utc)),
    Car(id=5, name='Porsche', factory_start=datetime(1931, 4, 25, tzinfo=timezone.utc)),
]


@app.get('/cars', response_model=JsonPaginationResp[Car])
async def cars(
    p: Annotated[
        PaginationDependProtocol[list[Car], Car],
        Depends(FastApiCursorPagination.depend(paginator)),
    ],
):
    result = await p.paginate(store)
    return result.json_resp()

Request:

curl -X GET "http://127.0.0.1:8000/cars?ordering=factory_start" -H  "accept: application/json"

Response:

{
  "pagination": {
    "size": 2,
    "after": "kscM_wAAAAD_____msOxAAE="
  },
  "links": {
    "next": "http://127.0.0.1:8000/cars?after=kscM_wAAAAD_____msOxAAE%3D&ordering=factory_start"
  },
  "data": [
    {
      "id": 2,
      "name": "Audi",
      "factory_start": "1909-07-16T00:00:00Z"
    },
    {
      "id": 1,
      "name": "BMW",
      "factory_start": "1916-03-07T00:00:00Z"
    }
  ]
}