def paginate(wrapped=None, page_size=PAGE_SIZE):
    if wrapped is None:
        def decorator(wrap):
            return paginate(wrap, page_size=page_size)
        return decorator

    @functools.wraps(wrapped)
    def wrapper(context, request):
        result = wrapped(context, request)
        total = result.count()
        page_max = int(math.ceil(total / page_size))
        page_max = max(1, page_max)  # there's always at least one page

        try:
            page = int(request.params['page'])
        except (KeyError, ValueError):
            page = 1
        page = max(1, page)
        page = min(page, page_max)

        offset = (page - 1) * page_size
        limit = page_size

        out = {
            'results': result.offset(offset).limit(limit).all(),
            'total': total,
            'page': {
                'cur': page,
                'max': page_max,
                'next': page + 1 if page < page_max else None,
                'prev': page - 1 if page > 1 else None,
            }
        }
        return out
    return wrapper
Decorate a view function, providing basic pagination facilities.
dataset/ETHPy150Open hypothesis/h/h/paginator.py/paginate