【发布时间】:2020-08-21 23:00:27
【问题描述】:
在 flask-restplus API 中,我需要对请求 JSON 数据进行验证,其中我已经使用 api.model 定义了请求正文模式。基本上我想将输入 JSON 数据传递给 API 函数,在使用 API 函数之前我必须验证输入 JSON 数据。为此,我使用RequestParser 来执行此任务,但是在验证和解析请求 JSON 之后,API 函数期望正确的 JSON 数据作为参数。要进行请求 JSON 验证,首先我必须解析接收到的输入 JSON 数据,解析其 JSON 主体,验证每一个,然后将其重构为 JSON 对象,然后传递给 API 函数。有没有更简单的方法来做到这一点?
输入 JSON 数据
{
"body": {
"gender": "M",
"PCT": {
"value": 12,
"device": "roche_cobas"
},
"IL6": {
"value": 12,
"device": "roche_cobas"
},
"CRP": {
"value": 12,
"device": "roche_cobas"
}
}
}
我目前在烧瓶中的尝试
from flask_restplus import Api, Namespace, Resource, fields, reqparse, inputs
from flask import Flask, request, make_response, Response, jsonify
app = Flask(__name__)
api = Api(app)
ns = Namespace('')
feature = api.model('feature', {
'value': fields.Integer(required=True),
'time': fields.Date(required=True)
})
features = api.model('featureList', {
'age': fields.String,
'gender': fields.String(required=True),
'time': fields.Date,
'features': fields.List(fields.Nested(feature, required=True))
})
@ns.route('/hello')
class helloResource(Resource):
@ns.expect(features)
def post(self):
json_dict = request.json ## get input JSON data
## need to parse json_dict to validate expected argument in JSON body
root_parser = reqparse.RequestParser()
root_parser.add_argument('body', type=dict)
root_args = root_parser.parse_args()
jsbody_parser = reqparse.RequestParser()
jsbody_parser.add_argument('age', type=dict, location = ('body',))
jsbody_parser.add_argument('gender', type=dict, location=('body',))
## IL6, CRP could be something else, how to use **kwargs here
jsbody_parser.add_argument('IL6', type=dict, location=('body',))
jsbody_parser.add_argument('PCT', type=dict, location=('body',))
jsbody_parser.add_argument('CRP', type=dict, location=('body',))
jsbody_parser = jsbody_parser.parse_args(req=root_args)
## after validate each argument on input JSON request body, all needs to be constructed as JSON data
json_data = json.dumps(jsonify(jsbody_parser)) ## how can I get JSON again from jsbody_parser
func_output = my_funcs(json_data)
rest = make_response(jsonify(str(func_output)), 200)
return rest
if __name__ == '__main__':
api.add_namespace(ns)
app.run(debug=True)
更新:虚拟 api 函数
这是验证后需要 json 数据的虚拟函数:
import json
def my_funcs(json_data):
a =json.loads(json_data)
for k,v in a.iteritems():
print k,v
return jsonify(a)
上述尝试的当前输出:
我在响应正文中有这个:
{
"errors": {
"gender": "'gender' is a required property"
},
"message": "Input payload validation failed"
}
显然,请求 JSON 输入在我的尝试中没有得到处理和验证。我想我必须将 json_dict 传递给 RequestParser 对象,但仍然无法在此处验证请求 JSON。如何做到这一点?
我必须验证来自 JSON 主体的预期参数,在验证之后,我想构建将用作 API 函数参数的 JSON 主体。我怎样才能做到这一点?任何解决方法来实现这一点?
解析后的 JSON 必须传递给 my_funcs
在我的帖子中,请求 JSON 数据应该被解析,例如 age,gender 应该被验证为请求 JSON 中的预期参数,然后 jsonify 将添加的参数作为 JSON 并传递 my_funcs。如何在 fl 中轻松实现这一点
我想确保烧瓶应该解析 JSON 正文并按预期添加参数,否则会抛出错误。例如:
{
"body": {
"car": "M",
"PCT": {
"value": 12,
"device": "roche_cobas"
},
"IL6": {
"device": "roche_cobas"
},
"CRP": {
"value": 12
}
}
}
如果我提供像上面这样的 JSON 数据来向服务器端点发出 POST 请求,它应该会给出错误。如何做到这一点?如何验证烧瓶 API 调用的 POST 请求 JSON?
【问题讨论】:
-
你遇到过Marshmallow和Flask-Marshmallow吗?
-
@PGHE 不,我要做的是验证请求 JSON 正文,解析每个参数并将其重建为 json 并传递给函数。为什么你说棉花糖能帮上忙?你能详细说明吗?我说清楚了吗?
-
Marshmallow 可以根据您定义的模式加载 JSON 和 validate 数据。它还可以为您处理序列化和反序列化。
-
@PGHE 我试过了,但还是不行。你如何解决这个问题?你能根据我的尝试提供编码输入吗?如果您提供任何可行的解决方案,我们将不胜感激。
-
@PGHE 使用 Marshmallow 很好,但您的尝试没有解决 jyson 的问题。你试过用 flask_Marshmallow 代替吗?