Flask restful pagination

妖精的绣舞 提交于 2020-12-28 20:54:24

问题


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.


回答1:


You can either use:

  • Pagination provided by flask_sqlalchemy (API documentation can be found here)
  • Custom method to paginate existing data as shown in this tutorial by Avi Aryan.

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:

  • API can be called with parameter or without parameter. Example of valid API calls:
    • 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
  • Default value for start is 1 and limit is 20.
  • If the start value is greater than data length or limit is negative then the API will return HTTP 404 error with an error message:



来源:https://stackoverflow.com/questions/55543011/flask-restful-pagination

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!