PlanOpticon

fix(viz): make networkx import optional so CI tests pass without it visualization.py now defers the ImportError to function call time instead of module import time, and test_visualization.py uses pytest.importorskip to skip gracefully when networkx is not installed.

lmata 2026-03-07 22:35 trunk
Commit 40374de5d99890156ab0e0fc9433501ea79fbc9b80764a7d2418aaed26cb3a03
--- tests/test_visualization.py
+++ tests/test_visualization.py
@@ -1,10 +1,12 @@
11
"""Tests for video_processor.utils.visualization module."""
22
33
import pytest
44
5
-from video_processor.utils.visualization import (
5
+nx = pytest.importorskip("networkx", reason="networkx not installed")
6
+
7
+from video_processor.utils.visualization import ( # noqa: E402
68
compute_graph_stats,
79
filter_graph,
810
generate_mermaid,
911
graph_to_d3_json,
1012
graph_to_dot,
1113
--- tests/test_visualization.py
+++ tests/test_visualization.py
@@ -1,10 +1,12 @@
1 """Tests for video_processor.utils.visualization module."""
2
3 import pytest
4
5 from video_processor.utils.visualization import (
 
 
6 compute_graph_stats,
7 filter_graph,
8 generate_mermaid,
9 graph_to_d3_json,
10 graph_to_dot,
11
--- tests/test_visualization.py
+++ tests/test_visualization.py
@@ -1,10 +1,12 @@
1 """Tests for video_processor.utils.visualization module."""
2
3 import pytest
4
5 nx = pytest.importorskip("networkx", reason="networkx not installed")
6
7 from video_processor.utils.visualization import ( # noqa: E402
8 compute_graph_stats,
9 filter_graph,
10 generate_mermaid,
11 graph_to_d3_json,
12 graph_to_dot,
13
--- video_processor/utils/visualization.py
+++ video_processor/utils/visualization.py
@@ -3,21 +3,27 @@
33
from typing import Dict, List, Optional
44
55
try:
66
import networkx as nx
77
except ImportError:
8
- raise ImportError(
9
- "networkx is required for graph visualization. Install it with: pip install networkx"
10
- )
8
+ nx = None
9
+
10
+
11
+def _require_nx():
12
+ if nx is None:
13
+ raise ImportError(
14
+ "networkx is required for graph visualization. Install it with: pip install networkx"
15
+ )
1116
1217
1318
def graph_to_networkx(kg_data: dict) -> "nx.DiGraph":
1419
"""Convert knowledge graph dict (from to_dict()) to NetworkX directed graph.
1520
1621
Nodes get attributes: type, descriptions, source, occurrences
1722
Edges get attributes: type, content_source, timestamp
1823
"""
24
+ _require_nx()
1925
G = nx.DiGraph()
2026
2127
for node in kg_data.get("nodes", []):
2228
name = node.get("name", node.get("id", ""))
2329
if not name:
2430
--- video_processor/utils/visualization.py
+++ video_processor/utils/visualization.py
@@ -3,21 +3,27 @@
3 from typing import Dict, List, Optional
4
5 try:
6 import networkx as nx
7 except ImportError:
8 raise ImportError(
9 "networkx is required for graph visualization. Install it with: pip install networkx"
10 )
 
 
 
 
 
11
12
13 def graph_to_networkx(kg_data: dict) -> "nx.DiGraph":
14 """Convert knowledge graph dict (from to_dict()) to NetworkX directed graph.
15
16 Nodes get attributes: type, descriptions, source, occurrences
17 Edges get attributes: type, content_source, timestamp
18 """
 
19 G = nx.DiGraph()
20
21 for node in kg_data.get("nodes", []):
22 name = node.get("name", node.get("id", ""))
23 if not name:
24
--- video_processor/utils/visualization.py
+++ video_processor/utils/visualization.py
@@ -3,21 +3,27 @@
3 from typing import Dict, List, Optional
4
5 try:
6 import networkx as nx
7 except ImportError:
8 nx = None
9
10
11 def _require_nx():
12 if nx is None:
13 raise ImportError(
14 "networkx is required for graph visualization. Install it with: pip install networkx"
15 )
16
17
18 def graph_to_networkx(kg_data: dict) -> "nx.DiGraph":
19 """Convert knowledge graph dict (from to_dict()) to NetworkX directed graph.
20
21 Nodes get attributes: type, descriptions, source, occurrences
22 Edges get attributes: type, content_source, timestamp
23 """
24 _require_nx()
25 G = nx.DiGraph()
26
27 for node in kg_data.get("nodes", []):
28 name = node.get("name", node.get("id", ""))
29 if not name:
30

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button