2026-02-09 15:49:50 +05:30
|
|
|
"""Typed wrapper around fastapi-pagination for backend query helpers."""
|
|
|
|
|
|
2026-02-06 19:11:11 +05:30
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from collections.abc import Awaitable, Callable, Sequence
|
2026-02-09 15:49:50 +05:30
|
|
|
from typing import TYPE_CHECKING, Any, TypeVar, cast
|
2026-02-06 19:11:11 +05:30
|
|
|
|
|
|
|
|
from fastapi_pagination.ext.sqlalchemy import paginate as _paginate
|
|
|
|
|
|
|
|
|
|
from app.schemas.pagination import DefaultLimitOffsetPage
|
|
|
|
|
|
2026-02-09 15:49:50 +05:30
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
|
|
|
|
from sqlmodel.sql.expression import Select, SelectOfScalar
|
|
|
|
|
|
2026-02-06 19:11:11 +05:30
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
|
|
|
|
Transformer = Callable[[Sequence[Any]], Sequence[Any] | Awaitable[Sequence[Any]]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def paginate(
|
|
|
|
|
session: AsyncSession,
|
|
|
|
|
statement: Select[Any] | SelectOfScalar[Any],
|
|
|
|
|
*,
|
|
|
|
|
transformer: Transformer | None = None,
|
|
|
|
|
) -> DefaultLimitOffsetPage[T]:
|
2026-02-09 15:49:50 +05:30
|
|
|
"""Execute a paginated query and cast to the project page type alias."""
|
|
|
|
|
# fastapi-pagination is not fully typed (it returns Any), but response_model
|
|
|
|
|
# validation ensures runtime correctness. Centralize casts here to keep strict
|
|
|
|
|
# mypy clean.
|
2026-02-06 19:11:11 +05:30
|
|
|
return cast(
|
|
|
|
|
DefaultLimitOffsetPage[T],
|
|
|
|
|
await _paginate(session, statement, transformer=transformer),
|
|
|
|
|
)
|