Spaces:
Sleeping
Sleeping
| """JSON serialization and deserialization for the knowledge graph.""" | |
| from __future__ import annotations | |
| import json | |
| import logging | |
| from datetime import datetime | |
| from pathlib import Path | |
| from typing import Optional | |
| from .graph_manager import KnowledgeGraph | |
| from .schema import ConceptNode, Edge | |
| logger = logging.getLogger(__name__) | |
| DEFAULT_PATH = Path(__file__).parent.parent / "data" / "knowledge_graph.json" | |
| def save_graph(kg: KnowledgeGraph, path: Optional[Path] = None) -> Path: | |
| """Save knowledge graph to JSON file.""" | |
| path = Path(path) if path else DEFAULT_PATH | |
| path.parent.mkdir(parents=True, exist_ok=True) | |
| edges = [] | |
| for src, tgt, edata in kg.G.edges(data=True): | |
| # Ensure source_id and target_id are always present | |
| edge_dict = dict(edata) | |
| edge_dict["source_id"] = src | |
| edge_dict["target_id"] = tgt | |
| edges.append(edge_dict) | |
| data = { | |
| "metadata": { | |
| "version": "0.1", | |
| "created": datetime.now().isoformat(), | |
| "stats": kg.stats(), | |
| }, | |
| "concepts": {nid: node.to_dict() for nid, node in kg._index.items()}, | |
| "edges": edges, | |
| } | |
| with open(path, "w", encoding="utf-8") as f: | |
| json.dump(data, f, ensure_ascii=False, indent=2) | |
| logger.info(f"saved graph to {path}: {kg.stats()['n_concepts']} concepts, {kg.stats()['n_edges']} edges") | |
| return path | |
| def load_graph(path: Optional[Path] = None) -> KnowledgeGraph: | |
| """Load knowledge graph from JSON file.""" | |
| path = Path(path) if path else DEFAULT_PATH | |
| if not path.exists(): | |
| logger.info(f"no graph file at {path}, returning empty graph") | |
| return KnowledgeGraph() | |
| with open(path, "r", encoding="utf-8") as f: | |
| data = json.load(f) | |
| kg = KnowledgeGraph() | |
| for nid, ndata in data.get("concepts", {}).items(): | |
| node = ConceptNode.from_dict(ndata) | |
| kg.add_concept(node) | |
| for edata in data.get("edges", []): | |
| try: | |
| edge = Edge.from_dict(edata) | |
| kg.add_edge(edge) | |
| except (TypeError, KeyError) as e: | |
| logger.warning(f"skipping malformed edge: {e}") | |
| continue | |
| stats = kg.stats() | |
| logger.info(f"loaded graph from {path}: {stats['n_concepts']} concepts, {stats['n_edges']} edges") | |
| return kg | |