flask - something more strict than @api.expect for input data?

两盒软妹~` 提交于 2020-12-28 07:50:53

问题


In my flask-restplus API I'd like not only to check that input data, like in the following example

resource_fields = api.model('Resource', {
    'name': fields.String(default = 'string: name', required = True),
    'state': fields.String(default = 'string: state'),
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    @api.expect(resource_fields, validate=True)
    def post(self):
        ...

must have 'name' field and may have 'state' field, but also to check that there are no other fields (and to raise an error if this happens). Is there another decorator for this? Can I check the correctness of the input data by a custom function?


回答1:


Instead of using a dictionary for your fields, try using a RequestParser (flask-restplus accepts both as documented here. That way, you can call parser.parse_args(strict=True) which will throw a 400 Bad Request exception if any unknown fields are present in your input data.

my_resource_parser = api.parser()
my_resource_parser.add_argument('name', type=str, default='string: name', required=True)
my_resource_parser.add_argument('state', type=str, default='string: state')

@api.route('/my-resource/<id>')
class MyResource(Resource):
    def post(self):
        args = my_resource_parser.parse_args(strict=True)
        ...

For more guidance on how to use the request_parser with your resource, check out the ToDo example app in the flask-restplus repo.




回答2:


Here is another answer to complete the one from @shiv. The following code snippet allows you to have your payload documented in the Swagger doc generated by Flask Restplus. Taken from the documentation about the expect decorator:

my_resource_parser = api.parser()
my_resource_parser.add_argument('name', type=str, default='string: name', required=True)
my_resource_parser.add_argument('state', type=str, default='string: state')

@api.route('/my-resource/<id>', endpoint='with-parser')
class MyResource(Resource):
    @api.expect(my_resource_parser)
    def post(self):
        args = my_resource_parser.parse_args(strict=True)
        ...



回答3:


For those that want to continue using the api.model rather than request parser, it's possible to iterate over your input (assuming list) versus the model. The model behaves like a dictionary.

from flask_restplus import abort

def check_exact(response_list, model):
    for response_dict in response_list:
        for key in response_dict:
            if key not in model:
                abort(400, "Non-specified fields added", field=key)

...

@ns.expect(my_model, validate=True)
def post(self, token):
    """Add new set of responses
    """
    check_exact(api.payload['responses'], my_model)
    ...


来源:https://stackoverflow.com/questions/41227736/flask-something-more-strict-than-api-expect-for-input-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!