Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Implement pagination headers
Browse files Browse the repository at this point in the history
Fixes #19
  • Loading branch information
rambobinator authored and Vincent Trubesset committed Nov 28, 2018
1 parent d020ac4 commit 7526b7b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
4 changes: 4 additions & 0 deletions flask_stupe/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ def make_response(self, rv):

rv = jsonify(rv)
rv.status_code = code

if request.response_headers:
rv.headers.extend(request.response_headers)

return rv

def __init__(self, *args, **kwargs):
Expand Down
34 changes: 26 additions & 8 deletions flask_stupe/pagination.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
import functools

from flask import request

from flask_stupe import pymongo

__all__ = []


if pymongo:
def _paginate(cursor, skip=None, limit=None, sort=None, count=True):
metadata = getattr(request, "metadata", None)
if count and isinstance(metadata, dict):
metadata.update(count=cursor.count())

def _get_link_header(total_count, limit, skip):
template = '<{}?limit={}&skip={{skip}}>; ' \
'rel="{{rel}}"'.format(request.base_url, limit)
return ", ".join([
template.format(skip=0, rel="first"),
template.format(skip=skip - limit, rel="prev"),
template.format(skip=skip + limit, rel="next"),
template.format(skip=total_count - limit, rel="last")
])

def _paginate(cursor, skip=None, limit=None, sort=None, count=True,
headers=False):
if headers:
total_count = cursor.count()
headers = getattr(request, "response_headers")
headers["X-Total-Count"] = total_count
headers["Link"] = _get_link_header(total_count, limit, skip)
else:
metadata = getattr(request, "metadata", None)
if count and isinstance(metadata, dict):
metadata.update(count=cursor.count())

skip = request.args.get("skip", skip, type=int)
if skip is not None:
Expand All @@ -35,16 +52,17 @@ def _paginate(cursor, skip=None, limit=None, sort=None, count=True):
return cursor

def paginate(function_or_cursor=None, skip=None, limit=None, sort=None,
count=True):
count=True, headers=False):
"""Apply pagination to the given MongoDB cursor or function"""
if isinstance(function_or_cursor, pymongo.cursor.Cursor):
return _paginate(function_or_cursor, skip, limit, sort, count)
return _paginate(function_or_cursor, skip, limit, sort, count,
headers)

def __decorator(function):
@functools.wraps(function)
def __wrapper(*args, **kwargs):
cursor = function(*args, **kwargs)
return _paginate(cursor, skip, limit, sort, count)
return _paginate(cursor, skip, limit, sort, count, headers)
return __wrapper

if function_or_cursor:
Expand Down
1 change: 1 addition & 0 deletions flask_stupe/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def __init__(self, *args, **kwargs):

#: Store additionnal data about the request.
self.metadata = {}
self.response_headers = {}


__all__ = ["Request"]

0 comments on commit 7526b7b

Please sign in to comment.