如何使用 flask restplus 验证 POST 有效负载中的日期类型?

How to validate date type in POST payload with flask restplus?

考虑以下几点:

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

app = Flask(__name__)
api = Api(app)
ns = api.namespace('ns')

payload = api.model('Payload', {
    'a_str': fields.String(required=True),
    'a_date': fields.Date(required=True)
})

@ns.route('/')
class AResource(Resource):

    @ns.expect(payload)
    def post(self):
        pass

如果我 POST {"a_str": 0, "a_date": "2000-01-01"} 我按预期得到 400, 因为 a_str 不是字符串。 但是,当我 POST {"a_str": "str", "a_date": "asd"} 我没有得到 400。 这里我也想得到 400,因为 "asd" 不是常见的日期格式。

我查看了 Date class doc 并且 我看到有一个 format 和一个 parse 方法应该检查字符串是否采用通用日期格式。 不过这里好像没有叫的。

还有其他方法吗? 目前我正在手动验证日期格式,但似乎 fask restplus 应该能够为我做这件事。

正如@andilabs 所提到的,两次定义预期有效载荷真的很奇怪。您可以仅使用 RequestParser 来定义预期的有效负载,如下所示:

from flask import Flask, jsonify
from flask_restplus import Api, Resource, fields, reqparse, inputs

app = Flask(__name__)
api = Api(app)
ns = api.namespace('ns')

parser = reqparse.RequestParser()
parser.add_argument('a_str', type=str)
parser.add_argument('a_date', type=inputs.datetime_from_iso8601, required=True)


@ns.route('/')
class AResource(Resource):

    @ns.expect(parser)
    def get(self):

        try:  # Will raise an error if date can't be parsed.
            args = parser.parse_args()  # type `dict`
            return jsonify(args)
        except:  # `a_date` wasn't provided or it failed to parse arguments.
            return {}, 400


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

使用curl进行测试:

$ curl -XGET -H "Content-type: application/json" -d '{"a_str": "Name", "a_date": "2012-01-01"}' 'http://127.0.0.1:5000/ns/'
{
  "a_date": "Sun, 01 Jan 2012 00:00:00 GMT", 
  "a_str": "Name"
}

要验证你可以添加参数验证:

@ns.expect(payload, validate=True)

这里是 link 文档: https://flask-restplus.readthedocs.io/en/stable/swagger.html#the-api-expect-decorator

第 1 步:pip install isodate

第 2 步:pip install strict-rfc3339

第 3 步:

from jsonschema import FormatChecker
api = Api(your_app,format_checker=FormatChecker(formats=("date-time",)))

第 4 步:

@api.expect(your_fields, validate=True)

参考: 未决问题:https://github.com/noirbizarre/flask-restplus/issues/204