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/employees
http://127.0.0.1:5002/employees?start=41&limit=20
http://127.0.0.1:5002/employees?limit=5
http://127.0.0.1:5002/employees?start=100
start
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