美文网首页Pythonflaskpython热爱者
Python的Flask框架开发RESTful API

Python的Flask框架开发RESTful API

作者: 我为峰2014 | 来源:发表于2018-01-17 11:31 被阅读2779次

    web框架选择

    • Django,流行但是笨重,还麻烦,人生苦短,肯定不选

    • web.py,轻量,但据说作者仙逝无人维护,好吧,先pass

    • tornado,据说倡导自己造轮子,虽然是facebook开源的吧,但听到这个,就算了吧

    • flask,轻量,流行,可以自己定义

    安装flask

    pip install flask
    

    flask前端模板引擎默认是jinja2,所以我们还需要安装jinja2

    pip install jinja2
    

    hello world

    from flask import Flask
    from flask import request
    
    app = Flask(__name__)
    
    @app.route('/', methods=['GET', 'POST'])
    def home():
        return '<h1>hello world</h1>'
    
    
    
    if __name__ == '__main__':
        app.run()
    

    运行python app.py,Flask自带的Server在端口5000上监听:

    打开浏览器,输入首页地址http://localhost:5000/

    会出现hello world

    简单的RESTful实现

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # by vellhe 2017/7/9
    from flask import Flask, abort, request, jsonify
    
    app = Flask(__name__)
    
    # 测试数据暂时存放
    tasks = []
    
    @app.route('/add_task/', methods=['POST'])
    def add_task():
        if not request.json or 'id' not in request.json or 'info' not in request.json:
            abort(400)
        task = {
            'id': request.json['id'],
            'info': request.json['info']
        }
        tasks.append(task)
        return jsonify({'result': 'success'})
    
    
    @app.route('/get_task/', methods=['GET'])
    def get_task():
        if not request.args or 'id' not in request.args:
            # 没有指定id则返回全部
            return jsonify(tasks)
        else:
            task_id = request.args['id']
            task = filter(lambda t: t['id'] == int(task_id), tasks)
            return jsonify(task) if task else jsonify({'result': 'not found'})
    
    
    if __name__ == "__main__":
        # 将host设置为0.0.0.0,则外网用户也可以访问到这个服务
        app.run(host="0.0.0.0", port=8383, debug=True)
    
    

    验证结果

    image.png image.png image.png

    以上是通过最原始的方式实现,没有使用flask的RESTful扩展库

    使用flask的RESTful扩展库 flask-restful

    安装Flask-RESTful库:

    pip install flask-restful
    

    demo

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # by vellhe 2017/7/9
    from flask import Flask
    from flask_restful import reqparse, abort, Api, Resource
    
    app = Flask(__name__)
    api = Api(app)
    
    TODOS = {
        'todo1': {'task': 'build an API'},
        'todo2': {'task': '哈哈哈'},
        'todo3': {'task': 'profit!'},
    }
    
    
    def abort_if_todo_doesnt_exist(todo_id):
        if todo_id not in TODOS:
            abort(404, message="Todo {} doesn't exist".format(todo_id))
    
    
    parser = reqparse.RequestParser()
    parser.add_argument('task')
    
    
    # # 操作(put / get / delete)单一资源Todo
    # shows a single todo item and lets you delete a todo item
    class Todo(Resource):
        def get(self, todo_id):
            abort_if_todo_doesnt_exist(todo_id)
            return TODOS[todo_id]
    
        def delete(self, todo_id):
            abort_if_todo_doesnt_exist(todo_id)
            del TODOS[todo_id]
            return '', 204
    
        def put(self, todo_id):
            args = parser.parse_args()
            task = {'task': args['task']}
            TODOS[todo_id] = task
            return task, 201
    
    
    # # 操作(post / get)资源列表TodoList
    # shows a list of all todos, and lets you POST to add new tasks
    class TodoList(Resource):
        def get(self):
            return TODOS
    
        def post(self):
            args = parser.parse_args()
            todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
            todo_id = 'todo%i' % todo_id
            TODOS[todo_id] = {'task': args['task']}
            return TODOS[todo_id], 201
    
    
    
    # 设置路由
    api.add_resource(TodoList, '/todos')
    api.add_resource(Todo, '/todos/<todo_id>')
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    (1)引入需要的库名、函数、变量等,并做简单的Application初始化:

    from flask import Flask
    from flask_restful import reqparse, abort, Api, Resource
    
    app = Flask(__name__)
    api = Api(app)
    

    (2)定义我们需要操作的资源类型(都是json格式的):

    TODOS = {
        'todo1': {'task': 'build an API'},
        'todo2': {'task': '哈哈哈'},
        'todo3': {'task': 'profit!'},
    }
    

    (3)Flask-RESTful提供了一个用于参数解析的RequestParser类,类似于Python中自带的argparse类,可以很方便的解析请求中的-d参数,并进行类型转换。

    parser = reqparse.RequestParser()
    parser.add_argument('task')
    

    (4)我们观察标准的API接口,这里的接口可以分为两类:带有item_id的,和不带有item_id的。前者是操作单一资源,后者是操作资源列表或新建一个资源。

    从操作单一资源开始,继承Resource类,并添加put / get / delete方法:

    class Todo(Resource):
        def get(self, todo_id):
            abort_if_todo_doesnt_exist(todo_id)
            return TODOS[todo_id]
    
        def delete(self, todo_id):
            abort_if_todo_doesnt_exist(todo_id)
            del TODOS[todo_id]
            return '', 204
    
        def put(self, todo_id):
            args = parser.parse_args()
            task = {'task': args['task']}
            TODOS[todo_id] = task
            return task, 201
    

    (5)继续操作资源列表,继承Resource类,并添加get / post方法:

    class TodoList(Resource):
        def get(self):
            return TODOS
    
        def post(self):
            args = parser.parse_args()
            todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
            todo_id = 'todo%i' % todo_id
            TODOS[todo_id] = {'task': args['task']}
            return TODOS[todo_id], 201
    

    (6)资源操作类定义完毕之后,需要设置路由,即告诉Python程序URL的对应关系。

    api.add_resource(TodoList, '/todos')
    api.add_resource(Todo, '/todos/<todo_id>')
    

    这样当我们请求url时,就能根据url类型,找到相应的资源类,并调用对应方法。

    验证结果

    查询列表:

    image.png

    查询单任务:

    image.png

    删除任务:

    image.png

    添加任务(这是用post表单形式,还可以改成json形式啦):

    image.png

    更新任务:

    image.png

    相关文章

      网友评论

      本文标题:Python的Flask框架开发RESTful API

      本文链接:https://www.haomeiwen.com/subject/pgvyoxtx.html