Flask-Rebar规则验证

时间:2018-11-21 18:14:03

标签: python rest flask

我需要在使用Flask构建的REST API中验证Flask-Rebar规则。我尝试了以下方法:

@registry.handles(
    rule='/horses/<int:horse_id>',
    method='GET',
    marshal_schema=GetHorseByIdSchema()
)
def getHorseById(horse_id):
    return {"horse_id": horse_id}

这使用here指定的<int:my_var>语法。当输入整数值作为horse_id时,一切正常。问题来自输入非整数值,即a;当我期望404 Not Found时,它将抛出400 Bad Request状态代码。

我认为我无法使用任何编组模式进行此操作,因此我不确定下一步该怎么做,我们将提供任何帮助。

谢谢, 亚当

1 个答案:

答案 0 :(得分:1)

这是Flask / Werkzeug的行为方式,因此有点超出Flask-Rebar的控制范围。也就是说,以下代码还将返回/horses/a的404:

app = Flask(__name__)

@app.route('/horses/<int:horse_id>')
def getHorseById(horse_id):
    return str(horse_id)

有了这,这里是一些解决方法:

(1)自定义URL转换器:http://flask.pocoo.org/docs/1.0/api/#flask.Flask.url_map

这看起来像:

import flask
from werkzeug.routing import BaseConverter

class StrictIntegerConverter(BaseConverter):
    def to_python(self, value):
        try:
            return int(value)
        except ValueError:
            flask.abort(400)

app = flask.Flask(__name__)
app.url_map.converters['strict_integer'] = StrictIntegerConverter


@registry.handles(
    rule='/horses/<strict_integer:horse_id>',
    method='GET',
    marshal_schema=GetHorseByIdSchema()
)
def getHorseById(horse_id):
    return {'horse_id': horse_id}

但是,路由是在应用程序上下文之外完成的,因此我们不能使用flask.jsonify或Flask-Rebar的错误来引发不错的JSON错误。

(2)检查处理程序函数内部的类型

from flask_rebar.errors import BadRequest

@registry.handles(
    rule='/horses/<horse_id>',
    method='GET',
    marshal_schema=GetHorseByIdSchema()
)
def getHorseById(horse_id):
    try:
        horse_id = int(horse_id)
    except ValueError:
        raise BadRequest('horse_id must be an integer')
    return {'horse_id': horse_id}

这不太优雅,但可以。 Swagger文档将默认为horse_id参数的字符串类型,但我们也可以解决该问题:

from werkzeug.routing import UnicodeConverter

class StrDocumentedAsIntConverter(UnicodeConverter):
    pass

app.url_map.converters['str_documented_as_int'] = StrDocumentedAsIntConverter
registry.swagger_generator.register_flask_converter_to_swagger_type('str_documented_as_int', 'int')

@registry.handles(rule='/horses/<str_documented_as_int:horse_id>')
...

(3)接受Flask / Werkzeug行为

根据最需要400而不是404的需要,什么都不做,而只屈服于Flask / Werkzeug的工作方式,这可能是最实际的。