- 安装
-
快速开始
- 初始化
-
一个最小API
- 面向资源(Resource)的路由
- 端点(Endpoint)
- 参数解析
- 数据格式化
安装
使用 pip
安装Flask-RESTPlus:
pip install flask-restplus
开发版可以从 Github 上下载:
git clone https://github.com/noirbizarre/flask-restplus.git
cd flask-restplus
pip install -e .[dev,test]
Flask-RESTPlus需要python 2.7, 3.3, 3.4 或 3.5支持。当然PyPy和PyPy3同样适用。
快速开始
本文档需要你对 Flask 的工作机制有所了解,同时请确保你已完成了Flask与Flask-RESTPlus的安装工作。如果没有完成安装,请参阅 安装。
初始化
和其他Flask扩展一样,你可以用 applicaiton 对象初始化它:
from flask import Flask
from flask_restplus import Api
app = Flask(__name__)
api = Api(app)
或者使用懒加载模式:
from flask import Flask
from flask_restplus import Api
api = Api()
app = Flask(__name__)
api.init_app(app)
一个最小API
一个最小的Flask-RESTPlus API 应该如下所示:
from flask import Flask
from flask_restplus import Resource, Api
app = Flask(__name__)
api = Api(app)
@api.route('/hello')
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
if __name__ == '__main__':
app.run(debug=True)
将上述代码保存为 api.py
并使用Python解释器运行。值得注意的是我们已经打开了Flask的调试模式(Flask debugging)这将为我们提供代码热重载和更好的报错信息。
$ python api.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader
警告:
调试模式不能用于任何生产环境下!
现在打开一个新窗口测试一下你的API:
$ curl http://127.0.0.1:5000/hello
{"hello": "world"}
你同时可以将自动文档作为你的API根目录(默认是开启的)。在本例子中,根目录为:http://127.0.0.1:5000/ 。查看 [Swagger UI](#Swagger UI) 章节获取完整信息。
面向资源(Resource)的路由
Flask-RESTPlus所能提供的主要组件由资源类(Resource)实现。资源类是在 Flask可扩展视图(Flask pluggable views) 的基础上实现的,提供了添加指定函数就能实现多种http访问方法的功能。一个实现代办事项(todo)应用程序的基础CURD(译者:就是增删改查的意思)资源类如下所示:
from flask import Flask, request
from flask_restplus import Resource, Api
app = Flask(__name__)
api = Api(app)
todos = {}
@api.route('/<string:todo_id>')
class TodoSimple(Resource):
def get(self, todo_id):
return {todo_id: todos[todo_id]}
def put(self, todo_id):
todos[todo_id] = request.form['data']
return {todo_id: todos[todo_id]}
if __name__ == '__main__':
app.run(debug=True)
测试一下:
$ curl http://localhost:5000/todo1 -d "data=Remember the milk" -X PUT
{"todo1": "Remember the milk"}
$ curl http://localhost:5000/todo1
{"todo1": "Remember the milk"}
$ curl http://localhost:5000/todo2 -d "data=Change my brakepads" -X PUT
{"todo2": "Change my brakepads"}
$ curl http://localhost:5000/todo2
{"todo2": "Change my brakepads"}
如果你的python安装了 python-requests 你也可以用python进行测试:
>>> 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-RESTPlus支持多种函数返回值。和 Flask 类似,你可以返回任意可迭代的对象(iterable)包括原生 Flask 响应对象(raw Flask response objects)而它们会被转化成响应(response)。Flask-RESTPlus同样支持使用多个返回值自定义状态码(response code)和响应头(response headers),示例如下:
class Todo1(Resource):
def get(self):
# Default to 200 OK
return {'task': 'Hello world'}
class Todo2(Resource):
def get(self):
# Set the response code to 201
return {'task': 'Hello world'}, 201
class Todo3(Resource):
def get(self):
# Set the response code to 201 and return custom headers
return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}
端点(Endpoint)
在很多情况下,一个API中,你的一个资源类可能需要对应多个url地址。你可以传入多个url地址到 add_resource() 函数中或者使用 route() 装饰器,这两个方法都由Api
对象提供。其中这的任意一个方法都能实现多url路由到你的资源类上:
api.add_resource(HelloWorld, '/hello', '/world')
# or
@api.route('/hello', '/world')
class HelloWorld(Resource):
pass
同时你也可以将一部分匹配路径作为变量传入你的资源类函数中:
api.add_resource(Todo, '/todo/<int:todo_id>', endpoint='todo_ep')
# or
@api.route('/todo/<int:todo_id>', endpoint='todo_ep')
class HelloWorld(Resource):
pass
提示:
如果请求无法匹配应用程序中的任何端点,Flask-RESTPlus 会返回404错误信息并附带最接近请求的端点猜测。你可以在配置文件中将
ERROR_404_HELP
改为False
来禁用这个功能。
参数解析
虽然 Flask 提供了很方便的途径访问请求数据(如:请求参数(querystring)或 POST表单数据(POST form encoded data)),但是验证表单数据依然很麻烦。Flask-RESTPlus提供了内置的表单验证功能,具体由一个类似于 argparse 的库完成。
from flask_restplus import reqparse
parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate to charge for this resource')
args = parser.parse_args()
提示:
和 argparse 不同的是,
parse_args()
返回的是一个Python字典对象,而不是一个自定义的数据结构
使用 RequestParser类同时也可以自动给你提供清晰的错误信息。如果一个参数在验证过程中出现问题,Flask-RESTPlus 将返回一个400错误并高亮错误。
$ curl -d 'rate=foo' http://127.0.0.1:5000/todos
{'status': 400, 'message': 'foo cannot be converted to int'}
input
模块提供了大量转化函数,如 date() 和 url() 。
调用 parse_args() 时附带参数 stict=True
,程序将在表单中出现解析器(parser)未定义的参数时抛出异常。
args = parser.parse_args(strict=True)
数据格式化
在默认情况下,你返回的所有可迭代对象将会被按照原样呈现。在针对Python原生数据结构时这种策略能够很好的完成任务,但是在处理对象时效果令人沮丧。为了解决这个问题,Flask-RESTPlus 提供了 **字段(Field)**模块和 **marshal_with()**装饰器。和 Django ORM 与 WTForm 类似,你可以使用 字段(fields)
模块来定义你的响应数据结构。
from collections import OrderedDict
from flask import Flask
from flask_restplus import fields, Api, Resource
app = Flask(__name__)
api = Api(app)
model = api.model('Model', {
'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'
@api.route('/todo')
class Todo(Resource):
@api.marshal_with(model)
def get(self, **kwargs):
return TodoDao(todo_id='my_todo', task='Remember the milk')
上面的例子我们拿了一个Python对象并准备将其序列化。 marlshal_with() 装饰器将会将其通过 model
进行转化。 fields.Url 字段是个很特别的字段,他将选取一个端点在响应中生成带该端点的URL。使用 marlshal_with() 同时也会为文档添加Swagger格式的文档内容。大部分字段类型已经预定义过。查看 字段(fields)
导航获取完整列表。
指令保存
在默认情况下,字段指令(fields order)并不会被保存,因为这将影响性能。如果你任然希望字段指令被保存,你可以通过添加参数 ordered=True
在某些类或者函数上进行强制保存:
-
在Api上全局设置:
api = Api(ordered=True)
-
在 命名空间(Namespace) 上全局设置:
ns = Namespace(ordered=True)
-
使用 marshal() 局部设置:return marshal(data, fields, ordered=True)
Comments 0