Skip to content

Commit a49232b

Browse files
committed
Load SHACL vocab into validation graph
Load the whole SHACL vocabulary from the web and add it to the generated validation graph. This allows us to use additional information which can not be found in `rdflib`, such as labels and descriptions of builtin SHACL severities.
1 parent f48cb8d commit a49232b

1 file changed

Lines changed: 12 additions & 7 deletions

File tree

src/software_card_policies/data_model.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ class Severity:
9292
comment: str
9393
level: SeverityLevel
9494

95-
# TODO: ``rdfs:label`` is ``None`` for SHACL's builtin severities. They exist in the
96-
# SHACL source but the validator doesn't put them into the graph. Should we do it?
9795
def __str__(self):
9896
return self.label if self.label else str(self.level)
9997

@@ -162,7 +160,7 @@ def read_rdf_resource(source: Path | str) -> Graph:
162160
graph = Graph()
163161
graph.parse(source)
164162
for prefix, iri in PREFIXES.items():
165-
graph.bind(prefix, iri)
163+
graph.bind(prefix, iri, replace=True)
166164
return graph
167165

168166

@@ -197,7 +195,8 @@ def _create_sc_scalar_parameter(
197195
return graph.value(parameter.uri, SC.parameterDefaultValue, None)
198196

199197

200-
# TODO: Is it safe to modify the graph while iterating over it?
198+
# TODO: Don't modify the graph while iterating over it! Collect new triples first, then
199+
# insert at the end!
201200
def parameterize_graph(graph: Graph, config_parameters: Dict[str, Any]) -> Graph:
202201
# iterate over all declared parameters of type `sc:Parameter`
203202
for parameter_ref in graph.subjects(RDF.type, SC.Parameter):
@@ -237,7 +236,6 @@ def parameterize_graph(graph: Graph, config_parameters: Dict[str, Any]) -> Graph
237236
graph.add((s, p, o))
238237

239238
# remove all references to the parameter from the graph
240-
# TODO: Keep all `(parameter.uri, None, None)` for debugging purposes?
241239
graph.remove((parameter.uri, None, None))
242240
graph.remove((None, None, parameter.uri))
243241

@@ -254,9 +252,16 @@ def validate_graph(data_graph: Graph, shacl_graph: Graph) -> Tuple[bool, Graph]:
254252
do_owl_imports=True,
255253
js=True,
256254
)
257-
# TODO: Is this required? Or are the bindings transferred from the data graph?
255+
256+
# Read the whole SHACL vocabulary into the graph so that we can use additional info
257+
# such as labels and descriptions.
258+
validation_graph.parse(SH._NS)
259+
260+
# Bind namespace prefixes for better readability. These _should_ already be bound;
261+
# we're just making sure.
258262
for prefix, iri in PREFIXES.items():
259-
validation_graph.bind(prefix, iri)
263+
validation_graph.bind(prefix, iri, replace=True)
264+
260265
return conforms, validation_graph
261266

262267

0 commit comments

Comments
 (0)