一、RESTful一个简单接口定义流程
from flask import Flask, request, jsonify, send_file
from flask_restful import Api, Resource
import settings
app = Flask(__name__)
app.config.from.object(settings)
# 步骤一:创建Api对象
api = Api(app=app)
# 步骤二:定义Resource子类
class UserResource(Resource):
def get(self):
user = {'name':'lisa','age':18}
return jsonify(user)
def post(self):
pass
def put(self):
pass
def delete(self):
pass
# 步骤三:绑定路由
api.add_resource(UserResource,'/user')
if __name__ == '__main__':
app.run()
二、终端调试接口
安装了 requests 库的话,可以从 python shell 中调试接口:
>>> from requests import put, get
>>> put('http://localhost:5000/todo1', data={'data': 'Remember the milk'}).json()
{u'todo1': u'Remember the milk'}
>>> get('http://localhost:5000/todo1').json()
{u'todo1': u'Remember the milk'}
>>> put('http://localhost:5000/todo2', data={'data': 'Change my brakepads'}).json()
{u'todo2': u'Change my brakepads'}
>>> get('http://localhost:5000/todo2').json()
{u'todo2': u'Change my brakepads'}
三、Flask-RESTful 支持视图方法多种类型的返回值。
class Todo1(Resource):
def get(self):
# 默认为200 OK
return {'task': 'Hello world'}
class Todo2(Resource):
def get(self):
# 将响应代码设置为201
return {'task': 'Hello world'}, 201
class Todo3(Resource):
def get(self):
# 将响应代码设置为201并返回自定义头信息
return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}
四、端点(Endpoints)
很多时候在一个 API 中,你的资源可以通过多个 URLs 访问。
把多个 URLs 传给 Api 对象的 Api.add_resource() 方法。
每一个 URL 都能访问到你的 Resource。
为你的资源方法指定 endpoint 参数。
api.add_resource(Todo,'/todo/<int:todo_id>', endpoint='todo_ep')
五、参数解析
目的:验证表单数据
Flask-RESTful 内置了支持验证请求数据,它使用了一个类似 argparse 的库。
from flask.ext.restful import reqparse
parser = reqparse.RequestParser() # parser对象用于解析对象
parser.add_argument('名称', type='类型', help='帮助信息',required=True,location=['form','args'])
# required 是否必填项
# location 限制请求方法
# 一般在函数内部取请求携带的参数时使用
args = parser.parse_args() # 返回结果是一个字典,函数中依次取值。
args = parser.parse_args(strict=True)
# 使用 strict=True 调用 parse_args 能够确保当请求包含你的解析器中未定义的参数的时候会抛出一个异常。
# 注意
# reqparse.RequestParser.parse_args() 返回一个 Python 字典而不是一个自定义的数据结构。
六、数据格式化
1、使用装饰器格式化@marshal_with()
Flask-RESTful 提供了 fields 模块和 marshal_with() 装饰器。
你可以使用 fields 模块来在你的响应中格式化结构。
from collections import OrderedDict
from flask.ext.restful import fields, marshal_with
resource_fields = {
'task': fields.String,
'uri': fields.Url('todo_ep')
}
class TodoDao(object):
def __init__(self, todo_id, task):
self.todo_id = todo_id
self.task = task
# This field will not be sent in the response
self.status = 'active'
class Todo(Resource):
@marshal_with(resource_fields) # 格式化返回结果
def get(self, **kwargs):
return TodoDao(todo_id='my_todo', task='Remember the milk') # 必须返回一个对象,自动格式化
@marshal_with进阶数据格式化 ——返回一个对象进行格式化
from flask import Flask, request, jsonify, send_file
from flask_restful import Api, Resource, reqparse
from flask_restful import fields, marshal_with
import settings
app = Flask(__name__)
app.config.from_object(settings)
# 第一步:创建api对象
api = Api(app=app)
# 参数解析
parser = reqparse.RequestParser()
parser.add_argument('name', type=str)
parser.add_argument('age', type=str)
# 具体单个信息格式转化
result_fields = {
'name': fields.String,
'age': fields.String,
}
# 整体数据返回格式化
user_info = {
'info': fields.String,
'user': fields.Nested(result_fields) # 把具体的单个对象包含进来格式化
}
# 第二步:Resource子类
class UserResource(Resource):
def get(self):
print(request)
return send_file(r'./test')
@marshal_with(user_info) # 这里使用想要返回数据所定义的格式对象
def post(self):
print(request.values)
args = parser.parse_args()
result = Result(args.get('name'), args.get('age'))
print(result)
return {'info': '用户信息', 'user': result}
# 创建一个用户对象
class Result():
def __init__(self, name, age):
self.name, self.age = name, age
def __str__(self):
return self.name
# 第三步:绑定路由
api.add_resource(UserResource, '/user')
# 运行脚本
if __name__ == '__main__':
app.run()
marshal_with进阶数据格式化 ——返回对象列表进行格式化
from flask import Flask, request, jsonify, send_file
from flask_restful import Api, Resource, reqparse
from flask_restful import fields, marshal_with
import settings
# 提前创建一个对象存储列表
li = list()
app = Flask(__name__)
app.config.from_object(settings)
# 第一步:创建api对象
api = Api(app=app)
# 参数解析
parser = reqparse.RequestParser()
parser.add_argument('name', type=str)
parser.add_argument('age', type=str)
# 仅仅返回对象数据
result_fields = {
'name': fields.String,
'age': fields.String,
}
# 添加额为的说明信息和状态码
user_info = {
'info': fields.String,
'start':fields.String,
'user': fields.Nested(result_fields)
}
# 所有用户列表格式化数据返回结果
user_info_list = {
'user_list_info': fields.String,
'start':fields.String,
'user_list': fields.List(fields.Nested(result_fields)),
}
# 第二步:Resource子类
class UserResource(Resource):
def get(self):
print(request)
return send_file(r'./test')
@marshal_with(user_info_list)
def post(self):
print(request.values)
args = parser.parse_args()
result = Result(args.get('name'), args.get('age'))
li.append(result)
return {'user_list_info':'所有的用户信息','start':'200 ok','user_list':li}
class Result():
def __init__(self, name, age):
self.name, self.age = name, age
def __str__(self):
return self.name
# 第三步:绑定路由
api.add_resource(UserResource, '/user')
if __name__ == '__main__':
app.run()
2、不使用装饰器格式化输出
from flask import Flask, request, jsonify, send_file
from flask_restful import Api, Resource, reqparse, marshal
from flask_restful import fields, marshal_with
import settings
li = list()
app = Flask(__name__)
app.config.from_object(settings)
# 第一步:创建api对象
api = Api(app=app)
# 参数解析
parser = reqparse.RequestParser()
parser.add_argument('name', type=str)
parser.add_argument('age', type=str)
# 仅仅返回对象数据
result_fields = {
'name': fields.String,
'age': fields.String,
}
# 添加额为的说明信息和状态码
user_info = {
'info': fields.String,
'start':fields.String,
'user': fields.Nested(result_fields)
}
# 所有用户列表格式化数据返回结果
user_info_list = {
'user_list_info': fields.String,
'start':fields.String,
'user_list': fields.List(fields.Nested(result_fields)),
}
# 第二步:Resource子类
class UserResource(Resource):
def get(self):
print(request)
return send_file(r'./test')
def post(self):
print(request.values)
args = parser.parse_args()
result = Result(args.get('name'), args.get('age'))
li.append(result)
data = {'user_all': 'all', 'start': '200 ok', 'user_list': li}
return marshal(data, user_info_list)
class Result():
def __init__(self, name, age):
self.name, self.age = name, age
def __str__(self):
return self.name
# 第三步:绑定路由
api.add_resource(UserResource, '/user')
if __name__ == '__main__':
app.run()