I’m implementing an API (proxy) that accepts incoming JSON POST data in Flask.
I need to process this JSON and after that send it on to a backend API, which was written in another language.
The JSON data will be sent by end-users, and they are used to sending this JSON data case-insensitive. This means that the incoming JSON data will sometimes have uppercase keys/nodes, sometimes lowercase, and sometimes maybe camelcase or pascalcase.
I’m using Flasks request.json
to get the data from the request. It is parsed into a Python object, but this object will have case-sensitive keys and values. These will also be nested.
A specific example of how I currently get data is:
data['ORDERS']['authentication']['AccountToken']
But my users might POST:
{
"Orders": {
"Authentication": {
"AccountToken": "C3485D7B"
},
...
Is there a way to get data['ORDERS']['authentication']['AccountToken']
in such a way that the complete path to that value is case-insensitive?
I understand I can check for each part of the path case-insensitive separately, but that requires a lot of overhead code to get to the right child-nodes.
I saw other solutions: Case insensitive dictionary
I have also tried using CaseInsensitiveDict
from the requests
library like this:
data = CaseInsensitiveDict(request.json)
, but that only makes the first level of the object case insensitive actually.
The problem with these solutions is that they deal with dicts, while the JSON data is a dict of objects that can be lists or other objects. The solutions provided don’t work recursively or only on Dicts.
Any help is appreciated.
2
Answers
Do you have to keep the case that the users send you? If not, it’s always a good idea to sanitise your input to some standard format, rather than anticipating everything you could be sent. Rather than checking your path case-insensitively, you could convert all your keys to plain lowercase on input, eg:
Which doesn’t require a lot of boilerplate and lets you keep the same path internally.
This function outputs a case insensitive dict, creating it recursively for every entry: