Codegen provides the ability to create interactive graph visualizations via the codebase.visualize(…) method.These visualizations have a number of applications, including:
Understanding codebase structure
Monitoring critical code paths
Analyzing dependencies
Understanding inheritance hierarchies
This guide provides a basic overview of graph creation and customization. Like the one below which displays the call_graph for the modal/client.py module.
Codegen visualizations are powered by NetworkX and
rendered using d3.
When adding nodes to your graph, you can either add the symbol directly or just its name:
Copy
Ask AI
import networkx as nxG = nx.DiGraph()function = codebase.get_function("my_function")# Add the function object directly - enables source code previewgraph.add_node(function) # Will show function's source code on click# Add just the name - no extra featuresgraph.add_node(function.name) # Will only show the name
Adding symbols to the graph directly (as opposed to adding by name) enables
automatic type information, code preview on hover, and more.
def create_modularity_graph(functions: list[Function]): graph = nx.Graph() # Group functions by shared dependencies for func in functions: for dep in func.dependencies: if isinstance(dep, Function): weight = len(set(func.dependencies) & set(dep.dependencies)) if weight > 0: graph.add_edge(func.name, dep.name, weight=weight) return graph# Visualize function modularityfuncs = codebase.functionsmodularity_graph = create_modularity_graph(funcs)codebase.visualize(modularity_graph)
You can customize your visualizations using NetworkX’s attributes while still preserving the smart node features:
Copy
Ask AI
def create_custom_graph(codebase): graph = nx.DiGraph() # Add nodes with custom attributes while preserving source preview for func in codebase.functions: graph.add_node(func, color='red' if func.is_public else 'blue', shape='box' if func.is_async else 'oval' ) # Add edges between actual function objects for func in codebase.functions: for call in func.call_sites: if call.resolved_symbol: graph.add_edge(func, call.resolved_symbol, style='dashed' if call.is_conditional else 'solid', weight=call.count ) return graph
# Better: Add symbol objects for rich previews# This will include source code previews, syntax highlighting, type information, etc.for func in api_funcs: graph.add_node(func)# Basic: Just names, no extra featuresfor func in api_funcs: graph.add_node(func.name)
Focus on Relevant Subgraphs
Copy
Ask AI
# Better: Visualize specific subsystemapi_funcs = [f for f in codebase.functions if "api" in f.filepath]api_graph = create_call_graph(api_funcs)codebase.visualize(api_graph)# Avoid: Visualizing entire codebasefull_graph = create_call_graph(codebase.functions) # Too complex
Use Meaningful Layouts
Copy
Ask AI
# Group related nodes togethergraph.add_node(controller_class, cluster="api")graph.add_node(service_class, cluster="db")
Add Visual Hints
Copy
Ask AI
# Color code by type while preserving rich previewsfor node in codebase.functions: if "Controller" in node.name: graph.add_node(node, color="red") elif "Service" in node.name: graph.add_node(node, color="blue")