# How to Use SHACL for Ontology Constraint Enforcement in Semantica: A Complete Guide

> Learn to use SHACL for ontology constraint enforcement in Semantica with our guide. Discover how Semantica transforms OWL ontologies into SHACL shapes and validates RDF data.

- Repository: [Semantica /semantica](https://github.com/semantica-agi/semantica)
- Tags: how-to-guide
- Published: 2026-08-16

---

**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`](https://github.com/semantica-agi/semantica/blob/main/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 **`NodeShape`** per OWL class via `_generate_node_shapes()`
- **`PropertyShape`** attachments 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:

```python
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`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_validator.py) (lines 158–170) orchestrates actual validation by calling the external **pySHACL** library. First install the required dependency:

```bash
pip install semantica[shacl]

```

Then validate any data graph:

```python
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 result
- **`violations`** / **`warnings`** / **`info`**: Structured `SHACLViolation`, `SHACLWarning`, and `SHACLInfo` objects

## 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:

```python
generator = SHACLGenerator(quality_tier="strict")  # Enforces closed shapes

```

## Complete Validation Workflow

The following example demonstrates the full pipeline from ontology definition to violation explanation:

```python
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 compliance
- **`report.violations`**: List of constraint failures that prevented conformance
- **`report.warnings`**: Non-fatal constraint issues
- **`report.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:

```python
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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_generator.py) | Shape generation and serialization | `SHACLGenerator`, `SHACLGraph`, `_apply_quality_tier` |
| [`semantica/ontology/ontology_validator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_validator.py) | Validation execution and reporting | `_run_pyshacl`, `SHACLValidationReport`, `SHACLViolation` |
| [`semantica/explorer/routes/ontology.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/explorer/routes/ontology.py) | HTTP API service layer | Size/timeout-guarded endpoints |
| [`tests/ontology/test_ontology_comprehensive.py`](https://github.com/semantica-agi/semantica/blob/main/tests/ontology/test_ontology_comprehensive.py) | Comprehensive test coverage | Generation, serialization, validation tests |
| [`tests/visualization/test_visualization.py`](https://github.com/semantica-agi/semantica/blob/main/tests/visualization/test_visualization.py) | Exporter integration tests | `RDFExporter.export_shacl()` |

## Summary

- **SHACLGenerator** in [`ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/ontology_generator.py) transforms OWL ontologies into `SHACLGraph` objects 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.py`](https://github.com/semantica-agi/semantica/blob/main/ontology_validator.py) executes validation via pySHACL, returning structured reports with `conforms` flags 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`](https://github.com/semantica-agi/semantica/blob/main/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`](https://github.com/semantica-agi/semantica/blob/main/ontology_validator.py) near the `SHACLValidationReport` class definition.