I need to throw together an very simple API with a short deadline. Flask-restful seems ideal except for one thing: I can't find anything in the documentation about pagination. Given a simple endpoint like this:
from flask import Flask, request 
from flask_restful import Resource, Api 
from sqlalchemy import create_engine
import json 
app = Flask(__name__)
api = Api(app)
class Employees(Resource):
    def get(self):
        return json.dumps([{'employees': 'hello world'} for i in range(1000)])
api.add_resource(Employees, '/employees')
if __name__ == '__main__':
    app.run(port='5002')
Is there any way for flask_restful to paginate the endpoint so that I only receive, say, 100 of those dictionaries per page, and have URLs for 'next' and 'previous'? If not, is it maybe possible to create pagination some other way in Flask? Thanks.
Modify the view to cater to pagination. Results are paginated using the paginate function of Flask SQLAlchemy with any number of arguments as desired. The result of calling the paginate() function is a Pagination Object, which has many methods that can help you achieve your desired result.
Being lightweight, easy to adopt, well-documented, and popular, Flask is a good option for developing RESTful APIs.
You can either use:
flask_sqlalchemy (API documentation can be found here)
As I am not sure if you are using flask_sqlalchemy or any model information, I am showing the custom pagination technique.
I have modified the data to show the employee id. And I also used jsonify from Flask.
from flask import Flask, request, jsonify, abort
from flask_restful import Resource, Api 
app = Flask(__name__)
api = Api(app)
data = [{'employee_id': i+1} for i in range(1000)]
def get_paginated_list(results, url, start, limit):
    start = int(start)
    limit = int(limit)
    count = len(results)
    if count < start or limit < 0:
        abort(404)
    # make response
    obj = {}
    obj['start'] = start
    obj['limit'] = limit
    obj['count'] = count
    # make URLs
    # make previous url
    if start == 1:
        obj['previous'] = ''
    else:
        start_copy = max(1, start - limit)
        limit_copy = start - 1
        obj['previous'] = url + '?start=%d&limit=%d' % (start_copy, limit_copy)
    # make next url
    if start + limit > count:
        obj['next'] = ''
    else:
        start_copy = start + limit
        obj['next'] = url + '?start=%d&limit=%d' % (start_copy, limit)
    # finally extract result according to bounds
    obj['results'] = results[(start - 1):(start - 1 + limit)]
    return obj
class Employees(Resource):
    def get(self):
        return jsonify(get_paginated_list(
        data, 
        '/employees', 
        start=request.args.get('start', 1), 
        limit=request.args.get('limit', 20)
    ))
api.add_resource(Employees, '/employees')
if __name__ == '__main__':
    app.run(port='5002', debug=True)
Output:

Footnote:
http://127.0.0.1:5002/employeeshttp://127.0.0.1:5002/employees?start=41&limit=20http://127.0.0.1:5002/employees?limit=5http://127.0.0.1:5002/employees?start=100start is 1 and limit is 20.start value is greater than data length or limit is negative then the API will return HTTP 404 error with an error message:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With