Graph integrity checking with SHACL shapes.
SHACL (Shapes Constraint Language) validates the Knowledge Graph structure and data integrity. Shapes are generated from DomainForge⢠policies and manually authored for complex constraints.
1
2
3
4
5
POST /graph/shacl/validate
{
"targetGraph": "production",
"shapes": "customer-validation-shapes"
}
1
2
3
4
5
6
7
8
9
10
11
{
"valid": false,
"violations": [
{
"node": "http://example.org/customer/123",
"constraint": "email-format",
"message": "Invalid email format",
"severity": "Violation"
}
]
}
Validates nodes of a specific type:
1
2
3
4
5
6
7
8
9
ex:EntityShape
a sh:NodeShape ;
sh:targetClass sea:Entity ;
sh:property [
sh:path rdfs:label ;
sh:minCount 1 ;
sh:datatype xsd:string ;
sh:message "Entity must have a label" ;
] .
Validates specific properties:
1
2
3
4
5
6
ex:FlowQuantityShape
a sh:PropertyShape ;
sh:path sea:quantity ;
sh:datatype xsd:decimal ;
sh:minInclusive 0 ;
sh:message "Flow quantity must be non-negative" .
1
2
3
4
5
6
7
8
9
10
11
ex:RequiredFieldsShape
a sh:NodeShape ;
sh:targetClass sea:Entity ;
sh:property [
sh:path rdfs:label ;
sh:minCount 1 ;
] ;
sh:property [
sh:path sea:inContext ;
sh:minCount 1 ;
] .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ex:UniqueNameShape
a sh:NodeShape ;
sh:targetClass sea:Entity ;
sh:sparql [
sh:message "Entity name must be unique within namespace" ;
sh:select """
SELECT $this ?name
WHERE {
$this rdfs:label ?name ;
sea:inContext ?ctx .
?other rdfs:label ?name ;
sea:inContext ?ctx .
FILTER ($this != ?other)
}
""" ;
] .
1
2
3
4
5
6
7
8
9
10
11
12
13
ex:FlowReferenceShape
a sh:NodeShape ;
sh:targetClass sea:Flow ;
sh:property [
sh:path sea:from ;
sh:class sea:Entity ;
sh:message "Flow 'from' must reference an existing Entity" ;
] ;
sh:property [
sh:path sea:to ;
sh:class sea:Entity ;
sh:message "Flow 'to' must reference an existing Entity" ;
] .
| Level | Description | Action |
|---|---|---|
Violation |
Must fix | Block deployment |
Warning |
Should fix | Log warning |
Info |
Informational | Track only |
1
2
3
4
5
# Validate graph against shapes
sea graph validate --shapes shapes/entity-shapes.ttl
# Validate specific graph
sea graph validate --graph production --shapes shapes/
1
2
3
4
5
6
7
8
9
10
from pyshacl import validate
result = validate(
data_graph,
shacl_graph=shapes_graph,
inference='rdfs',
abort_on_first=False,
)
conforms, graph, report_text = result
print(report_text)
| Error | Cause | Fix |
|---|---|---|
Missing required property |
Node lacks required field | Add missing property |
Datatype mismatch |
Wrong value type | Convert to correct type |
Cardinality violated |
Too few/many values | Adjust data |
Class constraint failed |
Reference wrong type | Fix reference target |