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)
本文来自博客园,作者:王竹笙,转载请注明原文链接:https://www.cnblogs.com/edeny/p/12647560.html
分类:
EOPS运维平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App