How to Use SHACL for Ontology Constraint Enforcement in Semantica: A Complete Guide
Semantica provides a first-class, three-stage pipeline—SHACLGenerator, serialize(), and _run_pyshacl—that transforms OWL-style ontologies into executable SHACL shapes and validates RDF data graphs against them.
Semantica treats SHACL (Shapes Constraint Language) as a core mechanism for data quality enforcement. Whether you're building knowledge graphs for AI pipelines or ensuring ontology compliance, the framework generates validatable SHACL shapes directly from your ontology definitions and integrates with pySHACL for robust validation. This guide walks through the complete implementation as found in semantica-agi/semantica.
The SHACL Pipeline: Three Core Components
Semantica's SHACL implementation consists of tightly integrated components spanning generation, serialization, and validation.
SHACLGenerator: Building Shapes from Ontologies
The SHACLGenerator class in semantica/ontology/ontology_generator.py (lines 779–822) transforms a Semantica OWL-style ontology dictionary into executable SHACL constraints. It constructs:
- A class index for O(1) lookups via
_build_class_index() - One
NodeShapeper OWL class via_generate_node_shapes() PropertyShapeattachments for each object/property via_attach_property_shapes()- Inheritance propagation (cycle-safe) via
_propagate_inheritance() - Quality-tier enforcement via
_apply_quality_tier()
The internal data model is represented by the SHACLGraph dataclass, which captures all generated shapes in a structured format before serialization.
Serialization: Turtle, JSON-LD, and N-Triples
The serialize() method (lines 842–854) converts SHACLGraph instances into three standard RDF formats:
generator = SHACLGenerator(quality_tier="strict")
shacl_graph = generator.generate(my_ontology_dict)
turtle_output = generator.serialize(shacl_graph, format="turtle")
jsonld_output = generator.serialize(shacl_graph, format="json-ld")
ntriples_output = generator.serialize(shacl_graph, format="ntriples")
These outputs can be written to files, streamed to validators, or stored in triple stores for reuse across your data pipeline.
_run_pyshacl: Executing Validation
The _run_pyshacl function in semantica/ontology/ontology_validator.py (lines 158–170) orchestrates actual validation by calling the external pySHACL library. First install the required dependency:
pip install semantica[shacl]
Then validate any data graph:
from semantica.ontology.ontology_validator import _run_pyshacl
report = _run_pyshacl(
data_graph=data_ttl,
shacl_graph=shacl_ttl,
data_graph_format="turtle"
)
The function returns a SHACLValidationReport containing:
conforms: Boolean validation resultviolations/warnings/info: StructuredSHACLViolation,SHACLWarning, andSHACLInfoobjects
Quality Tier Controls: Basic, Standard, and Strict
Semantica's quality-tier system (implemented in _apply_quality_tier, lines 1026–1035) lets you tune constraint strength:
| Tier | Behavior | Use Case |
|---|---|---|
| basic | Minimal constraints; only required property shapes | Rapid prototyping, flexible schemas |
| standard | Default tier; adds min/max cardinalities and datatype checks | Production knowledge graphs |
| strict | Closed shapes (closed=True) on every class |
Maximum data integrity, regulatory compliance |
Set the tier at initialization:
generator = SHACLGenerator(quality_tier="strict") # Enforces closed shapes
Complete Validation Workflow
The following example demonstrates the full pipeline from ontology definition to violation explanation:
from semantica.ontology.ontology_generator import SHACLGenerator
from semantica.ontology.ontology_validator import _run_pyshacl
# 1️⃣ Define your OWL-style ontology as a Python dictionary
my_ontology = {
"namespace": {"base_uri": "https://example.com/"},
"classes": [
{"name": "Person", "description": "A human being"},
{"name": "Organization", "description": "An organization"},
],
"properties": [
{"name": "name", "type": "string", "domain": ["Person", "Organization"]},
{"name": "memberOf", "type": "object", "domain": ["Person"], "range": ["Organization"]},
],
}
# 2️⃣ Generate SHACL shapes with strict enforcement
generator = SHACLGenerator(quality_tier="strict")
shacl_graph = generator.generate(my_ontology)
shacl_ttl = generator.serialize(shacl_graph, format="turtle")
# 3️⃣ Prepare your data graph (Turtle format)
data_ttl = """
@prefix ex: <https://example.com/> .
ex:alice a ex:Person ;
ex:name "Alice" ;
ex:memberOf ex:acme .
ex:acme a ex:Organization ;
ex:name "Acme Corp" .
"""
# 4️⃣ Execute validation
report = _run_pyshacl(data_ttl, shacl_ttl, data_graph_format="turtle")
# 5️⃣ Inspect results and explain violations
print("Conforms?", report.conforms)
if not report.conforms:
report.explain_violations() # Enriches violations with human-readable text
for violation in report.violations:
print(f"- {violation.explanation}")
Understanding Validation Reports
The SHACLValidationReport class provides structured access to validation outcomes without requiring LLM calls for explanation.
Key Attributes
report.conforms: Quick boolean check for compliancereport.violations: List of constraint failures that prevented conformancereport.warnings: Non-fatal constraint issuesreport.info: Informational messages about the validation process
Explaining Violations
Call explain_violations() to enrich each violation with human-readable descriptions based on an internal template map. This transformation happens entirely within the validator—no external LLM calls are required:
report.explain_violations()
for v in report.violations:
print(f"Severity: {v.severity}")
print(f"Shape: {v.shape_id}")
print(f"Explanation: {v.explanation}")
Integration Points
Semantica exposes SHACL functionality through multiple interfaces for different operational contexts.
Explorer API HTTP Service
The REST endpoint in semantica/explorer/routes/ontology.py wraps both generation and validation as HTTP services. The implementation includes patched constants for:
- Size limits: Maximum request body sizes for ontology and data graphs
- Timeout guards: Upper bounds on validation execution time
This enables SHACL validation as a microservice in distributed architectures.
RDFExporter Integration
When exporting knowledge graphs, RDFExporter.export_shacl() (tested in tests/visualization/test_visualization.py) allows optional inclusion of generated SHACL shapes alongside your data. This bundles constraints with their target graphs for portable, self-describing datasets.
Source File Reference
| File | Purpose | Key Symbols |
|---|---|---|
semantica/ontology/ontology_generator.py |
Shape generation and serialization | SHACLGenerator, SHACLGraph, _apply_quality_tier |
semantica/ontology/ontology_validator.py |
Validation execution and reporting | _run_pyshacl, SHACLValidationReport, SHACLViolation |
semantica/explorer/routes/ontology.py |
HTTP API service layer | Size/timeout-guarded endpoints |
tests/ontology/test_ontology_comprehensive.py |
Comprehensive test coverage | Generation, serialization, validation tests |
tests/visualization/test_visualization.py |
Exporter integration tests | RDFExporter.export_shacl() |
Summary
-
SHACLGenerator in
ontology_generator.pytransforms OWL ontologies intoSHACLGraphobjects through a six-stage pipeline with inheritance propagation and quality-tier controls. -
Three quality tiers—basic, standard, strict—let you balance flexibility against enforcement strength, with strict mode enabling closed shapes.
-
Serialization supports Turtle, JSON-LD, and N-Triples for interoperability with any standards-compliant SHACL processor.
-
_run_pyshacl in
ontology_validator.pyexecutes validation via pySHACL, returning structured reports withconformsflags and explainable violations. -
Integration options include direct Python API, HTTP microservices via the Explorer API, and bundled export through
RDFExporter.
Frequently Asked Questions
What is the minimum Python package requirement for SHACL validation in Semantica?
Semantica requires the [shacl] extra for validation functionality. Install with pip install semantica[shacl] to pull in pySHACL and its dependencies. Shape generation and serialization work without this extra, but _run_pyshacl will fail if pySHACL is missing.
How does the strict quality tier differ from standard enforcement?
Strict applies closed=True to every generated NodeShape, meaning data graphs cannot contain properties not explicitly defined in the ontology. Standard allows unspecified properties while still enforcing cardinalities and datatypes on declared properties. This distinction is implemented in _apply_quality_tier at lines 1026–1035 of ontology_generator.py.
Can I validate JSON-LD data graphs, or only Turtle?
The _run_pyshacl function accepts any format supported by pySHACL through the data_graph_format parameter. Valid options include "turtle", "json-ld", "n3", "nt", and "xml". The SHACL graph format is auto-detected, but data graphs require explicit format specification.
Are validation explanations generated by an LLM?
No. The explain_violations() method uses a built-in template map to transform raw SHACL violation data into human-readable strings. This design ensures deterministic, low-latency explanations without external API dependencies. The implementation resides in ontology_validator.py near the SHACLValidationReport class definition.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →