How the code-review-graph Export Functionality Works: GraphML, Neo4j, and Obsidian Explained

The code-review-graph library serializes analyzed codebases from a GraphStore into multiple interchange formats—including GraphML, Neo4j Cypher, and Obsidian Vault—via specialized functions in code_review_graph/exports.py that consume a normalized data payload from export_graph_data.

The code-review-graph repository provides a complete pipeline for transforming static code analysis into portable graph formats. Whether you need to visualize relationships in Gephi, import structures into a graph database, or browse code complexity in Obsidian, the export functionality handles normalization, serialization, and atomic file operations through a consistent Python API.

The Core Export Pipeline

Every export format follows an identical two-step pattern. First, the shared export_graph_data function (defined in code_review_graph/visualization.py) extracts nodes, edges, and community data from the GraphStore into a normalized dictionary. Second, format-specific writers in code_review_graph/exports.py serialize this payload to disk.

from code_review_graph.visualization import export_graph_data

# Normalize the store into a portable payload

data = export_graph_data(store)  # Contains nodes, edges, communities

All export functions accept a GraphStore instance and a destination Path, automatically creating parent directories via Path.mkdir(parents=True, exist_ok=True).

JSON Export with Atomic Writes

The export_json function (lines 23-51 of exports.py) provides the simplest serialization path. It writes UTF-8 JSON using an atomic file replacement strategy to prevent corruption during interrupted writes.

from pathlib import Path
from code_review_graph.exports import export_json

export_json(store, Path("output/graph.json"))

Under the hood, the function writes to a temporary file first, then calls os.replace to atomically move the completed file into place. This ensures that readers never encounter a partially written JSON object.

GraphML Export for Visualization Tools

GraphML export targets desktop visualization tools like Gephi, yEd, and Cytoscape. Implemented in export_graphml (lines 58-117 of exports.py), this function generates XML conforming to the GraphML schema specification.

Each node receives <data> entries encoding kind, file, language, and community attributes. Edges include an edge_kind property distinguishing relationship types. This rich metadata preserves the analytical context when importing into external tools.

from code_review_graph.exports import export_graphml

export_graphml(store, Path("output/graph.graphml"))

Neo4j Cypher Export

For graph database ingestion, export_neo4j_cypher (lines 124-170 of exports.py) generates executable Cypher statements. The output contains CREATE clauses for nodes and MATCH...CREATE patterns for relationships.

The implementation uses two helper functions to ensure syntactic correctness:

  • _cypher_props: Converts Python dictionaries into Cypher property maps
  • _cypher_escape: Sanitizes strings to prevent injection or parsing errors
from code_review_graph.exports import export_neo4j_cypher

export_neo4j_cypher(store, Path("output/import.cypher"))

The resulting .cypher file can be pasted directly into the Neo4j Browser or executed via the cypher-shell command-line tool.

Obsidian Vault Export

The Obsidian export generates a complete knowledge base as a directory of Markdown files. Unlike single-file formats, export_obsidian_vault (lines 192-444 of exports.py) creates a hierarchical structure:

  • One Markdown page per graph node with YAML front-matter metadata
  • Wikilink syntax ([[...]]) connecting related entities
  • Community overview pages aggregating members
  • A global index page for vault navigation

The helper _obsidian_slug normalizes node names into file-safe identifiers.

from code_review_graph.exports import export_obsidian_vault

export_obsidian_vault(store, Path("output/obsidian_vault"))

Opening the obsidian_vault folder in Obsidian reveals a browsable network where code entities, files, and communities function as interlinked notes.

SVG Visualization Export

For static visualization, export_svg constructs a networkx.DiGraph from the normalized payload, applies color mapping by node kind, and renders using Matplotlib's Agg backend. This export requires the optional matplotlib dependency; the function raises a clear ImportError if the library is missing.

from code_review_graph.exports import export_svg

export_svg(store, Path("output/graph.svg"))

The SVG output provides a quick overview suitable for documentation or presentation decks without requiring external tool installation.

Command-Line Interface Integration

The CLI module at code_review_graph/cli.py (lines 1658-1685) exposes these exporters via the --export flag. The interface maps user input to the appropriate function:

from code_review_graph.exports import (
    export_json,
    export_graphml,
    export_neo4j_cypher,
    export_obsidian_vault,
    export_svg,
)

# CLI dispatch example

export_mapping = {
    "json": export_json,
    "graphml": export_graphml,
    "neo4j": export_neo4j_cypher,
    "obsidian": export_obsidian_vault,
    "svg": export_svg,
}

This allows terminal users to invoke exports without writing Python scripts:

code-review-graph analyze ./src --export graphml --output ./graph.graphml

Summary

  • All formats consume the same normalized payload from export_graph_data in visualization.py.
  • JSON uses atomic file replacement via os.replace to prevent corruption.
  • GraphML embeds rich metadata including community assignments and language tags.
  • Neo4j output generates ready-to-run Cypher with sanitized string escaping.
  • Obsidian creates a multi-file vault with YAML front-matter and wikilinks.
  • SVG requires matplotlib and renders colored node networks.

Frequently Asked Questions

How does the code-review-graph export functionality normalize data before writing?

All exporters call export_graph_data(store) from code_review_graph/visualization.py first. This function transforms the internal GraphStore representation into a standardized dictionary containing a nodes list, edges list, and community mappings, ensuring every format receives identically structured input regardless of the source analysis state.

What prevents partial file writes during JSON export?

The export_json function writes to a temporary file in the same directory, then calls os.replace to atomically rename the temporary file to the final destination. This ensures that readers either see the complete previous file or the complete new file, never a partially written intermediate state.

How does the Obsidian Vault export differ from GraphML?

While GraphML produces a single XML file optimized for graph visualization software, the Obsidian export generates an entire directory structure containing multiple Markdown files—one per node—complete with YAML front-matter metadata and wikilink syntax. This creates a navigable knowledge base rather than a graph interchange format.

Which export formats require optional dependencies?

Only the SVG export requires an external dependency. The export_svg function attempts to import matplotlib lazily at runtime, raising an ImportError with a clear message if the library is not installed. JSON, GraphML, Neo4j, and Obsidian exports rely solely on the Python standard library.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →