Export all graph nodes and edges as a JSON-serializable dict. Returns ``{"nodes": [...], "edges": [...], "stats": {...}, "flows": [...], "communities": [...]}``.
(store: GraphStore)
| 100 | |
| 101 | |
| 102 | def export_graph_data(store: GraphStore) -> dict: |
| 103 | """Export all graph nodes and edges as a JSON-serializable dict. |
| 104 | |
| 105 | Returns ``{"nodes": [...], "edges": [...], "stats": {...}, |
| 106 | "flows": [...], "communities": [...]}``. |
| 107 | """ |
| 108 | nodes = [] |
| 109 | seen_qn: set[str] = set() |
| 110 | |
| 111 | # Preload community_id mapping from DB (column may not exist in old schemas) |
| 112 | community_map = store.get_all_community_ids() |
| 113 | |
| 114 | for file_path in store.get_all_files(): |
| 115 | for gnode in store.get_nodes_by_file(file_path): |
| 116 | if gnode.qualified_name in seen_qn: |
| 117 | continue |
| 118 | seen_qn.add(gnode.qualified_name) |
| 119 | d = node_to_dict(gnode) |
| 120 | d["params"] = gnode.params |
| 121 | d["return_type"] = gnode.return_type |
| 122 | d["community_id"] = community_map.get(gnode.qualified_name) |
| 123 | nodes.append(d) |
| 124 | |
| 125 | name_index = _build_name_index(nodes, seen_qn) |
| 126 | |
| 127 | all_edges = [edge_to_dict(e) for e in store.get_all_edges()] |
| 128 | |
| 129 | # Resolve short/unqualified edge targets to full qualified names, |
| 130 | # then drop edges that still can't be resolved (external/stdlib calls). |
| 131 | edges = [] |
| 132 | for e in all_edges: |
| 133 | src = _resolve_target(e["source"], e["source"], seen_qn, name_index) |
| 134 | tgt = _resolve_target(e["target"], e["source"], seen_qn, name_index) |
| 135 | if src and tgt: |
| 136 | e["source"] = src |
| 137 | e["target"] = tgt |
| 138 | edges.append(e) |
| 139 | |
| 140 | stats = store.get_stats() |
| 141 | |
| 142 | # Include flows (graceful fallback if table doesn't exist) |
| 143 | try: |
| 144 | from code_review_graph.flows import get_flows |
| 145 | flows = get_flows(store, limit=100) |
| 146 | except (ImportError, sqlite3.OperationalError) as exc: |
| 147 | logger.debug("flows unavailable for export: %s", exc) |
| 148 | flows = [] |
| 149 | |
| 150 | # Include communities (graceful fallback if table doesn't exist) |
| 151 | try: |
| 152 | from code_review_graph.communities import get_communities |
| 153 | communities = get_communities(store) |
| 154 | except (ImportError, sqlite3.OperationalError) as exc: |
| 155 | logger.debug("communities unavailable for export: %s", exc) |
| 156 | communities = [] |
| 157 | |
| 158 | return { |
| 159 | "nodes": nodes, |