# How to Validate Knowledge Graphs Against SHACL Constraints in Semantica

> Learn how to validate knowledge graphs against SHACL constraints using Semantica. Our pipeline generates SHACL shapes and executes validation via Python APIs, CLI, and HTTP endpoints.

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

---

**Semantica validates knowledge graphs against SHACL constraints through a complete pipeline that generates SHACL shapes from ontologies and executes validation via pySHACL, accessible through Python APIs, CLI commands, and HTTP endpoints.**

The `semantica-agi/semantica` repository provides a production-ready framework for **SHACL-based validation** of RDF knowledge graphs. Whether you need programmatic validation in Python, command-line tooling, or REST API integration, Semantica's architecture covers all three interfaces with consistent underlying logic.

## Generating SHACL Shapes from Ontologies

All validation starts with **SHACL shape generation**. The `SHACLGenerator` class in [`semantica/ontology/ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_generator.py) transforms OWL-style ontology dictionaries into executable SHACL constraints.

### The Generation Pipeline

The generator executes five sequential steps:

1. **`_build_class_index`** – Indexes all classes from the ontology dictionary
2. **`_attach_property_shapes`** – Creates `NodeShape` instances and attaches property shapes to each class
3. **`_propagate_inheritance`** – Propagates inherited shapes through the class hierarchy
4. **`_apply_quality_tier`** – Applies validation strictness (e.g., *strict* mode closes all shapes)
5. **`serialize`** – Outputs the final `SHACLGraph` to Turtle, JSON-LD, or N-Triples

```python
from semantica.ontology.ontology_generator import SHACLGenerator

# Define your ontology as a dictionary

ontology = {
    "classes": [
        {"uri": "https://example.org/Person", "label": "Person"},
        {"uri": "https://example.org/Organization", "label": "Organization"},
    ],
    "properties": [
        {
            "uri": "https://example.org/name",
            "domain": "https://example.org/Person",
            "range": "http://www.w3.org/2001/XMLSchema#string",
        }
    ],
    "namespace": {"base_uri": "https://example.org/"},
}

# Generate strict SHACL shapes

generator = SHACLGenerator(quality_tier="strict")
shacl_graph = generator.generate(ontology)
shacl_turtle = generator.serialize(shacl_graph, format="turtle")

print(shacl_turtle)

```

## Running SHACL Validation Programmatically

Once you have SHACL shapes, use `OntologyEngine.validate_graph` to validate any RDF data graph. This method, defined in [`semantica/ontology/ontology_validator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_validator.py), wraps **pyshacl.validate** with Semantica's structured reporting.

### The Validation Flow

The engine performs these operations:

- Parses both data graph and SHACL shapes using **rdflib**
- Invokes `pyshacl.validate` with appropriate format parameters
- Converts raw pySHACL results into a `SHACLValidationReport` object

```python
from semantica.ontology.ontology_validator import OntologyEngine

# Load your data graph (Turtle format)

with open("my_knowledge_graph.ttl") as f:
    data_turtle = f.read()

# Initialize engine and validate

engine = OntologyEngine()
report = engine.validate_graph(
    data_graph_str=data_turtle,
    shacl=shacl_turtle,           # From generator above

    data_graph_format="turtle",
    shacl_format="turtle",
)

# Inspect results

print(f"Conforms: {report.conforms}")
print(report.summary())

# Iterate through violations

for violation in report.violations:
    print(f"Node: {violation.focus_node}")
    print(f"Severity: {violation.severity}")
    print(f"Message: {violation.message}")

```

The `SHACLValidationReport` provides:

- **`conforms`**: Boolean indicating overall validation status
- **`violations`**: List of `SHACLViolation` objects with `focus_node`, `result_path`, `severity`, and `message`
- **`summary()`**: Human-readable string summarizing results

## CLI Validation for Automation

