from typing import List from models.json_path_guide import JsonPathGuide, DictGuide, ListGuide def get_dict_paths_with_key(data: dict, key: str) -> List[JsonPathGuide]: result = [] def _find_paths(obj, current_path: List[DictGuide | ListGuide]): if isinstance(obj, dict): if key in obj: result.append(JsonPathGuide(guides=current_path.copy())) for k, v in obj.items(): new_path = current_path + [DictGuide(key=k)] _find_paths(v, new_path) elif isinstance(obj, list): for i, item in enumerate(obj): new_path = current_path + [ListGuide(index=i)] _find_paths(item, new_path) _find_paths(data, []) return result def get_dict_at_path(data: dict, path: JsonPathGuide) -> dict: current = data for guide in path.guides: if isinstance(guide, DictGuide): current = current[guide.key] elif isinstance(guide, ListGuide): current = current[guide.index] return current def set_dict_at_path(data: dict, path: JsonPathGuide, value: dict): current = data for guide in path.guides[:-1]: if isinstance(guide, DictGuide): current = current[guide.key] elif isinstance(guide, ListGuide): current = current[guide.index] if path.guides: final_guide = path.guides[-1] if isinstance(final_guide, DictGuide): current[final_guide.key] = value elif isinstance(final_guide, ListGuide): current[final_guide.index] = value def deep_update(original: dict, updates: dict) -> dict: for key, value in updates.items(): if key in original: if isinstance(original[key], dict) and isinstance(value, dict): deep_update(original[key], value) elif isinstance(original[key], list) and isinstance(value, list): if len(value) == 0: continue elif len(value) == 1 and isinstance(value[0], dict): if len(original[key]) > 0 and isinstance(original[key][0], dict): deep_update(original[key][0], value[0]) else: original[key][0] = ( value[0] if len(original[key]) > 0 else value[0] ) else: min_length = min(len(original[key]), len(value)) for i in range(min_length): if isinstance(original[key][i], dict) and isinstance( value[i], dict ): deep_update(original[key][i], value[i]) else: original[key][i] = value[i] elif not isinstance(value, (dict, list)): original[key] = value else: if not isinstance(value, (dict, list)): original[key] = value return original def has_more_than_n_keys(obj: dict[str, object], n: int) -> bool: i = 0 for _ in obj.keys(): i += 1 if i > n: return True return False