GaetanoParente's picture
Update src/validation/validator.py
4e0fede verified
raw
history blame
2.65 kB
import os
from rdflib import Graph, Literal, RDF, URIRef, Namespace
from rdflib.namespace import SKOS, XSD
from pyshacl import validate
class SemanticValidator:
def __init__(self):
# Definiamo i namespace
self.EX = Namespace("http://activa.ai/ontology/")
self.shapes_file = os.path.join(os.path.dirname(__file__), "shapes/schema_constraints.ttl")
# Carica le shapes se il file esiste, altrimenti usa grafo vuoto
if os.path.exists(self.shapes_file):
self.shacl_graph = Graph()
self.shacl_graph.parse(self.shapes_file, format="turtle")
print("🛡️ SHACL Constraints caricati.")
else:
print("⚠️ File SHACL non trovato. Validazione disabilitata.")
self.shacl_graph = None
def _json_to_rdf(self, triples):
"""Converte le triple JSON (Pydantic) in un grafo RDFLib in memoria."""
g = Graph()
g.bind("skos", SKOS)
g.bind("ex", self.EX)
for t in triples:
# Creiamo URI sanitizzati
subj_uri = URIRef(self.EX[t.subject.replace(" ", "_")])
obj_uri = URIRef(self.EX[t.object.replace(" ", "_")])
# Aggiungiamo il tipo Concept
g.add((subj_uri, RDF.type, SKOS.Concept))
g.add((subj_uri, SKOS.prefLabel, Literal(t.subject, lang="it")))
g.add((obj_uri, RDF.type, SKOS.Concept))
g.add((obj_uri, SKOS.prefLabel, Literal(t.object, lang="it")))
# Mappiamo il predicato (se è standard o custom)
if t.predicate == "skos:related" or t.predicate == "related":
pred = SKOS.related
elif t.predicate == "skos:broader" or t.predicate == "broader":
pred = SKOS.broader
else:
# Fallback su namespace custom per predicati non standard (es. situato_in)
pred = self.EX[t.predicate]
g.add((subj_uri, pred, obj_uri))
return g
def validate_batch(self, triples):
"""
Esegue la validazione SHACL sulle triple.
Ritorna (is_valid, report_text, rdf_graph)
"""
if not self.shacl_graph:
return True, "No Constraints", None
data_graph = self._json_to_rdf(triples)
print("🔍 Esecuzione Validazione SHACL...")
conforms, report_graph, report_text = validate(
data_graph,
shacl_graph=self.shacl_graph,
inference='rdfs',
serialize_report_graph=True
)
return conforms, report_text, data_graph