Files
notifications-api/notifications_utils/insensitive_dict.py
Carlo Costino 99edc88197 Localize notification_utils to the API
This changeset pulls in all of the notification_utils code directly into the API and removes it as an external dependency.  We are doing this to cut down on operational maintenance of the project and will begin removing parts of it no longer needed for the API.

Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
2024-05-16 10:17:45 -04:00

60 lines
1.7 KiB
Python

from functools import lru_cache
from ordered_set import OrderedSet
class InsensitiveDict(dict):
"""
`InsensitiveDict` behaves like an ordered dictionary, except it normalises
case, whitespace, hypens and underscores in keys.
In other words,
InsensitiveDict({'FIRST_NAME': 'example'}) == InsensitiveDict({'first name': 'example'})
>>> True
"""
KEY_TRANSLATION_TABLE = {ord(c): None for c in " _-"}
def __init__(self, row_dict):
for key, value in row_dict.items():
self[key] = value
@classmethod
def from_keys(cls, keys):
"""
This behaves like `dict.from_keys`, except:
- it normalises the keys to ignore case, whitespace, hypens and
underscores
- it stores the original, unnormalised key as the value of the
item so it can be retrieved later
"""
return cls({key: key for key in keys})
def keys(self):
return OrderedSet(super().keys())
def __getitem__(self, key):
return super().__getitem__(self.make_key(key))
def __setitem__(self, key, value):
super().__setitem__(self.make_key(key), value)
def __contains__(self, key):
return super().__contains__(self.make_key(key))
def get(self, key, default=None):
return self[key] if key in self else default
def copy(self):
return self.__class__(super().copy())
def as_dict_with_keys(self, keys):
return {key: self.get(key) for key in keys}
@staticmethod
@lru_cache(maxsize=32, typed=False)
def make_key(original_key):
if original_key is None:
return None
return original_key.translate(InsensitiveDict.KEY_TRANSLATION_TABLE).lower()