Flask-RESTPlus 中文文档 - 6

454 0

  • Swagger文档
    • 使用@api.doc()装饰器进行文档编辑
    • 模型自动记录
    • @api.marshal_with()装饰器
    • @api.expect()装饰器
    • 使用@api.response装饰器进行文档编辑
    • @api.route()装饰器
    • 对字段进行文档编写
    • 对函数进行文档编写
    • 级联(Cascading)
    • 已弃用标记
    • 隐藏文档
    • 文档授权(Documenting authorizations)
    • 展示支持信息(Expose vendor Extensions)
    • 导出Swagger格式
    • Swagger UI

Swagger UI

在默认情况下,Flask-RESTPlusAPI的根目录提供 Swagger UI 文档服务。

from flask import Flask
from flask_restplus import Api, Resource, fields

app = Flask(__name__)
api = Api(app, version='1.0', title='Sample API',
    description='A sample API',
)

@api.route('/my-resource/<id>')
@api.doc(params={'id': 'An ID'})
class MyResource(Resource):
    def get(self, id):
        return {}

    @api.response(403, 'Not Authorized')
    def post(self, id):
        api.abort(403)


if __name__ == '__main__':
    app.run(debug=True)

运行上面的代码并访问API的根目录(http://localhost:5000),你就能看到自动生成的Swagger UI文档。

个性化

你可以通过 doc 关键字配置 Swagger UI 的路径(默认为根目录):

from flask import Flask, Blueprint
from flask_restplus import Api

app = Flask(__name__)
blueprint = Blueprint('api', __name__, url_prefix='/api')
api = Api(blueprint, doc='/doc/')

app.register_blueprint(blueprint)

assert url_for('api.doc') == '/api/doc/'

你可以通过设定 config.SWAGGER_VALIDATOR_URL 来指定一个自定义的验证器地址(validator URL):

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
app.config.SWAGGER_VALIDATOR_URL = 'http://domain.com/validator'

api = Api(app)

您可以启用 OAuth2隐式流程(OAuth2 Implicit Flow) ,以获取用于在Swagger UI中交互测试api端点的授权令牌。 config.SWAGGER_UI_OAUTH_CLIENT_IDauthorizationUrlscopes 将用于指定你的OAuth2 IDP配置。 域字符串(realm string) 将会作为查询参数(query parameter) 添加到 授权地址(authorizationUrl) 和 凭证地址(tokenUrl)。这些值都是公开信息。此处未指定 客户端密钥(client secret)。使用PKCE代替隐式流取决于https://github.com/swagger-api/swagger-ui/issues/5348

from flask import Flask
app = Flask(__name__)

app.config.SWAGGER_UI_OAUTH_CLIENT_ID = 'MyClientId'
app.config.SWAGGER_UI_OAUTH_REALM = '-'
app.config.SWAGGER_UI_OAUTH_APP_NAME = 'Demo'

api = Api(
    app,
    title=app.config.SWAGGER_UI_OAUTH_APP_NAME,
    security={'OAuth2': ['read', 'write']},
    authorizations={
        'OAuth2': {
            'type': 'oauth2',
            'flow': 'implicit',
            'authorizationUrl': 'https://idp.example.com/authorize?audience=https://app.example.com',
            'clientId': app.config.SWAGGER_UI_OAUTH_CLIENT_ID,
            'scopes': {
                'openid': 'Get ID token',
                'profile': 'Get identity',
            }
        }
    }
)

你也可以通过修改 config.SWAGGER_UI_DOC_EXPANSION ('none', 'list''full') 来指定初期标签展开状态(the initial expansion state)。

from flask_restplus import Api

app = Flask(__name__)
app.config.SWAGGER_UI_DOC_EXPANSION = 'list'

api = Api(app)

默认情况下, 操作ID(operation ID)请求区间(request duration) 是影藏的,可以通过下面的方法分别启用它们:

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
app.config.SWAGGER_UI_OPERATION_ID = True
app.config.SWAGGER_UI_REQUEST_DURATION = True

api = Api(app)

如果你需要自定义UI,你可以通过 documentation() 修饰器来注册自定义视图:

from flask import Flask
from flask_restplus import Api, apidoc

app = Flask(__name__)
api = Api(app)

@api.documentation
def custom_ui():
    return apidoc.ui_for(api)

配置“试一试(Try it Out)”

默认情况下,所有的路径和方法都有一个“试一试(Try it Out)”按钮用于在浏览器中测试API。你可以通过修改 SWAGGER_SUPPORTED_SUBMIT_METHODS 的配置禁用任意一种Http方法,该参数支持符合 Swagger UI 参数(Swagger UI parameter)supportedSubmitMethods 参数的所有值。

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)

# disable Try it Out for all methods
app.config.SWAGGER_SUPPORTED_SUBMIT_METHODS = []

