How to Validate Knowledge Graphs Against SHACL Shapes Using Semantica's OntologyValidator

Semantica's OntologyValidator leverages the pySHACL library to verify whether RDF knowledge graphs conform to SHACL constraints, returning a detailed report of violations and conformance status.

The OntologyValidator in the semantica-agi/semantica repository provides a production-ready interface for validating semantic data quality. Integrated with pySHACL and rdflib, it checks knowledge graphs against SHACL shapes either generated from OWL ontologies or supplied manually, with built-in safeguards for timeouts and memory limits.

Architecture Overview

The validation system consists of three core components that work together to ensure data integrity across your knowledge graphs.

SHACLGenerator

Located in semantica/ontology/ontology_generator.py, the SHACLGenerator class converts Semantica OWL ontology dictionaries into SHACL shapes. It supports multiple quality tiers—basic, standard, and strict—that control the strictness of constraint generation. The generator outputs shapes in Turtle, JSON-LD, or N-Triples format, which the validator consumes as input.

OntologyValidator

The validate_shacl function in semantica/ontology/ontology_validator.py serves as the primary entry point. This function accepts an RDF data graph and a SHACL shapes string, executes the validation via pySHACL, and enforces configurable limits on execution time and graph size. It raises ProcessingError when dependencies are missing or when validation exceeds defined thresholds.

SHACLValidationReport and SHACLViolation

Validation results return as a SHACLValidationReport object containing:

  • conforms: Boolean indicating overall validity
  • violations: List of SHACLViolation objects detailing constraint breaches
  • warnings and infos: Non-fatal issues for debugging

Each SHACLViolation captures the focus_node, path, message, and severity level, enabling precise identification of data quality issues.

Step-by-Step Validation Workflow

The validation process follows a clear pipeline from shape generation to result inspection.

  1. Generate or load SHACL shapes using SHACLGenerator or by loading existing Turtle/JSON-LD files.
  2. Parse the target knowledge graph into an rdflib.Graph object from any RDF serialization format.
  3. Invoke validate_shacl with the data graph, shapes string, and optional limits for triples, bytes, and timeout duration.
  4. Analyze the SHACLValidationReport to determine conformance and iterate on any reported violations.

This workflow is exposed programmatically in semantica/ontology/ontology_validator.py and mirrors the HTTP endpoint logic found in semantica/explorer/routes/ontology.py.

Practical Code Examples

Generating SHACL Shapes from an Ontology

Before validation, generate constraints from your ontology definition:

import json
from semantica.ontology.ontology_generator import SHACLGenerator

# Load a Semantica ontology dictionary

with open("my_ontology.json") as f:
    ontology_dict = json.load(f)

# Initialize generator with quality tier

gen = SHACLGenerator(quality_tier="strict")
shacl_graph = gen.generate(ontology_dict)

# Serialize to Turtle format for validation

shacl_turtle = gen.serialize(shacl_graph, format="turtle")

Validating a Knowledge Graph

Execute validation against your RDF data:

from rdflib import Graph
from semantica.ontology.ontology_validator import validate_shacl

# Load target knowledge graph

data_graph = Graph()
data_graph.parse("knowledge_graph.ttl", format="turtle")

# Run validation with safety limits

report = validate_shacl(
    data_graph=data_graph,
    shacl_str=shacl_turtle,
    max_shacl_triples=5000,
    max_shacl_bytes=2_000_000,
    timeout_seconds=30,
)

# Check results

if report.conforms:
    print("Graph conforms to SHACL shapes")
else:
    for violation in report.violations:
        print(f"Node: {violation.focus_node}")
        print(f"Path: {violation.path}")
        print(f"Severity: {violation.severity}")
        print(f"Message: {violation.message}")
        print("---")

Using Custom SHACL Shapes

Skip generation and validate against existing shapes:

with open("custom_shapes.ttl") as f:
    custom_shacl = f.read()

report = validate_shacl(
    data_graph=data_graph,
    shacl_str=custom_shacl
)

