bedrock.helpers.dictionary
1import uuid 2from typing import Type, Any 3 4from bedrock._helpers.string import camelCase_to_snake_case, snake_case_to_camelCase 5 6 7def exclude_keys_from_dict(dictionary: dict, exclude_keys: list[str]) -> dict: # pragma: unit 8 """ 9 Returns a copy of the dictionary without the specified keys. 10 :param dictionary: The original dictionary 11 :param exclude_keys: The keys to exclude 12 :return: A new dictionary 13 """ 14 d = dictionary.copy() 15 for key in exclude_keys: 16 if key in d: 17 del d[key] 18 return d 19 20 21def merge_dictionaries(base_dictionary: dict, dictionary_to_merge: dict = None, 22 bypass_nones=False) -> dict: # pragma: unit 23 """ 24 Superficially merges two dictionaries, with the second dictionary taking precedence (i.e.: if any key is present in 25 both dictionaries, the value in the second dictionary will be used). 26 :param base_dictionary: A dictionary 27 :param dictionary_to_merge: The dictionary to merge into the base dictionary 28 :param bypass_nones: Whether to bypass None values in the second dictionary 29 :return: A new dictionary 30 """ 31 body = base_dictionary.copy() 32 if dictionary_to_merge is None: 33 return body 34 35 for key in dictionary_to_merge: 36 if not (bypass_nones and dictionary_to_merge[key] is None): 37 body[snake_case_to_camelCase(key)] = dictionary_to_merge[key] 38 return body 39 40 41def get_dict_key_with_fallback(dictionary: dict, key: str, fallback=None) -> Any: # pragma: unit 42 """ 43 Returns the value of the specified key in the dictionary, or the fallback value if the key does not exist. 44 :param dictionary: Dictionary to search in 45 :param key: The key in the dictionary 46 :param fallback: The fallback value when `key` is not found 47 :return: Either `dictionary[key]` or `fallback` 48 """ 49 try: 50 return dictionary[key] 51 except (KeyError, TypeError): 52 if fallback is None: 53 raise Exception(f"Could not find attribute {key} in dictionary") 54 return fallback 55 56 57def check_dict_key(dictionary: dict, key: str, exception: Type[Exception] = Exception): # pragma: unit 58 """ 59 Checks if the specified key exists in the dictionary, and raises the provided exception if it does not. 60 61 This is a handy shortcut to turn a `KeyError` or `TypeError` into a custom exception. 62 63 :param dictionary: Dictionary to search in 64 :param key: The key in the dictionary 65 :param exception: The exception to raise if the key is not found (Default: `Exception`) 66 """ 67 try: 68 dictionary[key] 69 except (KeyError, TypeError): 70 raise exception(f"{key} is required") 71 72 73def get_snake_or_camel_case_key(dictionary: dict, key: str) -> str: # pragma: unit 74 """ 75 Returns the key in the dictionary that matches the specified key, regardless of whether it is in snake_case or camelCase. 76 :param dictionary: The dictionary to search in 77 :param key: The key to search for 78 :return: The properly formatted key 79 """ 80 try: 81 _key = camelCase_to_snake_case(key) 82 dictionary[_key] # Check if the key exists 83 return _key 84 except KeyError: 85 _key = snake_case_to_camelCase(key) 86 dictionary[_key] # Check if the key exists 87 return _key 88 89 90def get_snake_or_camel_case_value(dictionary: dict, key: str) -> Any: # pragma: unit 91 """ 92 Returns the value in the dictionary that matches the specified key, regardless of whether it is in snake_case or 93 camelCase. 94 :param dictionary: The dictionary to search in 95 :param key: The key to search for (either in snake_case or camelCase) 96 """ 97 try: 98 return dictionary[camelCase_to_snake_case(key)] 99 except KeyError: 100 return dictionary[snake_case_to_camelCase(key)] 101 102 103def has_key_value(dictionary: dict, key: str, value, 104 snake_and_camel_case: bool = False, 105 compare_lists_with_contains=False) -> bool: # pragma: unit 106 """ 107 Checks whether the specified key exists in the dictionary, and whether the value matches the specified value. 108 This method treats a string UUID and an object UUID the same 109 110 Optionally: 111 * the key can be in snake_case or camelCase (with `snake_and_camel_case`) 112 * the value can be a list, in which case the value will be checked with `in` instead of `==` (with `compare_lists_with_contains`) 113 114 :param dictionary: The dictionary to search in 115 :param key: The key to search for 116 :param value: The value to compare with 117 :param snake_and_camel_case: Whether the key can be in snake_case or camelCase 118 :param compare_lists_with_contains: Whether to compare lists with `in` instead of `==` 119 :return: 120 """ 121 try: 122 if snake_and_camel_case: 123 _key = get_snake_or_camel_case_key(dictionary, key) 124 else: 125 _key = key 126 127 if compare_lists_with_contains and isinstance(value, list): 128 return dictionary[_key] in value 129 if isinstance(dictionary[_key], uuid.UUID): 130 return str(dictionary[_key]) == str(value) 131 return dictionary[_key] == value 132 except (KeyError, TypeError): 133 return False 134 135 136def has_key(dictionary: dict, key: str, snake_and_camel_case: bool = False) -> bool: # pragma: unit 137 """ 138 Checks whether the specified key exists in the dictionary. 139 140 Optionally, the key can be in snake_case or camelCase (with `snake_and_camel_case`). 141 142 :param dictionary: The dictionary to search in 143 :param key: The key to search for 144 :param snake_and_camel_case: Whether the key can be in snake_case or camelCase 145 """ 146 try: 147 if snake_and_camel_case: 148 _key = get_snake_or_camel_case_key(dictionary, key) 149 else: 150 _key = key 151 return _key in dictionary 152 except KeyError: 153 return False 154 155 156def contains_keys(dictionary, keys, snake_and_camel_case: bool = False): # pragma: unit 157 """ 158 Checks if the dictionary contains all the specified keys. 159 160 Optionally, the keys can be in snake_case or camelCase (with `snake_and_camel_case`). 161 162 :param dictionary: The dictionary to search in 163 :param keys: The keys to search for 164 :param snake_and_camel_case: Whether the keys can be in snake_case or camelCase 165 """ 166 for key in keys: 167 if not has_key(dictionary, key, snake_and_camel_case): 168 return False 169 return True
8def exclude_keys_from_dict(dictionary: dict, exclude_keys: list[str]) -> dict: # pragma: unit 9 """ 10 Returns a copy of the dictionary without the specified keys. 11 :param dictionary: The original dictionary 12 :param exclude_keys: The keys to exclude 13 :return: A new dictionary 14 """ 15 d = dictionary.copy() 16 for key in exclude_keys: 17 if key in d: 18 del d[key] 19 return d
Returns a copy of the dictionary without the specified keys.
Parameters
- dictionary: The original dictionary
- exclude_keys: The keys to exclude
Returns
A new dictionary
22def merge_dictionaries(base_dictionary: dict, dictionary_to_merge: dict = None, 23 bypass_nones=False) -> dict: # pragma: unit 24 """ 25 Superficially merges two dictionaries, with the second dictionary taking precedence (i.e.: if any key is present in 26 both dictionaries, the value in the second dictionary will be used). 27 :param base_dictionary: A dictionary 28 :param dictionary_to_merge: The dictionary to merge into the base dictionary 29 :param bypass_nones: Whether to bypass None values in the second dictionary 30 :return: A new dictionary 31 """ 32 body = base_dictionary.copy() 33 if dictionary_to_merge is None: 34 return body 35 36 for key in dictionary_to_merge: 37 if not (bypass_nones and dictionary_to_merge[key] is None): 38 body[snake_case_to_camelCase(key)] = dictionary_to_merge[key] 39 return body
Superficially merges two dictionaries, with the second dictionary taking precedence (i.e.: if any key is present in both dictionaries, the value in the second dictionary will be used).
Parameters
- base_dictionary: A dictionary
- dictionary_to_merge: The dictionary to merge into the base dictionary
- bypass_nones: Whether to bypass None values in the second dictionary
Returns
A new dictionary
42def get_dict_key_with_fallback(dictionary: dict, key: str, fallback=None) -> Any: # pragma: unit 43 """ 44 Returns the value of the specified key in the dictionary, or the fallback value if the key does not exist. 45 :param dictionary: Dictionary to search in 46 :param key: The key in the dictionary 47 :param fallback: The fallback value when `key` is not found 48 :return: Either `dictionary[key]` or `fallback` 49 """ 50 try: 51 return dictionary[key] 52 except (KeyError, TypeError): 53 if fallback is None: 54 raise Exception(f"Could not find attribute {key} in dictionary") 55 return fallback
Returns the value of the specified key in the dictionary, or the fallback value if the key does not exist.
Parameters
- dictionary: Dictionary to search in
- key: The key in the dictionary
- fallback: The fallback value when
keyis not found
Returns
Either
dictionary[key]orfallback
58def check_dict_key(dictionary: dict, key: str, exception: Type[Exception] = Exception): # pragma: unit 59 """ 60 Checks if the specified key exists in the dictionary, and raises the provided exception if it does not. 61 62 This is a handy shortcut to turn a `KeyError` or `TypeError` into a custom exception. 63 64 :param dictionary: Dictionary to search in 65 :param key: The key in the dictionary 66 :param exception: The exception to raise if the key is not found (Default: `Exception`) 67 """ 68 try: 69 dictionary[key] 70 except (KeyError, TypeError): 71 raise exception(f"{key} is required")
Checks if the specified key exists in the dictionary, and raises the provided exception if it does not.
This is a handy shortcut to turn a KeyError or TypeError into a custom exception.
Parameters
- dictionary: Dictionary to search in
- key: The key in the dictionary
- exception: The exception to raise if the key is not found (Default:
Exception)
74def get_snake_or_camel_case_key(dictionary: dict, key: str) -> str: # pragma: unit 75 """ 76 Returns the key in the dictionary that matches the specified key, regardless of whether it is in snake_case or camelCase. 77 :param dictionary: The dictionary to search in 78 :param key: The key to search for 79 :return: The properly formatted key 80 """ 81 try: 82 _key = camelCase_to_snake_case(key) 83 dictionary[_key] # Check if the key exists 84 return _key 85 except KeyError: 86 _key = snake_case_to_camelCase(key) 87 dictionary[_key] # Check if the key exists 88 return _key
Returns the key in the dictionary that matches the specified key, regardless of whether it is in snake_case or camelCase.
Parameters
- dictionary: The dictionary to search in
- key: The key to search for
Returns
The properly formatted key
91def get_snake_or_camel_case_value(dictionary: dict, key: str) -> Any: # pragma: unit 92 """ 93 Returns the value in the dictionary that matches the specified key, regardless of whether it is in snake_case or 94 camelCase. 95 :param dictionary: The dictionary to search in 96 :param key: The key to search for (either in snake_case or camelCase) 97 """ 98 try: 99 return dictionary[camelCase_to_snake_case(key)] 100 except KeyError: 101 return dictionary[snake_case_to_camelCase(key)]
Returns the value in the dictionary that matches the specified key, regardless of whether it is in snake_case or camelCase.
Parameters
- dictionary: The dictionary to search in
- key: The key to search for (either in snake_case or camelCase)
104def has_key_value(dictionary: dict, key: str, value, 105 snake_and_camel_case: bool = False, 106 compare_lists_with_contains=False) -> bool: # pragma: unit 107 """ 108 Checks whether the specified key exists in the dictionary, and whether the value matches the specified value. 109 This method treats a string UUID and an object UUID the same 110 111 Optionally: 112 * the key can be in snake_case or camelCase (with `snake_and_camel_case`) 113 * the value can be a list, in which case the value will be checked with `in` instead of `==` (with `compare_lists_with_contains`) 114 115 :param dictionary: The dictionary to search in 116 :param key: The key to search for 117 :param value: The value to compare with 118 :param snake_and_camel_case: Whether the key can be in snake_case or camelCase 119 :param compare_lists_with_contains: Whether to compare lists with `in` instead of `==` 120 :return: 121 """ 122 try: 123 if snake_and_camel_case: 124 _key = get_snake_or_camel_case_key(dictionary, key) 125 else: 126 _key = key 127 128 if compare_lists_with_contains and isinstance(value, list): 129 return dictionary[_key] in value 130 if isinstance(dictionary[_key], uuid.UUID): 131 return str(dictionary[_key]) == str(value) 132 return dictionary[_key] == value 133 except (KeyError, TypeError): 134 return False
Checks whether the specified key exists in the dictionary, and whether the value matches the specified value. This method treats a string UUID and an object UUID the same
Optionally:
- the key can be in snake_case or camelCase (with
snake_and_camel_case) - the value can be a list, in which case the value will be checked with
ininstead of==(withcompare_lists_with_contains)
Parameters
- dictionary: The dictionary to search in
- key: The key to search for
- value: The value to compare with
- snake_and_camel_case: Whether the key can be in snake_case or camelCase
- compare_lists_with_contains: Whether to compare lists with
ininstead of==
Returns
137def has_key(dictionary: dict, key: str, snake_and_camel_case: bool = False) -> bool: # pragma: unit 138 """ 139 Checks whether the specified key exists in the dictionary. 140 141 Optionally, the key can be in snake_case or camelCase (with `snake_and_camel_case`). 142 143 :param dictionary: The dictionary to search in 144 :param key: The key to search for 145 :param snake_and_camel_case: Whether the key can be in snake_case or camelCase 146 """ 147 try: 148 if snake_and_camel_case: 149 _key = get_snake_or_camel_case_key(dictionary, key) 150 else: 151 _key = key 152 return _key in dictionary 153 except KeyError: 154 return False
Checks whether the specified key exists in the dictionary.
Optionally, the key can be in snake_case or camelCase (with snake_and_camel_case).
Parameters
- dictionary: The dictionary to search in
- key: The key to search for
- snake_and_camel_case: Whether the key can be in snake_case or camelCase
157def contains_keys(dictionary, keys, snake_and_camel_case: bool = False): # pragma: unit 158 """ 159 Checks if the dictionary contains all the specified keys. 160 161 Optionally, the keys can be in snake_case or camelCase (with `snake_and_camel_case`). 162 163 :param dictionary: The dictionary to search in 164 :param keys: The keys to search for 165 :param snake_and_camel_case: Whether the keys can be in snake_case or camelCase 166 """ 167 for key in keys: 168 if not has_key(dictionary, key, snake_and_camel_case): 169 return False 170 return True
Checks if the dictionary contains all the specified keys.
Optionally, the keys can be in snake_case or camelCase (with snake_and_camel_case).
Parameters
- dictionary: The dictionary to search in
- keys: The keys to search for
- snake_and_camel_case: Whether the keys can be in snake_case or camelCase