Skip to content

Commit

Permalink
Report list of focus nodes for SHACL shapes
Browse files Browse the repository at this point in the history
  • Loading branch information
avillar committed Aug 1, 2023
1 parent 42f8e4f commit c6ce4c6
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
36 changes: 29 additions & 7 deletions ogc/bblocks/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
import jsonschema
import requests
from jsonschema.validators import validator_for
from ogc.na.annotate_schema import SchemaResolver
from ogc.na.util import validate as shacl_validate, load_yaml, is_url
from ogc.na.util import load_yaml, is_url
from pyparsing import ParseBaseException
from rdflib import Graph
from rdflib.term import Node
from yaml import MarkedYAMLError

from ogc.bblocks.util import BuildingBlock
import traceback
import pyshacl

OUTPUT_SUBDIR = 'output'
FORMAT_ALIASES = {
Expand Down Expand Up @@ -197,11 +198,23 @@ def validate_inner():
'Using SHACL files for validation:\n - ' + '\n - '.join(str(f) for f in shacl_files)
)
try:
shacl_report = shacl_validate(graph, shacl_graph)
if shacl_report.result:
report.add_info('SHACL', shacl_report.text)
else:
report.add_error('SHACL', shacl_report.text)
shacl_conforms, shacl_result, shacl_report, focus_nodes = shacl_validate(graph, shacl_graph)
report_add = report.add_info if shacl_conforms else report.add_error
report_add('SHACL', shacl_report)
if focus_nodes:
focus_nodes_report = ''
for shape, shape_focus_nodes in focus_nodes.items():
focus_nodes_report += f"Shape {shape.node}"
shape_path = shape.path()
if shape_path:
focus_nodes_report += f" (path {shape_path})"
focus_nodes_report += ": "
if not shape_focus_nodes:
focus_nodes_report += '*none*'
else:
focus_nodes_report += ','.join(str(x) for x in shape_focus_nodes)
focus_nodes_report += "\n"
report.add_info('SHACL', 'Focus nodes:\n' + focus_nodes_report)
except ParseBaseException as e:
if e.args:
query_lines = e.args[0].splitlines()
Expand Down Expand Up @@ -396,3 +409,12 @@ def validate_json(instance: Any, validator: jsonschema.Validator):
error = jsonschema.exceptions.best_match(validator.iter_errors(instance))
if error is not None:
raise error


def shacl_validate(g: Graph, s: Graph) -> tuple[bool, Graph, str, dict[pyshacl.Shape, Node]]:
validator = pyshacl.Validator(g, shacl_graph=s, options={
'advanced': True
})
focus_nodes: dict[pyshacl.Shape, Node] = {shape: shape.focus_nodes(g) for shape in validator.shacl_graph.shapes}
conforms, shacl_result, shacl_report = validator.run()
return conforms, shacl_result, shacl_report, focus_nodes
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ jsonschema==4.17.3
ogc-na>=0.3.2
rdflib @ git+https://github.com/avillar/[email protected]#egg=rdflib
requests~=2.31.0

pyparsing~=3.0.9
pyshacl~=0.21.0
rdflib~=6.3.2

0 comments on commit c6ce4c6

Please sign in to comment.