Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 677
user1403546 Avatar asked Dec 19 '16 17:12

user1403546


2 Answers

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.

like image 138
shiv Avatar answered Sep 20 '22 18:09

shiv


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)
        ...
like image 25
Alexis.Rolland Avatar answered Sep 22 '22 18:09

Alexis.Rolland