# enable Try it Out for specific methods
app.config.SWAGGER_SUPPORTED_SUBMIT_METHODS = ["get", "post"]

api = Api(app)

禁用文档

设置 doc=False 可以完全禁用文档。

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
api = Api(app, doc=False)

异常处理

Http异常处理

Werkzeug HTTP异常(Werkzeug HTTPException)将适当的自动重写描述(description)属性。

from werkzeug.exceptions import BadRequest
raise BadRequest()

上述代码将会返回一个400状态码和输出:

{
    "message": "The browser (or proxy) sent a request that this server could not understand."
}

而这段代码:

from werkzeug.exceptions import BadRequest
raise BadRequest('My custom message')

将会输出:

{
    "message": "My custom message"
}

你可以通过修改data属性值添加额外的参数到你的异常中:

from werkzeug.exceptions import BadRequest
e = BadRequest('My custom message')
e.data = {'custom': 'value'}
raise e

这将输出:

{
    "message": "My custom message",
    "custom": "value"
}

Flask终止助手

终止助手(abort helper) 适当的将错误封装成了一个 Http异常( HTTPException ) ,因此它们表现几乎相同。

from flask import abort
abort(400)

上述代码将会返回一个400状态码和输出:

{
    "message": "The browser (or proxy) sent a request that this server could not understand."
}

而这段代码:

from flask import abort
abort(400, 'My custom message')

将会输出:

{
    "message": "My custom message"
}

Flask-RESTPlus终止助手

errors.abort()Namespace.abort() 终止助手与原生Flask Flask.abort() 原理相似,但将会把关键字参数(keyword arguments)打包进响应中。

from flask_restplus import abort
abort(400, custom='value')

上述代码将会返回一个400状态码和输出:

{
    "message": "The browser (or proxy) sent a request that this server could not understand.",
    "custom": "value"
}

而这段代码:

from flask import abort
abort(400, 'My custom message', custom='value')

将会输出:

{
    "message": "My custom message",
    "custom": "value"
}

@api.errorhandler 装饰器

@api.errorhandler装饰器将为指定的异常(或继承于这个异常的任何异常)注册一个特别的处理机(handler),你也可以用同样的方法使用 Flask/Blueprint 的 @errorhandler装饰器。

@api.errorhandler(RootException)
def handle_root_exception(error):
    '''Return a custom message and 400 status code'''
    return {'message': 'What you want'}, 400


@api.errorhandler(CustomException)
def handle_custom_exception(error):
    '''Return a custom message and 400 status code'''
    return {'message': 'What you want'}, 400


@api.errorhandler(AnotherException)
def handle_another_exception(error):
    '''Return a custom message and 500 status code'''
    return {'message': error.specific}


@api.errorhandler(FakeException)
def handle_fake_exception_with_header(error):
    '''Return a custom message and 400 status code'''
    return {'message': error.message}, 400, {'My-Header': 'Value'}


@api.errorhandler(NoResultFound)
def handle_no_result_exception(error):
    '''Return a custom not found error message and 404 status code'''
    return {'message': error.specific}, 404

提示:

一个带有描述的“未找到结果(NoResultFound)”异常是 OpenAPI 2.0规范所规定的。处理机种的文档字符串(docstring)(译者:就是那坨三引号)将会被输出到swagger.json中作为描述。

你也可以专门为异常编写文档:

@api.errorhandler(FakeException)
@api.marshal_with(error_fields, code=400)
@api.header('My-Header',  'Some description')
def handle_fake_exception_with_header(error):
    '''This is a custom error'''
    return {'message': error.message}, 400, {'My-Header': 'Value'}


@api.route('/test/')
class TestResource(Resource):
    def get(self):
        '''
        Do something

        :raises CustomException: In case of something
        '''
        pass

在这个例子里,:raises:字符串将会被自动提取并填充至文档400错误处。

你只需要在使用时忽略参数,就可以重写默认的 errorhandler

@api.errorhandler
def default_error_handler(error):
    '''Default error handler'''
    return {'message': str(error)}, getattr(error, 'code', 500)

提示:

Flask-RESTPlus 默认会返回一个带消息的错误信息。如果你在自定义一个错误响应并且不需要消息字段的话,你可以在配置文件中将 ERROR_INCLUDE_MESSAGE 改为 False 以禁用消息字段。

errorhandler也可以在命名空间中注册。在命名空间中注册的处理机将会覆盖在 Api 中注册的处理机。

ns = Namespace('cats', description='Cats related operations')

@ns.errorhandler
def specific_namespace_error_handler(error):
    '''Namespace error handler'''
    return {'message': str(error)}, getattr(error, 'code', 500)
技术文章 Flask Flask Extension

TOPIC

Flask

关于Flask


Comments 0