From 1ef47954df20f1b601c9dab3fd2d4b85afe492e6 Mon Sep 17 00:00:00 2001 From: rahul21-7 Date: Thu, 13 Aug 2026 18:58:32 +0530 Subject: [PATCH 1/7] fix: replace crashing graphar import with raw yaml parser --- icebug_format/graphar.py | 49 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/icebug_format/graphar.py b/icebug_format/graphar.py index c98cbf7..52b6c26 100644 --- a/icebug_format/graphar.py +++ b/icebug_format/graphar.py @@ -18,6 +18,7 @@ """ import argparse +import yaml from pathlib import Path import duckdb @@ -28,6 +29,45 @@ set_memory_limit, ) +class YamlVertexInfo: + def __init__(self, data): + self.data = data + def get_type(self): return self.data.get('type') + def get_prefix(self): return self.data.get('prefix') + +class YamlEdgeInfo: + def __init__(self, data): + self.data = data + def get_edge_type(self): return self.data.get('edge_type', self.data.get('type')) + def get_src_type(self): return self.data.get('src_type') + def get_dst_type(self): return self.data.get('dst_type') + def get_prefix(self): return self.data.get('prefix') + +class YamlGraphInfo: + def __init__(self, yaml_path: str): + self.base_path = Path(yaml_path).parent + with open(yaml_path, 'r') as f: + self.data = yaml.safe_load(f) + + self.vertices = [] + for v_file in self.data.get('vertices', []): + with open(self.base_path / v_file, 'r') as f: + self.vertices.append(YamlVertexInfo(yaml.safe_load(f))) + + self.edges = [] + for e_file in self.data.get('edges', []): + with open(self.base_path / e_file, 'r') as f: + self.edges.append(YamlEdgeInfo(yaml.safe_load(f))) + + def vertex_info_num(self): return len(self.vertices) + def get_vertex_info_by_index(self, i): return self.vertices[i] + def edge_info_num(self): return len(self.edges) + def get_edge_info_by_index(self, i): return self.edges[i] + + @classmethod + def load(cls, yaml_path): + return cls(yaml_path) + def duckdb_type_to_cypher_type(duckdb_type: str) -> str: """Convert DuckDB column type to Cypher/Kuzu type.""" @@ -175,7 +215,7 @@ def convert_graphar_to_graph_std( """ print("\n=== Converting GraphAr to Graph-Std Format ===") - import graphar + # import graphar # Load graph info # Find the .graph.yml file in the directory @@ -184,7 +224,12 @@ def convert_graphar_to_graph_std( if not yaml_files: raise ValueError(f"No .graph.yml file found in {graphar_dir}") yaml_path = yaml_files[0] - graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) + + # graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) + + #using raw yaml files instead of graphar for now + graph_info = YamlGraphInfo.load(str(yaml_path.absolute())) + graph_path = graphar_path From 06ca2b14ab20ec793314b92bf9227a99eeed76aa Mon Sep 17 00:00:00 2001 From: rahul21-7 Date: Thu, 13 Aug 2026 21:48:31 +0530 Subject: [PATCH 2/7] refactor: replace custom yaml parser with lazy _require_graphar import --- icebug_format/graphar.py | 56 +++++++++------------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/icebug_format/graphar.py b/icebug_format/graphar.py index 52b6c26..e2bec79 100644 --- a/icebug_format/graphar.py +++ b/icebug_format/graphar.py @@ -29,45 +29,16 @@ set_memory_limit, ) -class YamlVertexInfo: - def __init__(self, data): - self.data = data - def get_type(self): return self.data.get('type') - def get_prefix(self): return self.data.get('prefix') - -class YamlEdgeInfo: - def __init__(self, data): - self.data = data - def get_edge_type(self): return self.data.get('edge_type', self.data.get('type')) - def get_src_type(self): return self.data.get('src_type') - def get_dst_type(self): return self.data.get('dst_type') - def get_prefix(self): return self.data.get('prefix') - -class YamlGraphInfo: - def __init__(self, yaml_path: str): - self.base_path = Path(yaml_path).parent - with open(yaml_path, 'r') as f: - self.data = yaml.safe_load(f) - - self.vertices = [] - for v_file in self.data.get('vertices', []): - with open(self.base_path / v_file, 'r') as f: - self.vertices.append(YamlVertexInfo(yaml.safe_load(f))) - - self.edges = [] - for e_file in self.data.get('edges', []): - with open(self.base_path / e_file, 'r') as f: - self.edges.append(YamlEdgeInfo(yaml.safe_load(f))) - - def vertex_info_num(self): return len(self.vertices) - def get_vertex_info_by_index(self, i): return self.vertices[i] - def edge_info_num(self): return len(self.edges) - def get_edge_info_by_index(self, i): return self.edges[i] - - @classmethod - def load(cls, yaml_path): - return cls(yaml_path) - +def _require_grapphar(context: str = "GraphAr conversion") -> "module": + """Lazily import ansd return the ``graphar`` module.""" + try: + import graphar + except ImportError as exc: + raise ImportError( + f"graphar is required by {context} but is not installed or failed to load." + "Please ensure you have graphar installed(e.g., pip install graphar)." + ) from exc + return graphar def duckdb_type_to_cypher_type(duckdb_type: str) -> str: """Convert DuckDB column type to Cypher/Kuzu type.""" @@ -215,7 +186,7 @@ def convert_graphar_to_graph_std( """ print("\n=== Converting GraphAr to Graph-Std Format ===") - # import graphar + graphar = _require_grapphar() # Load graph info # Find the .graph.yml file in the directory @@ -225,10 +196,7 @@ def convert_graphar_to_graph_std( raise ValueError(f"No .graph.yml file found in {graphar_dir}") yaml_path = yaml_files[0] - # graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) - - #using raw yaml files instead of graphar for now - graph_info = YamlGraphInfo.load(str(yaml_path.absolute())) + graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) graph_path = graphar_path From 4bf63f174972507c940835d8357e429b043edc2f Mon Sep 17 00:00:00 2001 From: rahul21-7 Date: Thu, 13 Aug 2026 21:53:20 +0530 Subject: [PATCH 3/7] removed the import yaml header --- icebug_format/graphar.py | 1 - 1 file changed, 1 deletion(-) diff --git a/icebug_format/graphar.py b/icebug_format/graphar.py index e2bec79..70ee0ed 100644 --- a/icebug_format/graphar.py +++ b/icebug_format/graphar.py @@ -18,7 +18,6 @@ """ import argparse -import yaml from pathlib import Path import duckdb From 47c7246a751922aff04da26868c916349fde5434 Mon Sep 17 00:00:00 2001 From: rahul21-7 Date: Thu, 13 Aug 2026 21:54:50 +0530 Subject: [PATCH 4/7] Fix typo in docstring for _require_grapphar --- icebug_format/graphar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icebug_format/graphar.py b/icebug_format/graphar.py index 70ee0ed..4f3db33 100644 --- a/icebug_format/graphar.py +++ b/icebug_format/graphar.py @@ -29,7 +29,7 @@ ) def _require_grapphar(context: str = "GraphAr conversion") -> "module": - """Lazily import ansd return the ``graphar`` module.""" + """Lazily import and return the ``graphar`` module.""" try: import graphar except ImportError as exc: From 32c2a969b94a6cb5ed3df535d2b05f82fe61066e Mon Sep 17 00:00:00 2001 From: rahul21-7 Date: Fri, 14 Aug 2026 00:10:48 +0530 Subject: [PATCH 5/7] feat: add YamlGraphInfo fallback for _require_graphar --- icebug_format/graphar.py | 50 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/icebug_format/graphar.py b/icebug_format/graphar.py index 4f3db33..0f07658 100644 --- a/icebug_format/graphar.py +++ b/icebug_format/graphar.py @@ -18,6 +18,7 @@ """ import argparse +import yaml from pathlib import Path import duckdb @@ -28,7 +29,46 @@ set_memory_limit, ) -def _require_grapphar(context: str = "GraphAr conversion") -> "module": +class YamlVertexInfo: + def __init__(self, data): + self.data = data + def get_type(self): return self.data.get('type') + def get_prefix(self): return self.data.get('prefix') + +class YamlEdgeInfo: + def __init__(self, data): + self.data = data + def get_edge_type(self): return self.data.get('edge_type', self.data.get('type')) + def get_src_type(self): return self.data.get('src_type') + def get_dst_type(self): return self.data.get('dst_type') + def get_prefix(self): return self.data.get('prefix') + +class YamlGraphInfo: + def __init__(self, yaml_path: str): + self.base_path = Path(yaml_path).parent + with open(yaml_path, 'r') as f: + self.data = yaml.safe_load(f) + + self.vertices = [] + for v_file in self.data.get('vertices', []): + with open(self.base_path / v_file, 'r') as f: + self.vertices.append(YamlVertexInfo(yaml.safe_load(f))) + + self.edges = [] + for e_file in self.data.get('edges', []): + with open(self.base_path / e_file, 'r') as f: + self.edges.append(YamlEdgeInfo(yaml.safe_load(f))) + + def vertex_info_num(self): return len(self.vertices) + def get_vertex_info_by_index(self, i): return self.vertices[i] + def edge_info_num(self): return len(self.edges) + def get_edge_info_by_index(self, i): return self.edges[i] + + @classmethod + def load(cls, yaml_path): + return cls(yaml_path) + +def _require_graphar(context: str = "GraphAr conversion") -> "module": """Lazily import and return the ``graphar`` module.""" try: import graphar @@ -185,7 +225,11 @@ def convert_graphar_to_graph_std( """ print("\n=== Converting GraphAr to Graph-Std Format ===") - graphar = _require_grapphar() + try: + graphar = _require_graphar() + graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) + except ImportError: + graph_info = YamlGraphInfo.load(str(yaml_path.absolute())) # Load graph info # Find the .graph.yml file in the directory @@ -195,7 +239,7 @@ def convert_graphar_to_graph_std( raise ValueError(f"No .graph.yml file found in {graphar_dir}") yaml_path = yaml_files[0] - graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) + # graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) graph_path = graphar_path From dedd175b30876a74268bceaa100c9f314820ae28 Mon Sep 17 00:00:00 2001 From: rahul21-7 Date: Fri, 14 Aug 2026 01:32:11 +0530 Subject: [PATCH 6/7] test: add unit test for YamlGraphInfo parser --- icebug_format/graphar.py | 25 ++++++++++++------------- tests/test_graphar.py | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 tests/test_graphar.py diff --git a/icebug_format/graphar.py b/icebug_format/graphar.py index 0f07658..af3329e 100644 --- a/icebug_format/graphar.py +++ b/icebug_format/graphar.py @@ -59,14 +59,14 @@ def __init__(self, yaml_path: str): with open(self.base_path / e_file, 'r') as f: self.edges.append(YamlEdgeInfo(yaml.safe_load(f))) - def vertex_info_num(self): return len(self.vertices) - def get_vertex_info_by_index(self, i): return self.vertices[i] - def edge_info_num(self): return len(self.edges) - def get_edge_info_by_index(self, i): return self.edges[i] + def vertex_info_num(self): return len(self.vertices) + def get_vertex_info_by_index(self, i): return self.vertices[i] + def edge_info_num(self): return len(self.edges) + def get_edge_info_by_index(self, i): return self.edges[i] - @classmethod - def load(cls, yaml_path): - return cls(yaml_path) + @classmethod + def load(cls, yaml_path): + return cls(yaml_path) def _require_graphar(context: str = "GraphAr conversion") -> "module": """Lazily import and return the ``graphar`` module.""" @@ -225,11 +225,6 @@ def convert_graphar_to_graph_std( """ print("\n=== Converting GraphAr to Graph-Std Format ===") - try: - graphar = _require_graphar() - graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) - except ImportError: - graph_info = YamlGraphInfo.load(str(yaml_path.absolute())) # Load graph info # Find the .graph.yml file in the directory @@ -239,7 +234,11 @@ def convert_graphar_to_graph_std( raise ValueError(f"No .graph.yml file found in {graphar_dir}") yaml_path = yaml_files[0] - # graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) + try: + graphar = _require_graphar() + graph_info = graphar.GraphInfo.load(str(yaml_path.absolute())) + except ImportError: + graph_info = YamlGraphInfo.load(str(yaml_path.absolute())) graph_path = graphar_path diff --git a/tests/test_graphar.py b/tests/test_graphar.py new file mode 100644 index 0000000..908dd78 --- /dev/null +++ b/tests/test_graphar.py @@ -0,0 +1,18 @@ +import yaml +from icebug_format.graphar import YamlGraphInfo + +def test_yaml_parser_fallback_loads_empty_graph(tmp_path): + """Test that our fallback YAML parser can read a basic graph configuration.""" + yaml_content = { + "vertices": [], + "edges": [] + } + yaml_file = tmp_path / "test.graph.yml" + + with open(yaml_file, "w") as f: + yaml.dump(yaml_content, f) + + graph_info = YamlGraphInfo.load(str(yaml_file)) + + assert graph_info.vertex_info_num() == 0 + assert graph_info.edge_info_num() == 0 \ No newline at end of file From 14d371795ddd3899901ade57b19907d180477a4c Mon Sep 17 00:00:00 2001 From: Arun Sharma Date: Thu, 13 Aug 2026 13:24:18 -0700 Subject: [PATCH 7/7] graphar: add yaml to dependencies --- .github/workflows/ci.yml | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 430dcd8..f4df3b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - name: Install dependencies run: | uv venv - uv sync --extra convert + uv sync --all-extras uv pip install -e . - name: Run tests diff --git a/pyproject.toml b/pyproject.toml index 9b5310f..5681e24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ convert-duckdb = [ ] graphar = [ "graphar", + "PyYAML>=6.0", ] [project.scripts]