官网
https://flask-restful.readthedocs.io/en/latest/ 1 安装

pip install flask-restful

2 小demo

from flask import Flask,request
from flask_restful import Api, Resource

app = Flask(__name__)

api = Api(app)  # 初始化得到 api 对象

class HelloRESTful(Resource):
    def get(self):
        return {'greet': 'Hello Flask RESTful!'}

api.add_resource(HelloRESTful, '/')


# 初始化待办列表
todos = {
  'todo_1': "读《程序员的自我修养》",
  'todo_2': "买点吃的",
  'todo_3': "去看星星"
}
class Todo(Resource):
    # 根据 todo_id 获取代办事项
    def get(self, todo_id):
        return { todo_id: todos[todo_id] }
    #获取post的数据并返回
    def post(self):
        return request.get_json(force=True)

    # 新增一个待办事项
    def put(self,todo_id):
        # todos[todo_id] = request.form['data']
        todos[todo_id]=request.get_json(force=True)
        return {todo_id: todos[todo_id]}
from flask_restful import reqparse  # 引入 reqparse 模块
# ...

parser = reqparse.RequestParser()  # 定义全局的解析实体
# 定义参数 id,类型必须是整数
parser.add_argument('id', type=int, help='必须提供参数 id')
# 定义参数 name,且为必填
parser.add_argument('name', required=True)
# ...

class Reqparser(Resource):
    def get(self):
        args = parser.parse_args()  # 获取解析器中定义的参数 并校验
        return args

api.add_resource(Reqparser, '/reqparser/')  # 指定路由
api.add_resource(Todo, '/todo/<string:todo_id>/','/todo')
if __name__ == '__main__':   # 别忘了启动应用的代码
    app.run(port=500)
    #app.run(debug=True)
    自定义端口号
    #app.run(host=,port=)

上面代码中从 flask_restful 中引入的 Resource 类是用来定义资源的,具体资源必须是 Resource 的子类
接着,通过api.add_resource给资源绑定 URI

在终端或者命令行下运行 python test.py 启动应用

访问 localhost:5000 或者 127.0.0.1:5000 查看效果,将会看到 JSON 格式的数据输出:

请求解析
官网 RESTful 服务器对请求数据有很强的依赖,就请求数据的获取及校验是很繁琐的事情,还好 Flask-RESTful 提供了非常好的请求解析工具 reqparse,不仅可以获取请求数据,还可以对数据进行校验并返回合适的错误消息。

from flask_restful import reqparse,Api,Resource  # 引入 reqparse 模块
from flask import Flask
# ...
app=Flask(__name__)

parser = reqparse.RequestParser()  # 定义全局的解析实体
# 定义参数 id,类型必须是整数
parser.add_argument('id', type=int, help='必须提供参数 id')
# 定义参数 name,且为必填
parser.add_argument('name', required=True,help='必须提供参数 id')
# ...


@app.route('/reqparser',methods = 'POST')
def get():
    args = parser.parse_args()  # 获取解析器中定义的参数 并校验
    return args



if __name__ == '__main__':   # 别忘了启动应用的代码
    app.run(port=5000)
看下效果:

# 提供一个非整数参数 id
 curl http://localhost:5000/reqparser/ -d "id=noint"
{
    "message": {
        "id": "\u53c2\u6570 id \u5fc5\u987b\u662f\u6574\u6570"
    }
}

# 不提供参数 name
curl http://localhost:5000/reqparser/
{
    "message": {
        "name": "Missing required parameter in the JSON body or the post body or the query string"
    }
}
  • 当参数校验失败,自动返回 400 状态码,以及错误信息,通过命名参数 help 设置错误信息,不提供会有默认信息,如比选参数 name
    的错误信息。
  • 默认情况下有多个参数错误,会以定义参数的顺序,逐个显示错误,定义解析器时将 bundle_errors 设置为
    True,则可显示多个错误,如 parser =
    reqparse.RequestParser(bundle_errors=True),或者设置应用配置,如
    app.config[‘BUNDLE_ERRORS’] = True
  • 默认情况下参数都是从请求表单中获取,定义参数时命名参数 location 可以指定从 form、headers、args(即
    querystring)还是从 cookies 等中获取,如 parser.add_argument(‘id’, type=int,
    help=‘必须提供参数 id’, location=‘args’)
    请求解析器支持继承,可以定义最高级别的解析器,逐渐细化,最后应用的具体资源上:
from flask_restful import reqparse

parser = reqparse.RequestParser()
parser.add_argument('foo', type=int)

parser_copy = parser.copy()  # 继承
parser_copy.add_argument('bar', type=int)  # parser_copy 将有两个参数

# 改变继承来的参数 foo 必填且的获取位置为 querystring
parser_copy.replace_argument('foo', required=True, location='args')

# 删除继承来的参数 foo
parser_copy.remove_argument('foo')

格式化输出
请求解析处理用收到的信息,对于输入的信息也可以处理,通过 Flask-RESTful 提供的类 fields 和注解 marshal_with 来实现:

from flask_restful import Resource, fields, marshal_with

resource_fields = {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
}

class TodoFormat(Resource):
    @marshal_with(resource_fields, envelope='resource')
    def get(self):
        return db_get_todo()  # 某个获得待办事项的方法

定义一个字段格式化模板,属性用 fields 的类型方法定义
在响应方法上加上 marshal_with 注解,指定格式化模板,和封装属性名
格式化模板属性名,需要在响应函数返回的对象属性中匹配,如果需要会要对字段重命名,可以这样:

fields = {
 # name 将被重命名为 private_name
 ‘name’: fields.String(attribute=‘private_name’),
 ‘address’: fields.String
 }


返回值中没有可以定义默认值:

fields = {
 # 为 name 设置默认值
 ‘name’: fields.String(default=‘Anonymous User’),
 ‘address’: fields.String
 }