def test_traverse_upper(): actual = iterutil.traverse( { 'a': 'one', 'b': { 'c': { 'd': 'two', 'e': 'three' }, 'f': 'four' }, 'g': 'five', 'h': ['six', { 'i': 'seven', 'j': 'eight' }] }, lambda v, p: v.upper()) assert actual == { 'a': 'ONE', 'b': { 'c': { 'd': 'TWO', 'e': 'THREE' }, 'f': 'FOUR' }, 'g': 'FIVE', 'h': ['SIX', { 'i': 'SEVEN', 'j': 'EIGHT' }] }
def dumps(obj: dict) -> str: obj = dictutil.flatten(obj) def _process(value, key): path = '_'.join(key).upper().replace('.', '_') return f'{path}={value}' return '\n'.join(iterutil.traverse(obj, _process).values())
def inject(template: Template, context: Dict[str, Any], strict: bool = True, calls: int = 0) -> Template: """ Inject context to template. """ # Traverse template values if isinstance(template, (list, dict)): return iterutil.traverse( template, lambda v, k: inject(template=v, context=context, strict=strict)) # Return other types if not isinstance(template, str): return template result = KEY_RE.findall(template) # Increment recursive calls calls += 1 # Skip parameters replace if not result: return template # Check circular injections if calls > CIRCULAR_THRESHOLD: if strict: raise CircularInjectError(_('Circular injections detected.')) return template # Replace template context for whole, key in result: try: value = inject(template=context[key], context=context, calls=calls, strict=strict) str_value = str(value) template = template.replace(whole, str_value) if str_value == template: return value except KeyError: if strict: raise InvalidKey(_('Injected key `%(key)s` does not exist.') % {'key': key}, key=key) return inject(template=template, context=context, calls=calls, strict=strict)
def cleanse(data: dict, hidden='password', substitute='*****'): if isinstance(hidden, str): hidden = hidden.split() hidden_re = re.compile('|'.join(hidden), flags=re.IGNORECASE) def _replace(value, path: iterutil.IterPath): path = _str_path(path) if hidden_re.search(path): return substitute return value return iterutil.traverse(data, _replace)
def decrypt(data: dict, secure_keys: List[str]) -> dict: hidden_re = re.compile('|'.join(secure_keys), flags=re.IGNORECASE) def _process(value: Any, path: iterutil.IterPath) -> Any: if is_encrypted(value): path = _str_path(path) if hidden_re.search(path): encrypted_data = value.split(settings.ENCRYPT_PREFIX, maxsplit=1)[-1] obj = decrypt_data(encrypted_data) return json.loads(obj)['value'] return value return iterutil.traverse(data, _process)
def encrypt(data: dict, secure_keys: List[str]) -> dict: if not secure_keys: return data hidden_re = re.compile('|'.join(secure_keys), flags=re.IGNORECASE) def _process(value: Any, path: iterutil.IterPath) -> str: if not is_encrypted(value): path = _str_path(path) if hidden_re.search(path): encrypted_data = encrypt_data(json.dumps({'value': value})) return f'{settings.ENCRYPT_PREFIX}{encrypted_data}' return value return iterutil.traverse(data, _process)
def get_all_data() -> Dict[str, Dict[str, dict]]: if hasattr(_cached_data, _cached_data_key): return getattr(_cached_data, _cached_data_key) data = _store.all() return iterutil.traverse(data, lambda value, path: json.loads(value))