我思故我在我有我精彩--liangqihui

爱欲追而情已逝,子欲孝而亲不待。人生的困苦又怎能用一个难字囊尽百味
随笔 - 579, 文章 - 63, 评论 - 150, 阅读 - 127万
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

[转]python实现RESTful服务(基于flask)

Posted on   挥辉  阅读(3745)  评论(2编辑  收藏  举报

python实现RESTful服务(基于flask)

原文: https://www.jianshu.com/p/6ac1cab17929 

前言

上一篇文章讲到如何用java实现RESTful服务,这就来讲讲怎么用python来实现吧,因为要搭建一套java和python互调的服务,两者都不能少啊。
对于python的述求呢也是要轻量化,并且能快捷开发,因为我这套服务主要控制逻辑还是在java端,python这块负责一些工具逻辑,比如网页爬取、文字转拼音、图像处理等等,在java端当成工具类来使用,所以轻量和快捷开发就是重点了

web框架选择

java端需要选择一个web容器,同样的,python也需要选择一个web框架,当然自己实现一套也可以哈,不过本着【人生苦短,我用python】的原则,还是找框架吧

知乎上有一个讨论Python 有哪些好的 Web 框架?,从这个讨论中最后我选择了flask,原因是:

  • Django,流行但是笨重,还麻烦,人生苦短,肯定不选
  • web.py,轻量,但据说作者仙逝无人维护,好吧,先pass
  • tornado,据说倡导自己造轮子,虽然是facebook开源的吧,但听到这个,就算了吧
  • 还有一些其他的就不说了,直到看到一个人做了如下回复,就暂定了flask,再发现flask写RESTful居然超简单,于是就它了


    撸代码

    选定了flask框架,那就动手写代码咯


    安装flask

    pip install flask
    

    hello world

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # by vellhe 2017/7/9
    
    from flask import Flask
    
    # Flask初始化参数尽量使用你的包名,这个初始化方式是官方推荐的,官方解释:http://flask.pocoo.org/docs/0.12/api/#flask.Flask
    app = Flask(__name__)
    
    
    @app.route('/HelloWorld')
    def hello_world():
        return "Hello World!"
    
    
    if __name__ == "__main__":
        # 这种是不太推荐的启动方式,我这只是做演示用,官方启动方式参见:http://flask.pocoo.org/docs/0.12/quickstart/#a-minimal-application
        app.run(debug=True)
    

    注:代码里参见的官方文档都是英文的,也有一个不错的中文网站做了很好的翻译,可以在扎个上面找到很好的对应:
    http://www.pythondoc.com/flask/quickstart.html

    验证结果:

    PostMan验证


    PostMan验证

    浏览器打开


    浏览器打开

    完美!!!就这几行代码就实现了一个简单的网页,简直爽得不要不要的了


    简单的RESTful实现

    光实现一个简单网页可不是本事(毕竟python用SimpleHTTPServer都可以不用写代码),实现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)
    
    
    验证结果
    add_task
    get_task
    get_task by id

    以上是通过最原始的方式实现,没有使用flask的RESTful扩展库,就这种实现方式都已经非常给力了,这么一点代码就搞定了RESTful服务,真的是人生苦短啊,但这真的就完美了吗?
    答案肯定是no啦~ 必须要试试flask的RESTful扩展库才知道什么叫真正的爽啊


    使用flask的RESTful扩展库 flask-restful

    强烈建议参考官方文档(因为下面我也是照搬不误):http://flask-restful.readthedocs.io/en/0.3.5/quickstart.html#a-minimal-api

    安装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')
    
    
    # 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
    
    
    # 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
    
    
    ##
    ## Actually setup the Api resource routing here
    ##
    api.add_resource(TodoList, '/todos')
    api.add_resource(Todo, '/todos/<todo_id>')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    验证结果

    查询列表:


    get

    查询单任务:


    get by id

    删除任务:
    delete by id

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


    add

    更新任务:
    update
    flask-restful框架使用总结

    这个框架用Resource类将封装好了http的各种请求,只需定义一下对应的函数即可,返回值也是可以直接丢对象过去,非常方便,写好接口类用API配置一下路径就搞定了

    后语

    Perfect!!!经过这一番测试,flask-restful完全满足了我的需求,框架轻量,开发方便,以class为单位去开发我的各个接口给到java调用,果然是【人生苦短,我用python】啊~

    编辑推荐:
    · 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
    · .NET Core 中如何实现缓存的预热?
    · 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
    · AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
    · 基于Microsoft.Extensions.AI核心库实现RAG应用
    阅读排行:
    · 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
    · 地球OL攻略 —— 某应届生求职总结
    · 提示词工程——AI应用必不可少的技术
    · Open-Sora 2.0 重磅开源!
    · 字符编码:从基础到乱码解决
    点击右上角即可分享
    微信分享提示