Flask-RESTPlus 中文文档 - 1

645 0

  • 安装
  • 快速开始
    • 初始化
  • 一个最小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支持。当然PyPyPyPy3同样适用。

快速开始

本文档需要你对 Flask 的工作机制有所了解,同时请确保你已完成了FlaskFlask-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)

技术文章 Flask Flask Extension

TOPIC

Flask

关于Flask


Comments 0