Skip to content

Commit e4f5a68

Browse files
committed
LITE-29680 Supports of fastapi pagination
1 parent 9d9fa95 commit e4f5a68

File tree

4 files changed

+98
-1
lines changed

4 files changed

+98
-1
lines changed
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from fastapi import Query
2+
from fastapi_pagination import LimitOffsetPage, LimitOffsetParams, set_page
3+
from fastapi_pagination.api import resolve_params
4+
from fastapi_pagination.ext.sqlalchemy import paginate
5+
6+
7+
set_page(LimitOffsetPage)
8+
9+
10+
class PaginationParams(LimitOffsetParams):
11+
"""Here we can redefine default size value"""
12+
13+
limit: int = Query(1000, ge=1, le=1000, description="Page size")
14+
15+
16+
def apply_pagination(query, db, params, response):
17+
"""Apply pagination for the query
18+
* Paginate query according to applied parameters (size and page)
19+
* Add pagination headers to the response
20+
Don't filter or remove elements from query after the pagination
21+
"""
22+
paginated = paginate(db, query, params)
23+
resolve_params(params)
24+
init = paginated.offset
25+
# If we are selecting a page that it's out of range, we return the same start and end for on
26+
# header range, copying the same behavior as connect.
27+
end = init
28+
if paginated.items:
29+
end += len(paginated.items) - 1
30+
31+
response.headers['Content-Range'] = f'items {init}-{end}/{paginated.total}'
32+
return paginated.items

poetry.lock

+33-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ python = ">=3.8,<4"
1515
sqlalchemy = "^1.3.12"
1616
pyjwt = "^2.8.0"
1717
connect-eaas-core = "^30.3"
18+
fastapi-pagination = "<=0.12.17"
1819

1920
[tool.poetry.dev-dependencies]
2021
pytest = ">=6.1.2,<8"

tests/api/test_pagination.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import pytest
2+
from fastapi import Response
3+
4+
from connect_extension_utils.api.pagination import PaginationParams, apply_pagination
5+
6+
7+
@pytest.mark.parametrize(
8+
('limit', 'offset', 'expected_length', 'expected_header'),
9+
(
10+
(10, 0, 10, 'items 0-9/20'),
11+
(10, 20, 0, 'items 20-20/20'),
12+
(9, 18, 2, 'items 18-19/20'),
13+
),
14+
)
15+
def test_apply_pagination(
16+
limit,
17+
offset,
18+
expected_length,
19+
expected_header,
20+
dbsession,
21+
my_model_factory,
22+
):
23+
params = PaginationParams(limit=limit, offset=offset)
24+
for _ in range(20):
25+
my_model_factory()
26+
27+
items = dbsession.query(my_model_factory._meta.model)
28+
response = Response()
29+
paginated_items = apply_pagination(items, dbsession, params, response)
30+
31+
assert len(paginated_items) == expected_length
32+
assert response.headers['Content-Range'] == expected_header

0 commit comments

Comments
 (0)