orchestrata_tools.diagram.module_diagram
Reference › orchestrata_tools › diagram › module_diagram
This module draws a Mermaid dependency graph between modules. ModuleDiagramGenerator.generate counts each module's imports, keeps the max_modules (default 30) modules with the most imports, and draws an edge for each import of an orchestrata_ultimate package where the target, cut to its first two dotted segments, is also in the kept set. The result is a MermaidDiagram titled "Module Dependencies", defined in class_diagram. It reads from an ASTIndex.
At a glance
| Source | src/orchestrata_tools/diagram/module_diagram.py |
| Lines of code | 61 |
| Classes | 1 |
| Functions | 0 |
| Imports (internal) | orchestrata_tools.diagram.class_diagram, orchestrata_tools.parser.indexer |
| Imported by | orchestrata_tools, orchestrata_tools.diagram |
| Tests that import it | none |
Class diagram
Dependency diagram
API
Classes
ModuleDiagramGenerator
Line 14
Generate Mermaid diagrams showing module dependencies.
| Method | Signature | Summary |
|---|---|---|
__init__ |
__init__(index: ASTIndex) |
|
generate |
generate(max_modules: int = 30) -> MermaidDiagram |
Generate a module dependency diagram. |
Source
"""Generate Mermaid module dependency diagrams."""
from __future__ import annotations
from collections import defaultdict
from typing import TYPE_CHECKING
from orchestrata_tools.diagram.class_diagram import MermaidDiagram
if TYPE_CHECKING:
from orchestrata_tools.parser.indexer import ASTIndex
class ModuleDiagramGenerator:
"""Generate Mermaid diagrams showing module dependencies."""
def __init__(self, index: ASTIndex):
self.index = index
def generate(self, max_modules: int = 30) -> MermaidDiagram:
"""Generate a module dependency diagram."""
# Count imports between modules
module_imports: dict[str, set[str]] = defaultdict(set)
import_counts: dict[str, int] = defaultdict(int)
for mod in self.index.codebase.modules:
import_counts[mod.path] = len(mod.imports)
for imp in mod.imports:
if imp.module.startswith("orchestrata_ultimate"):
# Normalize to module path
parts = imp.module.split(".")
if len(parts) >= 2:
target = ".".join(parts[:2])
module_imports[mod.path].add(target)
# Pick top modules by import count
top_modules = sorted(
import_counts,
key=lambda m: import_counts[m],
reverse=True,
)[:max_modules]
top_set = set(top_modules)
lines = ["graph TD"]
edges = []
for mod_path in top_modules:
safe_name = mod_path.replace(".", "_")
lines.append(f' {safe_name}["{mod_path}"]')
for target in module_imports[mod_path]:
if target in top_set:
target_safe = target.replace(".", "_")
edges.append(f" {safe_name} --> {target_safe}")
lines.extend(sorted(set(edges)))
body = "\n".join(lines)
return MermaidDiagram(
title="Module Dependencies",
body=body,
node_count=len(top_modules),
edge_count=len(set(edges)),
)