一、起步:
Flask-RESTful 是用于快速构建REST API 的Flask扩展
1、安装RESTful
pip install flask-restful
2、Hello World示例
from flask import Flask from flask-restful import Resource, Api app = Flask(__name__) api = Api(app) class HelloWorldResource(Resource): def get(self): return {"hello": "world"} def post(self): return {"msg": "post hello world"} api.add_resource(HelloWorldResource, "/") # 下面对于1.0之后的Flask可有可无 if __name__ == "__main__": app.run(debug=True)
二、关于视图
1、为路由起名
通过endpoint参数为路由起名
api.add_resource(HelloWorldResource, "/", endpoint="HelloWorld")
2、蓝图中使用
from flask import Flask from flask_restful import Api, Resource app = Flask(__name__) user_bp = Blueprint("user", __name__) user_api = Api(user_bp) class UserProfileResource(Resource): def get(self): return {"msg": "get user profile"} user.add_resource(UserProfileResource, "/") app.register_blueprint(user_bp)
3 、装饰器
使用 method_decorators 添加装饰器
●为类视图中的所有方法添加装饰器
def decorator1(func): def wrapper(*args, **kwargs): print("decorator1") return func(*args, **kwargs) return wrapper def decorator2(func): def wrapper(*args, **kwargs): print("decorator2") return func(*args, **kwargs) return wrapper class DemoResource(Resource): method_decorators = [decorator1, decorator2]
def get(self): return {"msg": "get view"}
def post(self): return {"msg": 'post view'}
●为类视图中不同的方法添加不同的装饰器
class DemoResource(Resource): method_decorators = { "get": [decorator1, decorator2], "post": [decorator1] } # 使用了decorator1 decorator2两个装饰器 def get(self): return {"msg": "get view"} # 使用也decorator1 装饰器 def post(self): return {'msg': 'post view'} # 未使用装饰器 def put(self): return {'msg': 'put view'}
三、关于请求处理
Flask-RESTful 提供了 requestParser 类,用来帮助我们检验和转换请求数据。
from flask_restful import reqparse parser = reqparse.RequestParser() parser.add_argument('rate', type=int, help='Rate cannot be converted', location='args') parser.add_argument("name") args = parser.parse_args()
1、使用步骤
① 创建 RequestParser 对象
② 向 RequestParser 对象中添加需要检验或转换的参数声明
③ 使用 parse_args() 方法启动检验处理
④ 检验之后从检验结果中获取参数时可按照字典操作或对象属性操作
args.rate 或 args['rate']
2、参数说明
① required
描述请求是否一定要携带对应参数,默认值为False
●True 强烈要求携带,若未携带,则校验失败,向客户端返回错误信息,状态码400
●False 不强制要求携带,若不强烈携带,在客户端请求未携带参数时,取出值为 None
class DemoResource(Resource): def get(self): rp = RequestParser() rp.add_argument('a', required=False) args = rp.parse_args() return {'msg': 'data={}'.format(args.a)}
3、help
参数检验错误时返回的错误描述信息
rp.add_argument('a', required=True, help="missing a param")
4、action
描述对于请求参数中出现多个同名参数时的处理方式
● action='store' 保留出现的第一个,默认
● action="append" 以列表追加保存所有同名参数的值
rp.add_argumen('a', required=True, help="missing a param", action='append')
5、type
描述参数应该匹配的类型,可以使用 python 的标准数据类型 string、int,也可使用Flask-RESTFul提供的检验方式,还可以自己定义
●标准类型
rp.add_argument('a', type=int, required=True, help="missing a param", action="append")
● Flask-RESTFul提供
检验类型方法在 flask_restful.inputs 模块中
○ url
○ regex(指定正则表达式)
from flask_restful import inputs rp.add_argument('a', type=inputs.regex(r'^d{2}&'))
○ natural 自然数 0、1、2、3......
○ positive 正整数 1、2、3.....
○ int_range(low, high) 整数范围
rp.add_argument("a", type=inputs.int_range(1, 10))
○ boolean
● 自定义
def mobile(mobile_str): """ 检验手机号格式 :param mobile_str: str 被检验字符串 :return: mobile_str """ if re.match(r'^1[3-9]d{9}$', mobile_str): return mobile_str else: raise ValueError('{} is not a vaild mobile'.format(mobile_str)) rp.add_argument('a', type=mobile)
6、location
描述参数应该在请求数据中出现的位置
# Look only in the POST body parser.add_argument('name', type=int, location='form') # Look only in the querystring parser.add_argument('PageSize', type=int, location='args') # From the request headers parser.add_argument(User-Agent", location="headers") # From http cookies parser.add_argument("session_id", location="cookies") # From json parser.add_argument("user_id", location="json") # From file uploads parser.add_argument("picture", location="file")
也可指明多个位置
parser.add_argument("text", location=["headers", "json"])
四、关于响应处理
1、序列化数据
Flask-RESTful 提供了 marshal 工具,用来帮助我们将数据序列化特定格式的字典数据,以便作为视图的返回值。
from flask_restful import Resource, fields, marshal_with resource_fields = { "name": fields.String, "address": fields.String, "user_id": fields.Integer } class Todo(Resource): @marshal_with(resource_fields, envelope='resource') def get(self, **kwargs): return db_get_todo()
也可以不使用装饰器的方式
class Todo(Resource): def get(self, **kwargs): data = db_get_todo() return marshal(data, resource_fields)
示例