Fix TripletStore initialization and store method; update notebooks

This commit is contained in:
KaifAhmad1
2025-12-20 21:10:50 +05:30
parent 35760f97aa
commit fe1d8c425c
3 changed files with 266 additions and 35 deletions
@@ -25,21 +25,37 @@
"pip install semantica[all]\n",
"```\n",
"\n",
"## Workflow: Build KG \u2192 Generate Ontology \u2192 Create Semantic Layer \u2192 Export RDF \u2192 Triplet Store\n"
"## Workflow: Build KG Generate Ontology Create Semantic Layer Export RDF \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING: Ignoring invalid distribution ~gno (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~lotly (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~ython-socketio (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~gno (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~lotly (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~ython-socketio (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~gno (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~lotly (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n",
"WARNING: Ignoring invalid distribution ~ython-socketio (C:\\Users\\Mohd Kaif\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages)\n"
]
}
],
"source": [
"!pip install semantica\n"
"!pip install -qU semantica\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
@@ -58,9 +74,22 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 3,
"metadata": {},
"outputs": [],
"outputs": [
{
"data": {
"text/html": [
"<div style='font-family: monospace;'><h4>🧠 Semantica - 📊 Current Progress</h4><table style='width: 100%; border-collapse: collapse;'><tr><th>Status</th><th>Action</th><th>Module</th><th>Submodule</th><th>File</th><th>Time</th></tr><tr><td>✅</td><td>Semantica is building</td><td>🧠 kg</td><td>GraphBuilder</td><td>-</td><td>0.13s</td></tr><tr><td>🔄</td><td>Semantica is building</td><td>🧠 kg</td><td>EntityResolver</td><td>-</td><td>7.37s</td></tr><tr><td>✅</td><td>Semantica is deduplicating</td><td>🔄 deduplication</td><td>DuplicateDetector</td><td>-</td><td>0.09s</td></tr><tr><td>✅</td><td>Semantica is deduplicating</td><td>🔄 deduplication</td><td>SimilarityCalculator</td><td>-</td><td>0.01s</td></tr><tr><td>✅</td><td>Semantica is resolving</td><td>⚠️ conflicts</td><td>ConflictDetector</td><td>-</td><td>0.00s</td></tr><tr><td>✅</td><td>Semantica is generating</td><td>📚 ontology</td><td>OntologyGenerator</td><td>-</td><td>0.06s</td></tr><tr><td>✅</td><td>Semantica is generating</td><td>📚 ontology</td><td>ClassInferrer</td><td>-</td><td>0.01s</td></tr><tr><td>✅</td><td>Semantica is generating</td><td>📚 ontology</td><td>PropertyGenerator</td><td>-</td><td>0.01s</td></tr><tr><td>✅</td><td>Semantica is exporting</td><td>💾 export</td><td>RDFExporter</td><td>-</td><td>0.01s</td></tr><tr><td>✅</td><td>Semantica is storing</td><td>🗄️ triplet_store</td><td>BulkLoader</td><td>-</td><td>3.01s</td></tr></table></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"builder = GraphBuilder()\n",
"\n",
@@ -90,7 +119,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
@@ -107,7 +136,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
@@ -159,9 +188,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Exported knowledge graph to knowledge_graph.ttl\n"
]
}
],
"source": [
"exporter = RDFExporter()\n",
"# Export Knowledge Graph\n",
@@ -169,23 +206,6 @@
"print(\"Exported knowledge graph to knowledge_graph.ttl\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 5: Store in Triplet Store\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"triplet_store = TripletStore()\n",
"triplet_store.store(knowledge_graph, ontology)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
@@ -196,16 +216,44 @@
"- Knowledge Graph Built\n",
"- Ontology Generated\n",
"- Semantic Layer Created with Mappings\n",
"- RDF Export Completed\n",
"- Triplet Store Storage Completed\n"
"- RDF Export Completed\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
}
+20
View File
@@ -0,0 +1,20 @@
<e1> a <Person> ;
semantica:text "" ;
semantica:confidence 1.0 .
<e2> a <Person> ;
semantica:text "" ;
semantica:confidence 1.0 .
<e3> a <Organization> ;
semantica:text "" ;
semantica:confidence 1.0 .
<e4> a <Project> ;
semantica:text "" ;
semantica:confidence 1.0 .
<e1> <reports_to> <e2> .
<e1> <works_for> <e3> .
<e2> <works_for> <e3> .
<e1> <works_on> <e4> .
+166 -3
View File
@@ -93,6 +93,11 @@ class TripletStore:
backend_config = self.config.copy()
if self.endpoint:
backend_config["endpoint"] = self.endpoint
else:
backend_config["endpoint"] = triplet_store_config.get(
"blazegraph_endpoint",
"http://localhost:9999/blazegraph"
)
self._store_backend = BlazegraphStore(**backend_config)
@@ -101,9 +106,12 @@ class TripletStore:
backend_config = self.config.copy()
if self.endpoint:
# JenaStore might use different param names or structure
# Assuming JenaStore accepts endpoint or url
backend_config["url"] = self.endpoint
backend_config["endpoint"] = self.endpoint
else:
backend_config["endpoint"] = triplet_store_config.get(
"jena_endpoint",
"http://localhost:3030/ds"
)
self._store_backend = JenaStore(**backend_config)
@@ -113,6 +121,11 @@ class TripletStore:
backend_config = self.config.copy()
if self.endpoint:
backend_config["endpoint"] = self.endpoint
else:
backend_config["endpoint"] = triplet_store_config.get(
"rdf4j_endpoint",
"http://localhost:8080/rdf4j-server"
)
self._store_backend = RDF4JStore(**backend_config)
@@ -122,6 +135,156 @@ class TripletStore:
self.logger.error(f"Failed to initialize {self.backend_type} backend: {e}")
raise ProcessingError(f"Failed to initialize backend: {e}")
def store(
self,
knowledge_graph: Union[Dict[str, Any], Any],
ontology: Union[Dict[str, Any], Any],
**options
) -> Dict[str, Any]:
"""
Store knowledge graph and ontology in the triplet store.
Args:
knowledge_graph: Knowledge graph dictionary or object
ontology: Ontology dictionary or object
**options: Additional options
Returns:
Operation status
"""
# Convert inputs to dictionaries if they are objects
if hasattr(knowledge_graph, "to_dict"):
knowledge_graph = knowledge_graph.to_dict()
if hasattr(ontology, "to_dict"):
ontology = ontology.to_dict()
triplets = []
# Standard Namespaces
RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
RDFS_SUBCLASS = "http://www.w3.org/2000/01/rdf-schema#subClassOf"
OWL_CLASS = "http://www.w3.org/2002/07/owl#Class"
OWL_OBJECT_PROPERTY = "http://www.w3.org/2002/07/owl#ObjectProperty"
OWL_DATATYPE_PROPERTY = "http://www.w3.org/2002/07/owl#DatatypeProperty"
RDFS_DOMAIN = "http://www.w3.org/2000/01/rdf-schema#domain"
RDFS_RANGE = "http://www.w3.org/2000/01/rdf-schema#range"
# 1. Process Ontology
classes = ontology.get("classes", [])
properties = ontology.get("properties", [])
for cls in classes:
# Class definition
cls_uri = cls.get("uri") or cls.get("id") or cls.get("name")
if not cls_uri:
continue
if not cls_uri.startswith("http") and not cls_uri.startswith("urn:"):
# Fallback if no URI provided
cls_uri = f"urn:class:{cls_uri}"
triplets.append(Triplet(cls_uri, RDF_TYPE, OWL_CLASS))
# Hierarchy
parent = cls.get("parent") or cls.get("subClassOf")
if parent:
parent_uri = parent
if not parent.startswith("http") and not parent.startswith("urn:"):
parent_uri = f"urn:class:{parent}"
triplets.append(Triplet(cls_uri, RDFS_SUBCLASS, parent_uri))
for prop in properties:
prop_uri = prop.get("uri") or prop.get("id") or prop.get("name")
if not prop_uri:
continue
if not prop_uri.startswith("http") and not prop_uri.startswith("urn:"):
prop_uri = f"urn:property:{prop_uri}"
# Determine property type (Object or Datatype)
# Default to ObjectProperty if not specified
prop_type = prop.get("type", OWL_OBJECT_PROPERTY)
if prop_type == "datatype":
prop_type = OWL_DATATYPE_PROPERTY
elif prop_type == "object":
prop_type = OWL_OBJECT_PROPERTY
triplets.append(Triplet(prop_uri, RDF_TYPE, prop_type))
if "domain" in prop:
domains = prop["domain"]
if isinstance(domains, str):
domains = [domains]
for domain in domains:
domain_uri = domain
if not domain.startswith("http") and not domain.startswith("urn:"):
domain_uri = f"urn:class:{domain}"
triplets.append(Triplet(prop_uri, RDFS_DOMAIN, domain_uri))
if "range" in prop:
ranges = prop["range"]
if isinstance(ranges, str):
ranges = [ranges]
for range_ in ranges:
range_uri = range_
if not range_.startswith("http") and not range_.startswith("urn:"):
range_uri = f"urn:class:{range_}"
triplets.append(Triplet(prop_uri, RDFS_RANGE, range_uri))
# 2. Process Knowledge Graph
entities = knowledge_graph.get("entities", [])
relationships = knowledge_graph.get("relationships", [])
entity_map = {} # Map IDs to URIs
for entity in entities:
entity_id = entity.get("id")
if not entity_id:
continue
entity_uri = entity.get("uri")
if not entity_uri:
entity_uri = f"urn:entity:{entity_id}"
entity_map[entity_id] = entity_uri
# Entity Type
entity_type = entity.get("type")
if entity_type:
type_uri = entity_type
if not entity_type.startswith("http") and not entity_type.startswith("urn:"):
type_uri = f"urn:class:{entity_type}"
triplets.append(Triplet(entity_uri, RDF_TYPE, type_uri))
# Entity Properties
props = entity.get("properties", {})
for k, v in props.items():
prop_uri = k
if not k.startswith("http") and not k.startswith("urn:"):
prop_uri = f"urn:property:{k}"
triplets.append(Triplet(entity_uri, prop_uri, str(v)))
for rel in relationships:
source_id = rel.get("source")
target_id = rel.get("target")
rel_type = rel.get("type") or rel.get("label")
if not source_id or not target_id or not rel_type:
continue
source_uri = entity_map.get(source_id, f"urn:entity:{source_id}")
target_uri = entity_map.get(target_id, f"urn:entity:{target_id}")
rel_uri = rel_type
if not rel_type.startswith("http") and not rel_type.startswith("urn:"):
rel_uri = f"urn:property:{rel_type}"
triplets.append(Triplet(source_uri, rel_uri, target_uri))
# Bulk load all triplets
return self.add_triplets(triplets, **options)
def add_triplet(self, triplet: Triplet, **options) -> Dict[str, Any]:
"""
Add a single triplet to the store.