Skip to content

Commit 7706428

Browse files
committed
Change SHACL "rules" to "shapes"
All metadata properties and references are changed. Legacy "shaclRules" and "rules.shacl" are still supported as input, but only "shaclShapes" will be generated in the output.
1 parent 90449d8 commit 7706428

File tree

5 files changed

+39
-23
lines changed

5 files changed

+39
-23
lines changed

ogc/bblocks/models.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,18 @@ def __init__(self, identifier: str, metadata_file: Path,
9292
self.output_openapi = self.annotated_path / 'openapi.yaml'
9393
self.output_openapi_30 = self.output_openapi.with_stem(f"{self.output_openapi.stem}-oas30")
9494

95-
shacl_rules = self.metadata.setdefault('shaclRules', [])
96-
default_shacl_rules = fp / 'rules.shacl'
97-
if default_shacl_rules.is_file():
98-
shacl_rules.append('rules.shacl')
99-
self.shacl_rules = set(r if is_url(r) else fp / r for r in shacl_rules)
95+
shacl_shapes = self.metadata.setdefault('shaclShapes', [])
96+
if not shacl_shapes and self.metadata.get('shaclRules'):
97+
shacl_shapes.extend(self.metadata.pop('shaclRules'))
98+
default_shacl_shapes = fp / 'shapes.shacl'
99+
if default_shacl_shapes.is_file():
100+
shacl_shapes.append('shapes.shacl')
101+
else:
102+
legacy_shacl_shapes = fp / 'rules.shacl'
103+
if legacy_shacl_shapes.is_file():
104+
shacl_shapes.append('rules.shacl')
105+
106+
self.shacl_shapes = set(r if is_url(r) else fp / r for r in shacl_shapes)
100107

101108
self.ontology = self._find_path_or_url('ontology',
102109
('ontology.ttl', 'ontology.owl'))
@@ -466,7 +473,9 @@ def __init__(self,
466473
if identifier in self.bblocks:
467474
continue
468475
dep_graph.add_node(identifier)
469-
dep_graph.add_edges_from([(d, identifier) for d in imported_bblock.get('dependsOn', ())])
476+
dep_graph.add_edges_from([(d, identifier)
477+
for d in imported_bblock.get('dependsOn', ())
478+
if d != identifier])
470479
for schema_url in imported_bblock.get('schema', {}).values():
471480
self.imported_bblock_files[schema_url] = identifier
472481
source_schema = imported_bblock.get('sourceSchema')
@@ -492,7 +501,9 @@ def __init__(self,
492501
if found_deps:
493502
bblock.metadata['dependsOn'] = list(found_deps)
494503
dep_graph.add_node(bblock.identifier)
495-
dep_graph.add_edges_from([(d, bblock.identifier) for d in bblock.metadata.get('dependsOn', ())])
504+
dep_graph.add_edges_from([(d, bblock.identifier)
505+
for d in bblock.metadata.get('dependsOn', ())
506+
if d != bblock.identifier])
496507

497508
for a, b in dep_graph.edges:
498509
if a not in self.bblocks and a not in self.imported_bblocks:
@@ -595,14 +606,14 @@ def find_dependencies(self, identifier: str, seen: tuple[str] = None) -> list[di
595606

596607
return dependencies
597608

598-
def get_inherited_shacl_rules(self, identifier: str) -> dict[str, set[str | Path]]:
609+
def get_inherited_shacl_shapes(self, identifier: str) -> dict[str, set[str | Path]]:
599610
rules: dict[str, set[str | Path]] = {}
600611
for dep in self.find_dependencies(identifier):
601612
if isinstance(dep, BuildingBlock):
602-
if dep.shacl_rules:
603-
rules[dep.identifier] = dep.shacl_rules
613+
if dep.shacl_shapes:
614+
rules[dep.identifier] = dep.shacl_shapes
604615
else:
605-
dep_rules = dep.get('shaclRules')
616+
dep_rules = dep.get('shaclShapes', dep.get('shaclRules'))
606617
if dep_rules:
607618
if isinstance(dep_rules, list):
608619
rules.setdefault(dep.get('itemIdentifier'), set()).update(dep_rules)

ogc/bblocks/postprocess.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,11 @@ def do_postprocess(bblock: BuildingBlock, light: bool = False) -> bool:
192192
snippet['url'] = f"{base_url}{path}"
193193

194194
if base_url:
195-
if bblock.shaclRules:
196-
if isinstance(bblock.shaclRules, list):
197-
bblock.metadata['shaclRules'] = {bblock.identifier: bblock.shacl_rules}
198-
bblock.metadata['shaclRules'] = {k: [urljoin(base_url, str(s)) for s in v]
199-
for k, v in bblock.shaclRules.items()}
195+
if bblock.shaclShapes:
196+
if isinstance(bblock.shaclShapes, list):
197+
bblock.metadata['shaclShapes'] = {bblock.identifier: bblock.shaclShapes}
198+
bblock.metadata['shaclShapes'] = {k: [urljoin(base_url, str(s)) for s in v]
199+
for k, v in bblock.shaclShapes.items()}
200200
if bblock.transforms:
201201
bblock.metadata['transforms'] = []
202202
for transform in bblock.transforms:

ogc/bblocks/register-context.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ context:
9292
'@id': prof:isProfileOf
9393
'@type': '@id'
9494
tags: dcat:keyword
95-
shaclRules:
95+
shaclShapes:
9696
'@id': bblocks:hasShaclRule
9797
'@type': '@id'
9898
'@container': '@index'

ogc/bblocks/schemas/bblock.schema.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,16 @@ properties:
186186
group:
187187
description: An identifier to group Building Blocks together
188188
type: string
189-
shaclRules:
189+
shaclShapes:
190190
description: List of SHACL files to use for RDF validation. Can be URLs or file paths.
191191
type: array
192192
items:
193193
type: string
194+
shaclRules:
195+
description: Legacy alias for `shaclShapes`.
196+
type: array
197+
items:
198+
type: string
194199
shaclClosures:
195200
description: |
196201
List of RDF files or URLs that will be used as SHACL closures for RDF validation. They will be merged with

ogc/bblocks/validation/rdf.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ def __init__(self, bblock: BuildingBlock, register: BuildingBlockRegister):
107107
self.closure_graph = Graph()
108108
self.shacl_graphs: dict[str, Graph] = {}
109109
self.shacl_errors: list[str] = []
110-
inherited_shacl_rules = register.get_inherited_shacl_rules(bblock.identifier)
111-
for shacl_bblock in list(inherited_shacl_rules.keys()):
110+
inherited_shacl_shapes = register.get_inherited_shacl_shapes(bblock.identifier)
111+
for shacl_bblock in list(inherited_shacl_shapes.keys()):
112112
bblock_shacl_files = set()
113-
for shacl_file in inherited_shacl_rules[shacl_bblock]:
113+
for shacl_file in inherited_shacl_shapes[shacl_bblock]:
114114
if isinstance(shacl_file, Path) or (isinstance(shacl_file, str) and not is_url(shacl_file)):
115115
# assume file
116116
shacl_file = str(os.path.relpath(bblock.files_path / shacl_file))
@@ -121,7 +121,7 @@ def __init__(self, bblock: BuildingBlock, register: BuildingBlockRegister):
121121
self.shacl_errors.append(f"Error retrieving {e.url}: {e}")
122122
except Exception as e:
123123
self.shacl_errors.append(f"Error processing {shacl_file}: {str(e)}")
124-
inherited_shacl_rules[shacl_bblock] = bblock_shacl_files
124+
inherited_shacl_shapes[shacl_bblock] = bblock_shacl_files
125125

126126
for shacl_closure in bblock.shaclClosures or ():
127127
try:
@@ -131,7 +131,7 @@ def __init__(self, bblock: BuildingBlock, register: BuildingBlockRegister):
131131
except Exception as e:
132132
self.shacl_errors.append(f"Error processing {shacl_closure}: {str(e)}")
133133

134-
bblock.metadata['shaclRules'] = inherited_shacl_rules
134+
bblock.metadata['shaclShapes'] = inherited_shacl_shapes
135135

136136
self.uplifter = Uplifter(self.bblock)
137137

0 commit comments

Comments
 (0)