Search code examples
pythonswagger-uiflask-restplus

String not callable exception raised when trying to use fields.String with enum in flask-restplus


I try to use req parser with a fields.String enum to display a nice dropdown in swagger:

seen_search_parser = api.parser()
seen_search_parser.add_argument('page', type=int, default=1, help='Page number')
seen_search_parser.add_argument('max', type=int, default=100, help='Seen entries per page')
seen_search_parser.add_argument('local_seen', type=fields.String(enum=['true', 'false', 'all'], default='all')

@seen_api.route('/')
class SeenSearchAPI(APIResource):
    @api.response(404, 'Page does not exist')
    @api.response(200, 'Successfully retrieved seen objects', seen_search_schema)
    @api.doc(parser=seen_search_parser)
    def get(self, session):
        """ Search for seen entries """
        args = seen_search_parser.parse_args()

I the use the expect wrapper and I do see this nicely in swagger. But when I try to send the request I get a validation error. When debugging I get a error: String object is not callable raised from the reqparse.convert method:

{
  "errors": {
    "local_seen": "'String' object is not callable"
  },
  "message": "Input payload validation failed"
}

Why is that? I am sending a string value obviously under the parameter. What am I doing wrong?


Solution

  • Answered in the git issue:

    I forgot but RequestParser can also handle string enumerations

    seen_search_parser = api.parser()
    seen_search_parser.add_argument('page', type=int, default=1, help='Page number')
    seen_search_parser.add_argument('max', type=int, default=100, help='Seen entries per page')
    seen_search_parser.add_argument('local_seen', type=str, default='all',
                                    choices=('true', 'false', 'all'),
                                    help='Filter list by local status.')
    
    
    class MyResource(Resource):
        @api.expect(seen_search)
        def get(self):
            args = seen_search..parse_args()
            local_seen = args['local_seen']
            if local_seen == 'true':
                # true case
            elif local_seen == 'false':
                # false case
            elif local_seen == 'all':
                # all case