Skip to content

Commit

Permalink
Split paginate and template in Pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
AliRn76 committed Mar 28, 2024
1 parent b610c35 commit e690935
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/docs/release_notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### 4.1.1
- Fix an issue in `Response.prepare_data()` when `data` is `Cursor`
- Split `paginate` and `template` in `Pagination`

### 4.1.0
- Support `prepare_response` in `Serializers`
Expand Down
2 changes: 2 additions & 0 deletions panther/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ async def wrapper(request: Request) -> Response:
response = Response(data=response)
if self.output_model and response.data:
response.data = await response.apply_output_model(output_model=self.output_model)
if response.pagination:
response.data = await response.pagination.template(response.data)

# 10. Set New Response To Cache
if self.cache and self.request.method == 'GET':
Expand Down
10 changes: 5 additions & 5 deletions panther/generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ class ListAPI(GenericAPI, CursorRequired):
pagination: type[Pagination]

async def get(self, request: Request, **kwargs):
cursor = await self.prepare_cursor(request=request, **kwargs)
return Response(data=cursor, status_code=status.HTTP_200_OK)
cursor, pagination = await self.prepare_cursor(request=request, **kwargs)
return Response(data=cursor, pagination=pagination, status_code=status.HTTP_200_OK)

async def prepare_cursor(self, request: Request, **kwargs):
async def prepare_cursor(self, request: Request, **kwargs) -> tuple[Cursor | PantherDBCursor, Pagination | None]:
cursor = await self.cursor(request=request, **kwargs)
self._check_cursor(cursor)

Expand All @@ -83,9 +83,9 @@ async def prepare_cursor(self, request: Request, **kwargs):
cursor = cursor.sort(sort)

if pagination := self.process_pagination(query_params=request.query_params, cursor=cursor):
cursor = await pagination.paginate()
cursor = pagination.paginate()

return cursor
return cursor, pagination

def process_filters(self, query_params: dict, cursor: Cursor | PantherDBCursor) -> dict:
_filter = {}
Expand Down
7 changes: 5 additions & 2 deletions panther/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ def build_previous_params(self):
previous_skip = max(self.skip - self.limit, 0)
return f'?limit={self.limit}&skip={previous_skip}'

async def paginate(self):
def paginate(self):
return self.cursor.skip(skip=self.skip).limit(limit=self.limit)

async def template(self, response: list):
count = await self.cursor.cls.count(self.cursor.filter)
has_next = not bool(self.limit + self.skip >= count)

return {
'count': count,
'next': self.build_next_params() if has_next else None,
'previous': self.build_previous_params() if self.skip else None,
'results': self.cursor.skip(skip=self.skip).limit(limit=self.limit)
'results': response
}
5 changes: 5 additions & 0 deletions panther/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from panther.db.cursor import Cursor
from pantherdb import Cursor as PantherDBCursor
from panther.monitoring import Monitoring
from panther.pagination import Pagination

ResponseDataTypes = list | tuple | set | Cursor | PantherDBCursor | dict | int | float | str | bool | bytes | NoneType | Type[BaseModel]
IterableDataTypes = list | tuple | set | Cursor | PantherDBCursor
Expand All @@ -24,13 +25,17 @@ def __init__(
data: ResponseDataTypes = None,
headers: dict | None = None,
status_code: int = status.HTTP_200_OK,
pagination: Pagination | None = None,
):
"""
:param data: should be an instance of ResponseDataTypes
:param headers: should be dict of headers
:param status_code: should be int
:param pagination: instance of Pagination or None
Its template() method will be used
"""
self.headers = headers or {}
self.pagination: Pagination | None = pagination
if isinstance(data, Cursor):
data = list(data)
self.initial_data = data
Expand Down

0 comments on commit e690935

Please sign in to comment.