For shell scripts and CI/CD pipelines, Semantica exposes validation through the `validate shacl` subcommand in [`semantica/cli.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py) (lines 2754-2800).

```bash

# Validate a SHACL file against an ontology by URI

semantica validate shacl \
    --shapes my_shapes.ttl \
    --strictness strict \
    https://example.org/ontology

```

CLI options include:

- **`--shapes`**: Path to SHACL Turtle file
- **`--strictness`**: Quality tier (`permissive`, `standard`, or `strict`)
- **Positional argument**: Target ontology URI to fetch and validate against

Output formats include concise summaries and structured JSON for downstream processing.

## HTTP API Endpoint for Service Integration

The FastAPI route at `POST /ontology/shacl/validate` in [`semantica/explorer/routes/ontology.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/explorer/routes/ontology.py) (lines 2714-2865) enables remote validation with request size limits and detailed response structures.

```bash
curl -X POST https://semantica.example.com/ontology/shacl/validate \
     -H "Content-Type: application/json" \
     -d '{
           "uri": "https://example.org/ontology",
           "shacl_turtle": "@prefix sh: <http://www.w3.org/ns/shacl#> .\n@prefix ex: <https://example.org/> .\nex:PersonShape a sh:NodeShape ; sh:targetClass ex:Person ; sh:property [ sh:path ex:name ; sh:minCount 1 ] ."
         }' | jq .

```

The `ShaclValidationResponse` contains:

| Field | Type | Description |
|-------|------|-------------|
| `conforms` | boolean | Overall validation result |
| `status` | string | HTTP-style status code |
| `message` | string | Human-readable status description |
| `violations` | array | List of `ShaclViolation` objects |

## Key Implementation Files

| Component | File Path | Purpose |
|-----------|-----------|---------|
| Shape generation | [`semantica/ontology/ontology_generator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_generator.py) | `SHACLGenerator` class and `SHACLGraph` construction |
| Validation execution | [`semantica/ontology/ontology_validator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_validator.py) | `OntologyEngine.validate_graph`, `_run_pyshacl`, `SHACLValidationReport` |
| CLI interface | [`semantica/cli.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/cli.py) | `validate_shacl` command implementation |
| HTTP endpoint | [`semantica/explorer/routes/ontology.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/explorer/routes/ontology.py) | `POST /ontology/shacl/validate` route |

## Summary

- **Generate SHACL shapes** with `SHACLGenerator` from ontology dictionaries, with configurable quality tiers
- **Validate programmatically** through `OntologyEngine.validate_graph` which wraps pySHACL with structured reporting
- **Automate via CLI** using `semantica validate shacl` for shell-based workflows
- **Integrate via HTTP** through the FastAPI endpoint for microservice architectures
- **All interfaces share** the same underlying validation logic in [`semantica/ontology/ontology_validator.py`](https://github.com/semantica-agi/semantica/blob/main/semantica/ontology/ontology_validator.py)

## Frequently Asked Questions

### What SHACL features does Semantica support?

Semantica supports all pySHACL-validatable constraints including `sh:minCount`, `sh:maxCount`, `sh:datatype`, `sh:class`, `sh:nodeKind`, and closed shapes via `sh:closed`. The `quality_tier` parameter in `SHACLGenerator` controls whether shapes are open or closed.

### How does Semantica handle validation performance for large graphs?

The `validate_graph` method accepts string inputs and uses rdflib's efficient parsers. For very large graphs, consider streaming via the CLI or API, which process graphs incrementally before invoking pySHACL's native validation engine.

### Can I use existing SHACL files without generating shapes from ontologies?

Yes. Pass any valid SHACL Turtle directly to `OntologyEngine.validate_graph` as the `shacl` parameter, or via the CLI `--shapes` flag. The generator is optional when you have pre-authored constraint definitions.

### What's the difference between quality tiers in shape generation?

- **permissive**: Minimal constraints, allows additional properties
- **standard**: Balanced constraints with typical closed-world assumptions
- **strict**: Closes all shapes (`sh:closed true`), enforcing exact schema compliance