Python 规则验证

Python 规则验证,python,rest,flask,Python,Rest,Flask,我需要在使用Flask-reab构建的REST API中验证Flask规则。我尝试了以下方法: @registry.handles( rule='/horses/<int:horse_id>', method='GET', marshal_schema=GetHorseByIdSchema() ) def getHorseById(horse_id): return {"horse_id": horse_id} @registry.handles(

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

@registry.handles(
    rule='/horses/<int:horse_id>',
    method='GET',
    marshal_schema=GetHorseByIdSchema()
)
def getHorseById(horse_id):
    return {"horse_id": horse_id}
@registry.handles(
规则=“/horses/”,
方法='GET',
marshal_schema=GetHorseByIdSchema()
)
def getHorseById(马的id):
返回{“horse_id”:horse_id}
这是使用指定的
语法。当输入整数值作为
horse\u id
时,一切正常。问题来自输入非整数值,即
a
;这会在我期待
400错误请求时抛出
404notfound
状态代码

我不认为我可以使用任何编组模式来实现这一点,因此我不确定下一步要尝试什么,非常感谢您的帮助

谢谢,
Adam

这是Flask/Werkzeug的行为方式,因此它有点超出Flask钢筋的控制范围。也就是说,以下内容还将返回404 for
/horses/a

app = Flask(__name__)

@app.route('/horses/<int:horse_id>')
def getHorseById(horse_id):
    return str(horse_id)
app=Flask(\uuuuu name\uuuuuu)
@app.route(“/horses/”)
def getHorseById(马的id):
返回str(马匹id)
因此,以下是一些解决方法:

(1)自定义URL转换器:

这看起来像:

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}
导入烧瓶
从werkzeug.routing导入BaseConverter
StrictIntegerConverter类(BaseConverter):
定义到python(自身,值):
尝试:
返回int(值)
除值错误外:
烧瓶中止(400)
app=烧瓶。烧瓶(\uuuuu名称\uuuuuuu)
app.url\u map.converters['strict\u integer']=StrictIntegerConverter
@registry.handles(
规则=“/horses/”,
方法='GET',
marshal_schema=GetHorseByIdSchema()
)
def getHorseById(马的id):
返回{'horse\u id':horse\u 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}
来自flask\u rebar.errors导入请求
@registry.handles(
规则=“/horses/”,
方法='GET',
marshal_schema=GetHorseByIdSchema()
)
def getHorseById(马的id):
尝试:
马匹id=int(马匹id)
除值错误外:
raise BADDREQUEST('horse_id必须是整数')
返回{'horse\u id':horse\u 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>')
...
来自werkzeug.deconverter
标准文档D类转换器(单转换器):
通过
app.url\u map.converter['str\u documented\u as\u int']=StrDocumentedAsIntConverter
registry.swagger_generator.register_flask_converter_to_swagger_type('str_documented_as_int','int'))
@registry.handles(规则=“/horses/”)
...
(3)接受烧瓶/Werkzeug行为

根据您对400而不是404的需求程度,最实际的做法可能是什么都不做,只是屈服于Flask/Werkzeug的做法