Source code for flump.pagination

from collections import namedtuple
from math import ceil
from werkzeug.exceptions import BadRequest

from flask import request

try:
    # handle imports for python 2/3
    from urllib.parse import urlencode, urlparse
except ImportError:
    from urllib import urlencode
    from urlparse import urlparse


PaginationArgs = namedtuple('PaginationArgs', ('page', 'size'))


[docs]class BasePagination(object): """ Base Paginator class which all paginators should inherit from. Provides a `transform_get_many_response` function which is called from :func:`.methods.get_many.GetMany._make_get_many_response` in order to add any meta information as needed. """ def __init__(self, fetcher): self.fetcher = fetcher
[docs] def get_pagination_args(self): """ Gets the pagination args from the request. """ return
[docs] def transform_get_many_response(self, response, **kwargs): """ Transforms the response to a get_many request. Mainly intended to add extra pagination links/meta information if pagination is implemented for the api. :returns: :class:`.schemas.ManyResponseData` """ return response
[docs]class PageSizePagination(BasePagination): """ Mixin class which provides methods for Number/Size based pagination. """ DEFAULT_PAGE_SIZE = 10 MAX_PAGE_SIZE = 100
[docs] def get_pagination_args(self): """ Gets the pagination args from the query string. :returns: :class:`PaginationArgs` containing the page number and page sizes specified. Accounts for :attribute:`PageSizePagination.DEFAULT_PAGE_SIZE` and :attribute:`PageSizePagination.MAX_PAGE_SIZE`. """ page = int(request.args.get('page[number]') or 1) size = int(request.args.get('page[size]') or self.DEFAULT_PAGE_SIZE) if page < 1 or size < 1: raise BadRequest( "Both page[number] and page[size] must be at least 1" ) return PaginationArgs(max(page, 1), min(size, self.MAX_PAGE_SIZE))
[docs] def transform_get_many_response(self, response, **kwargs): """ Returns a `schemas.ManyResponseData` with the links replaced with those returned by `get_pagination_links`. Also adds the `max_results` and `page` args to the meta. """ response = response._replace(links=self.get_pagination_links(**kwargs)) pagination_args = self.get_pagination_args() meta = response.meta meta['extra'] = {'size': pagination_args.size, 'page': pagination_args.page} return response._replace(meta=meta)