| 2 | |
| 3 | |
| 4 | def deflate(node, index=None, path=None): |
| 5 | if index is None: |
| 6 | index = {} |
| 7 | if path is None: |
| 8 | path = [] |
| 9 | |
| 10 | if node and "id" in node and "__typename" in node: |
| 11 | route = ",".join(path) |
| 12 | cache_key = ":".join([route, str(node["__typename"]), str(node["id"])]) |
| 13 | |
| 14 | if index.get(cache_key) is True: |
| 15 | return {"__typename": node["__typename"], "id": node["id"]} |
| 16 | else: |
| 17 | index[cache_key] = True |
| 18 | |
| 19 | result = {} |
| 20 | |
| 21 | for field_name in node: |
| 22 | value = node[field_name] |
| 23 | |
| 24 | new_path = path + [field_name] |
| 25 | if isinstance(value, (list, tuple)): |
| 26 | result[field_name] = [deflate(child, index, new_path) for child in value] |
| 27 | elif isinstance(value, Mapping): |
| 28 | result[field_name] = deflate(value, index, new_path) |
| 29 | else: |
| 30 | result[field_name] = value |
| 31 | |
| 32 | return result |