• 9-----基于flask_restful模块构建一个优雅的后端服务器


    首先安装模块:
    pip install flask-restful
    
    ##官方文档的例子:
    from flask import Flask
    from flask_restful import Resource,Api
    
    app = Flask(__name__)
    api = Api(app)
    
    class HelloWorld(Resource):
        def get(self):
            return {'hello': 'world'}
    
    api.add_resource(HelloWorld, '/')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    ####测试访问get请求:
    [root@localhost opt]# curl http://127.0.0.1:5000/
    {
        "hello": "world"
    }
    
    2、添加路由:
    from flask import Flask, request
    from flask_restful import Resource, Api
    
    app = Flask(__name__)
    api = Api(app)
    
    todos = {}
    
    class TodoSimple(Resource):
        def get(self, todo_id):
            return {todo_id: todos[todo_id]}
    
        def put(self, todo_id):
            todos[todo_id] = request.form['data']
            return {todo_id: todos[todo_id]}
    
    api.add_resource(TodoSimple, '/<string:todo_id>')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    ###测试访问请求:
    [root@localhost opt]# curl http://127.0.0.1:5000/todo1 -d 'data=apple' -X PUT
    {
        "todo1": "apple"
    }
    [root@localhost opt]# curl http://127.0.0.1:5000/todo1
    {
        "todo1": "apple"
    }
    
    由于是form['data']所以我们传的参数一定是data:
    [root@localhost opt]# curl http://127.0.0.1:5000/todo1 -d 'task=jimi' -X PUT
    {
        "message": "The browser (or proxy) sent a request that this server could not understand."
    }
    
    3、多个类型返回值:
    [root@localhost opt]# cat test_rest.py 
    from flask import Flask, request
    from flask_restful import Resource, Api
    
    app = Flask(__name__)
    api = Api(app)
    todos = {}
    
    class Todo1(Resource):
        def get(self):
            return {'task': 'apple'}
    
    class Todo2(Resource):
        def get(self):
            return {'task': 'babana'}, 201
    
    class Todo3(Resource):
        def get(self):
            return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}
    
    api.add_resource(Todo1, '/Todo1')
    api.add_resource(Todo2, '/Todo2')
    api.add_resource(Todo3, '/Todo3')
    
    
    if __name__ == "__main__":
        app.run(debug=True)
    
    ##测试:
    [root@localhost opt]# curl -i http://127.0.0.1:5000/Todo1
    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 24
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Tue, 15 Oct 2019 16:41:09 GMT
    
    {
        "task": "apple"
    }
    
    #头部信息:
    [root@localhost opt]# curl -i http://127.0.0.1:5000/Todo3
    HTTP/1.0 201 CREATED
    Content-Type: application/json
    Content-Length: 30
    Etag: some-opaque-string
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Tue, 15 Oct 2019 16:41:31 GMT
    
    {
        "task": "Hello world"
    }
    
    4、多个URL访问同一个源:
    
    from flask import Flask
    from flask_restful import Resource, Api
    
    app = Flask(__name__)
    api = Api(app)
    
    class HelloWorld(Resource):
        def get(self):
            return {'hello': 'world'}
    
    api.add_resource(HelloWorld, '/', '/hello')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    ##测试:
    
    [root@localhost opt]# curl http://127.0.0.1:5000/
    {
        "hello": "world"
    }
    [root@localhost opt]# curl http://127.0.0.1:5000/hello
    {
        "hello": "world"
    }
    
    5、上一讲的为例,改造这个模块:
    [root@localhost opt]# cat test_rest.py 
    from flask import Flask,abort, make_response, request
    from flask_restful import Resource, Api
    
    app = Flask(__name__)
    api = Api(app)
    
    tasks = [
        {
            'id': 1,
            'title': u'Buy groceries',
            'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
            'done': False
        },
        {
            'id': 2,
            'title': u'Learn Python',
            'description': u'Need to find a good Python tutorial on the web',
            'done': False
        }
    ]
    
    class TaskListAPI(Resource):
        def get(self):
            return jsonify({'tasks': tasks})
    
        def post(self):
            if not request.json or not 'title' in request.json:
                abort(400)
                task = {
                   'id': tasks[-1]['id'] + 1,
                   'title': request.json['title'],
                   'description': request.json.get('description', ""),
                   'done': False
                }
                tasks.append(task)
                return jsonify({'task': task}), 201
    
    
    class TaskAPI(Resource):
        def get(self, id):
            if id:
                task = [i for i in tasks if i['id']==id] 
                if len(task) == 0:
                    abort(404)
                return jsonify({'task': task})
    
        def put(self, id):
            task = [i for i in tasks if i['id']==id]
            if len(task) == 0:
                abort(404)
            if not request.json:
                abort(400)
            if 'title' in request.json and type(request.json['title']) != unicode:
                abort(400)
            if 'description' in request.json and type(request.json['description']) is not unicode:
                abort(400)
            if 'done' in request.json and type(request.json['done']) is not bool:
                abort(400)
            task[0]['title'] = request.json.get('title', task[0]['title'])
            task[0]['description'] = request.json.get('description', task[0]['description'])
            task[0]['done'] = request.json.get('done', task[0]['done'])
            return jsonify({'task': task})
    
    
        def delete(self, id):
            task = [i for i in tasks if i['id']==id]
            if len(task) == 0:
                abort(404)
            tasks.remove(task[0]) 
            return jsonify({'result': True})
    
    api.add_resource(TaskListAPI, '/devops/api/v1.0/tasks', endpoint = 'tasks')
    api.add_resource(TaskAPI, '/devops/api/v1.0/tasks/<int:id>', endpoint = 'task')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    ##测试:
    
    [root@localhost opt]# curl -i -X GET http://localhost:5000/devops/api/v1.0/tasks/1
    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 162
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 02:03:38 GMT
    
    {
      "task": [
        {
          "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
          "done": false, 
          "id": 1, 
          "title": "Buy groceries"
        }
      ]
    }
    [root@localhost opt]# curl -i -X GET http://localhost:5000/devops/api/v1.0/tasks
    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 317
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 02:03:40 GMT
    
    {
      "tasks": [
        {
          "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
          "done": false, 
          "id": 1, 
          "title": "Buy groceries"
        }, 
        {
          "description": "Need to find a good Python tutorial on the web", 
          "done": false, 
          "id": 2, 
          "title": "Learn Python"
        }
      ]
    }
    ###POST:
    [root@localhost opt]#  curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000/devops/api/v1.0/tasks
    HTTP/1.0 201 CREATED
    Content-Type: application/json
    Content-Length: 105
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 02:04:23 GMT
    
    {
      "task": {
        "description": "", 
        "done": false, 
        "id": 3, 
        "title": "Read a book"
      }
    }
    [root@localhost opt]# curl -i -X GET http://localhost:5000/devops/api/v1.0/tasks
    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 424
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 02:04:29 GMT
    
    {
      "tasks": [
        {
          "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
          "done": false, 
          "id": 1, 
          "title": "Buy groceries"
        }, 
        {
          "description": "Need to find a good Python tutorial on the web", 
          "done": false, 
          "id": 2, 
          "title": "Learn Python"
        }, 
        {
          "description": "", 
          "done": false, 
          "id": 3, 
          "title": "Read a book"
        }
      ]
    }
    
    ##PUT和DELETE:
    [root@localhost opt]# curl -i -H "Content-Type: application/json" -X PUT -d '{"done":true}' http://localhost:5000/devops/api/v1.0/tasks/2
    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 171
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 02:05:23 GMT
    
    {
      "task": [
        {
          "description": "Need to find a good Python tutorial on the web", 
          "done": true, 
          "id": 2, 
          "title": "Learn Python"
        }
      ]
    }
    
    
    ##DELETE:
    
    [root@localhost opt]# curl -i -X DELETE http://localhost:5000/devops/api/v1.0/tasks/3
    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 21
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 02:06:25 GMT
    
    {
      "result": true
    }
    [root@localhost opt]# curl -i -X GET http://localhost:5000/devops/api/v1.0/tasks
    HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 316
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 02:06:27 GMT
    
    {
      "tasks": [
        {
          "description": "Milk, Cheese, Pizza, Fruit, Tylenol", 
          "done": false, 
          "id": 1, 
          "title": "Buy groceries"
        }, 
        {
          "description": "Need to find a good Python tutorial on the web", 
          "done": true, 
          "id": 2, 
          "title": "Learn Python"
        }
      ]
    }
    
    
    ###但是我们发现在POST和PUT定义参数的时候又臭又长,这个时候,我们需要一个检查机制,Flask-RESTful 提供了一个更好的方式来处理数据验证,它叫做 RequestParser 类。这个类工作方式类似命令行解析工具 argparse。
    
    class TaskListAPI(Resource):
        def __init__(self):
            self.reqparse = reqparse.RequestParser()
            self.reqparse.add_argument('title', type = str, required = True,
                help = 'No task title provided', location = 'json')
            self.reqparse.add_argument('description', type = str, default = "", location = 'json')
            super(TaskListAPI, self).__init__()
    
     def __init__(self):
            self.reqparse = reqparse.RequestParser()
            self.reqparse.add_argument('title', type = str, location = 'json')
            self.reqparse.add_argument('description', type = str, location = 'json')
            self.reqparse.add_argument('done', type = bool, location = 'json')
            super(TaskAPI, self).__init__()
    
    
    ###PUT请求直接解析数据:
        def put(self, id):
            task = [i for i in tasks if i['id']==task_id]
            if len(task) == 0:
                abort(404)
            task=task[0]
            args = self.reqparse.parse_args()
            for k, v in args.iteritems():
                if v != None:
                    task[k] = v
            return jsonify({'task': task})
    
    ##验证:
    [root@localhost ~]# curl -i -H "Content-Type: application/json" -X POST -d '{"test":"Read a book"}' http://localhost:5000/devops/api/v1.0/tasks
    HTTP/1.0 400 BAD REQUEST
    Content-Type: application/json
    Content-Length: 69
    Server: Werkzeug/0.15.6 Python/3.6.4
    Date: Wed, 16 Oct 2019 14:02:48 GMT
    
    {
        "message": {
            "title": "No task title provided"
        }
    }
    
    
    ##POST请求修改:
        def post(self):
            args = self.reqparse.parse_args()
            task = {
                'id': tasks[-1]['id'] + 1,
                 'title': args.get('title',''),
                 'description': args.get('description', ""),
                 'done': False
              }
            tasks.append(task)
            return jsonify({'tasks':tasks})
    
    #########总体文件:
    
    [root@localhost opt]# cat test_rest.py 
    from flask import Flask,abort, make_response, request,jsonify
    from flask_restful import Resource, Api, reqparse
    
    app = Flask(__name__)
    api = Api(app)
    
    tasks = [
        {
            'id': 1,
            'title': u'Buy groceries',
            'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
            'done': False
        },
        {
            'id': 2,
            'title': u'Learn Python',
            'description': u'Need to find a good Python tutorial on the web',
            'done': False
        }
    ]
    
    class TaskListAPI(Resource):
        def __init__(self):
            self.reqparse = reqparse.RequestParser()
            self.reqparse.add_argument('title', type = str, required = True,help = 'No task title provided', location = 'json')
            self.reqparse.add_argument('description', type = str, default = "", location = 'json')
            super(TaskListAPI, self).__init__()
    
        def get(self):
            return jsonify({'tasks': tasks})
    
        def post(self):
            args = self.reqparse.parse_args()
            task = {
                'id': tasks[-1]['id'] + 1,
                 'title': args.get('title',''),
                 'description': args.get('description', ""),
                 'done': False
              }
            tasks.append(task)
            return jsonify({'tasks':tasks})
    
    
    class TaskAPI(Resource):
        def __init__(self):
            self.reqparse = reqparse.RequestParser()
            self.reqparse.add_argument('title', type = str, location = 'json')
            self.reqparse.add_argument('description', type = str, location = 'json')
            self.reqparse.add_argument('done', type = bool, location = 'json')
            super(TaskAPI, self).__init__()
    
        def get(self, id):
            if id:
                task = [i for i in tasks if i['id']==id] 
                if len(task) == 0:
                    abort(404)
                return jsonify({'task': task})
    
        def put(self, id):
            task = [i for i in tasks if i['id']==id]
            if len(task) == 0:
                abort(404)
            task=task[0]
            args = self.reqparse.parse_args()
            for k, v in args.items():
                if v != None:
                    task[k] = v
            return jsonify({'task': task})
    
    
        def delete(self, id):
            task = [i for i in tasks if i['id']==id]
            if len(task) == 0:
                abort(404)
            tasks.remove(task[0]) 
            return jsonify({'result': True})
    
    api.add_resource(TaskListAPI, '/devops/api/v1.0/tasks', endpoint = 'tasks')
    api.add_resource(TaskAPI, '/devops/api/v1.0/tasks/<int:id>', endpoint = 'task')
    
    
    
    if __name__ == '__main__':
        app.run(debug=True)
  • 相关阅读:
    如何更改 iOS 和安卓浏览器上的 input[type="radio"] 元素的默认样式?
    js获取样式、currentStyle和getComputedStyle的兼容写法
    js选中文字兼容性解决
    最短的IE判断var ie=!-[1,]分析
    总结oninput、onchange与onpropertychange事件的用法和区别
    jQuery工具函数
    Vnpy官网汇总
    Anaconda下各个Python版本下载地址
    APScheduler——定时任务框架
    PyQt5——隐藏控件并保留位置
  • 原文地址:https://www.cnblogs.com/edeny/p/12647560.html
Copyright © 2020-2023  润新知