Search code examples
pythonflaskflask-restful

Can Flask-Restful accept case-insensitive argument names?


If I do this with Flask-Restful:

parser = reqparse.RequestParser()
parser.add_argument('group', type=str, help='Please specify a valid group')

then the parser will accept an argument of group=X but not Group=X or GROUP=X.

Is there a way to make it be case-insensitive when taking argument names?

(The reqparse.Argument class has a parameter called case_sensitive but unfortunately that only makes the values case insensitive (by making them lowercase). It doesn't affect the argument name.


Solution

  • Pass a different Argument class to the RequestParser that wraps the args in a case-insensitive MultiDict subclass.

    class CaseInsensitiveMultiDict(MultiDict):
        def __init__(self, mapping=None):
            super().__init__(mapping)
            # map lowercase keys to the real keys
            self.lower_key_map = {key.lower(): key for key in self}
    
        def __contains__(self, key):
            return key.lower() in self.lower_key_map
    
        def getlist(self, key):
            return super().getlist(self.lower_key_map.get(key.lower()))
    
        def pop(self, key):
            return super().pop(self.lower_key_map.get(key.lower()))
    
    
    class CaseInsensitiveArgument(Argument):
        def source(self, request):
            return CaseInsensitiveMultiDict(super().source(request))
    
    parser = RequestParser(argument_class=CaseInsensitiveArgument)
    

    You can still have case-sensitive args by passing an Argument instance to add_argument, rather than keywords.

    The MultiDict subclass implements just enough to be case-insensitive for the parser's use case, it's not suitable as a general implementation.