zoukankan      html  css  js  c++  java
  • Flask 扩展 Flask-RESTful

    Flask路由可以指定HTTP请求方法,并在请求函数中根据不同的请求方法,执行不同的逻辑。这样实现一个Restful的请求已经相当简单了

    Flask还有更简便的方法,就是其Flask-RESTful扩展。首先,我们来安装这个扩展:

    pip install Flask-RESTful

    安装完后,你就可以在代码中导入该扩展包

    from flask import Flask, request
    from flask_restful import Api, Resource
     
    app = Flask(__name__)
    api = Api(app)
     
    USER_LIST = {
        '1': {'name':'Michael'},
        '2': {'name':'Tom'},
    }
     
    class UserList(Resource):
        def get(self):
            return USER_LIST
     
        def post(self):
            user_id = int(max(USER_LIST.keys())) + 1
            user_id = '%i' % user_id
            USER_LIST[user_id] = {'name': request.form['name']}
            return USER_LIST[user_id]
     
    api.add_resource(UserList, '/users')
     
    if __name__ == '__main__':
        app.run(host='0.0.0.0', debug=True)

    这个例子很容易理解,Restful扩展通过”api.add_resource()”方法来添加路由,方法的第一个参数是一个类名,该类继承”Resource”基类,其成员函数定义了不同的HTTP请求方法的逻辑;第二个参数定义了URL路径。运行上面的例子并访问”http://localhost:5000/users”,GET请求时会列出全局变量”USER_LIST”中的内容,POST请求时会在”USER_LIST”中添加一项,并返回刚添加的项。如果在POST请求中找不到”name”字段,则返回”400 Bad Request”错误。由于类”UserList”没有定义”put”和”delete”函数,所以在PUT或DELETE请求时会返回”405 Method Not Allowed”错误。

    另外,路由支持多路径,比如:

    api.add_resource(UserList, '/userlist', '/users')

    这样访问”http://localhost:5000/userlist”和”http://localhost:5000/users”的效果完全一样。

    带参数的请求

    上面的例子请求是针对user列表的,如果我们要对某个具体的user做操作,就需要传递具体的”user_id”了。这时候,我们需要路由支持带参数。Flask-RESTful的实现同Flask一样,就是在路由中加上参数变量即可。我们看下例子:

    class User(Resource):
        def get(self, user_id):
            return USER_LIST[user_id]
     
        def delete(self, user_id):
            del USER_LIST[user_id]
            return ''
     
        def put(self, user_id):
            USER_LIST[user_id] = {'name': request.form['name']}
            return USER_LIST[user_id]
     
    api.add_resource(User, '/users/<user_id>')

    在”api.add_resource()”的第二个参数路径中加上URL参数变量即可,格式Flask路由中完全一样,也支持转换器来转换变量类型。此外,在User类的GET,POST,PUT等成员函数中,记得加上参数”user_id”来获取传入的变量值。

    参数解析

    在POST或PUT请求中,直接访问form表单并验证的工作有些麻烦。Flask-RESTful提供了”reqparse”库来简化。我们来改进下上例中的PUT函数:

    from flask_restful import reqparse
     
    parser = reqparse.RequestParser()
    parser.add_argument('name', type=str)
     
    class User(Resource):
        def put(self, user_id):
            args = parser.parse_args()
            USER_LIST[user_id] = {'name': args['name']}
            return USER_LIST[user_id]

    可以通过”parser.add_argument()”方法来定义form表单字段,并指定其类型(本例中是字符型str)。然后在PUT函数中,就可以调用”parser.parse_args()”来获取表单内容,并返回一个字典,该字典就包含了表单的内容。”parser.parse_args()”方法会自动验证数据类型,并在类型不匹配时,返回400错误。你还可以添加”strict”参数,如”parser.parse_args(strict=True)”,此时如果请求中出现未定义的参数,也会返回400错误。

    示例代码

    from flask import Flask
    from flask_restful import Api, Resource, reqparse, abort
     
    app = Flask(__name__)
    api = Api(app)
     
    USER_LIST = {
        1: {'name':'Michael'},
        2: {'name':'Tom'},
    }
     
    parser = reqparse.RequestParser()
    parser.add_argument('name', type=str)
     
    def abort_if_not_exist(user_id):
        if user_id not in USER_LIST:
            abort(404, message="User {} doesn't exist".format(user_id))
     
    class User(Resource):
        def get(self, user_id):
            abort_if_not_exist(user_id)
            return USER_LIST[user_id]
     
        def delete(self, user_id):
            abort_if_not_exist(user_id)
            del USER_LIST[user_id]
            return '', 204
     
        def put(self, user_id):
            args = parser.parse_args(strict=True)
            USER_LIST[user_id] = {'name': args['name']}
            return USER_LIST[user_id], 201
     
    class UserList(Resource):
        def get(self):
            return USER_LIST
     
        def post(self):
            args = parser.parse_args(strict=True)
            user_id = int(max(USER_LIST.keys())) + 1
            USER_LIST[user_id] = {'name': args['name']}
            return USER_LIST[user_id], 201
     
    api.add_resource(UserList, '/users')
    api.add_resource(User, '/users/<int:user_id>')
     
    if __name__ == '__main__':
        app.run(host='0.0.0.0', debug=True)
  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/Erick-L/p/7025708.html
Copyright © 2011-2022 走看看