From 884dfc2d043eaaa2c50a7e4391d3d6563b4d1b23 Mon Sep 17 00:00:00 2001 From: Boris Ranto Date: Fri, 19 May 2017 15:58:40 +0200 Subject: [PATCH] restful: Add pagination support This commit adds a pagination support via paginate decorator. The decorator will paginate the output if it is told to. The first page is 0, the last page is -1. The decorator was applied to /request endpoint so you can get requests in hunderds if you supply the endpoint with ?page=N. If no ?page=N is supplied, the decorator will output the full list. Signed-off-by: Boris Ranto --- src/pybind/mgr/restful/api/request.py | 3 ++- src/pybind/mgr/restful/decorators.py | 34 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/pybind/mgr/restful/api/request.py b/src/pybind/mgr/restful/api/request.py index 3c4dd7abca8b..b22b80bff8a4 100644 --- a/src/pybind/mgr/restful/api/request.py +++ b/src/pybind/mgr/restful/api/request.py @@ -2,7 +2,7 @@ from pecan import expose, request, response from pecan.rest import RestController from restful import module -from restful.decorators import auth, lock +from restful.decorators import auth, lock, paginate class RequestId(RestController): @@ -48,6 +48,7 @@ class RequestId(RestController): class Request(RestController): @expose(template='json') + @paginate @auth def get(self, **kwargs): """ diff --git a/src/pybind/mgr/restful/decorators.py b/src/pybind/mgr/restful/decorators.py index 09fa64dca536..e5d7d62ae87c 100644 --- a/src/pybind/mgr/restful/decorators.py +++ b/src/pybind/mgr/restful/decorators.py @@ -41,3 +41,37 @@ def lock(f): with module.instance.requests_lock: return f(*args, **kwargs) return decorated + + +# Support ?page=N argument +def paginate(f): + @wraps(f) + def decorated(*args, **kwargs): + _out = f(*args, **kwargs) + + # Do not modify anything without a specific request + if not 'page' in kwargs: + return _out + + # A pass-through for errors, etc + if not isinstance(_out, list): + return _out + + # Parse the page argument + _page = kwargs['page'] + try: + _page = int(_page) + except ValueError: + response.status = 500 + return {'message': 'The requested page is not an integer'} + + # Raise _page so that 0 is the first page and -1 is the last + _page += 1 + + if _page > 0: + _page *= 100 + else: + _page = len(_out) - (_page*100) + + return _out[_page - 100: _page] + return decorated -- 2.47.3