Handling Large Graphs and Timeouts

Protect against runaway validation jobs using limit parameters:

report = validate_shacl(
    data_graph=data_graph,
    shacl_str=shacl_turtle,
    max_shacl_triples=10_000,    # Abort if shapes exceed 10k triples

    max_shacl_bytes=5_000_000,   # Abort if shape file > 5MB

    timeout_seconds=60           # Hard stop after 60 seconds

)

These limits prevent memory exhaustion and ensure the validator remains responsive under load, as implemented in the production routes at semantica/explorer/routes/ontology.py.

Full End-to-End Example

Combine generation and validation in a single pipeline:

import json
from rdflib import Graph
from semantica.ontology.ontology_generator import SHACLGenerator
from semantica.ontology.ontology_validator import validate_shacl

# Step 1: Generate shapes from ontology

with open("ontology.json") as f:
    ontology = json.load(f)

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

# Step 2: Load knowledge graph

kg = Graph()
kg.parse("data_graph.ttl", format="turtle")

# Step 3: Validate

report = validate_shacl(
    data_graph=kg,
    shacl_str=shacl_turtle,
    timeout_seconds=20
)

# Step 4: Report results

print(f"Conforms: {report.conforms}")
for violation in report.violations:
    print(f"{violation.focus_node} - {violation.path}: {violation.message}")

Key Configuration Options

When calling validate_shacl, consider these performance and safety parameters:

  • max_shacl_triples: Integer limit on the number of triples in the shapes graph (default varies by implementation).
  • max_shacl_bytes: Maximum byte size of the SHACL string to prevent parsing of oversized constraint files.
  • timeout_seconds: Hard time limit for the pySHACL validation process to prevent hanging on complex constraint checks.
  • quality_tier: When using SHACLGenerator, choose basic for minimal constraints, standard for typical OWL coverage, or strict for comprehensive validation rules.

Summary

  • Semantica's OntologyValidator in semantica/ontology/ontology_validator.py provides the validate_shacl function for checking RDF conformance against SHACL constraints.
  • The SHACLGenerator in semantica/ontology/ontology_generator.py creates validation shapes from OWL ontologies with configurable quality tiers (basic, standard, strict).
  • Validation returns a SHACLValidationReport containing boolean conformance status and detailed SHACLViolation objects with focus nodes, paths, and messages.
  • Built-in limits (max_shacl_triples, max_shacl_bytes, timeout_seconds) protect against resource exhaustion when processing large knowledge graphs.
  • The validator integrates pySHACL and rdflib to support any RDF serialization format while raising ProcessingError for missing dependencies or limit violations.

Frequently Asked Questions

What is the difference between SHACLGenerator and OntologyValidator?

SHACLGenerator creates constraint definitions from OWL ontologies, while OntologyValidator checks actual data graphs against those constraints. The generator produces the "rules" (SHACL shapes), and the validator tests whether your knowledge graph "follows" those rules. Both reside in the semantica/ontology/ directory but serve distinct phases of the data quality pipeline.

How do I handle validation timeouts for large knowledge graphs?

Set the timeout_seconds parameter in validate_shacl to enforce a hard limit on processing time. For extremely large graphs, also configure max_shacl_triples and max_shacl_bytes to prevent memory issues. If validation consistently times out, consider splitting your knowledge graph into smaller subgraphs or using the basic quality tier to reduce constraint complexity.

Can I use custom SHACL shapes instead of generated ones?

Yes. The validate_shacl function accepts any valid SHACL string via the shacl_str parameter, regardless of origin. You can load shapes from external .ttl files, manually crafted constraints, or third-party shape libraries. Simply read the file contents into a string and pass it to the validator alongside your data graph.

What information does the SHACLValidationReport contain?

The report provides a conforms boolean indicating overall validity, plus three lists of objects: violations (constraint failures), warnings (potential issues), and infos (informational messages). Each violation includes the specific focus_node (the problematic resource), the path (the property involved), a human-readable message, and the severity level, enabling precise debugging of data quality issues.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →