专栏首页测试开发社区Python的Flask框架开发RESTful API

Python的Flask框架开发RESTful API

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

更新任务:

作者:我为峰2014 链接:https://www.jianshu.com/p/ed1f819a7b58 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

本文分享自微信公众号 - 测试开发社区(TestDevHome)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 用Python拨打电话

    跟selenium操作浏览器原理类似,这是用appium操作移动设备的一个自动化功能,自娱自乐,主要是通过小案例引出相关技术

    测试开发社区
  • Android自动化环境搭建

    1.安装JDK,配置JDK环境变量。注意一下电脑是32位还是64位,需要与之对应。

    测试开发社区
  • ​性能优化指南:性能优化的一般性原则与方法

      作为一个程序员,性能优化是常有的事情,不管是桌面应用还是web应用,不管是前端还是后端,不管是单点应用还是分布式系统。本文从以下几个方面来思考这个问题:性能...

    测试开发社区
  • 使用Flask构建简单的RESTful服务

    我们现在的一个项目是使用Django来构建,说来也是基于技术扩展的考虑,我对于Django里面大而全的一些组件还是持有保守态度,所以虽然项目用了Djan...

    jeanron100
  • MyBatis学习总结(五)——实现关联表查询

    一枝花算不算浪漫
  • MyBatis 实现关联表查询

    一、一对一关联  1.1、提出需求   根据班级id查询班级信息(带老师的信息) 1.2、创建表和数据   创建一张教师表和班级表,这里我们假设一个老师只负责教...

    庞小明
  • Mybatid关联表查询

    一、一对一关联  1.1、提出需求   根据班级id查询班级信息(带老师的信息) 1.2、创建表和数据   创建一张教师表和班级表,这里我们假设一个老师只负...

    汤高
  • 浅谈CAS在分布式ID生成方案上的应用 | 架构师之路

    近几篇文章聊CAS被骂得较多,今天还是聊CAS,谈谈CAS在一种“分布式ID生成方案”上的应用。 所谓“分布式ID生成方案”,是指在分布式环境下,生成全局唯一I...

    架构师之路
  • [767]MongoDB聚合运算

    MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。

    周小董
  • 使用Oracle with内嵌视图优化一例

    用户1148526

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动