Skip to content

Commit

Permalink
Normalize mime types for validation. RDF/XML support
Browse files Browse the repository at this point in the history
  • Loading branch information
avillar committed Nov 18, 2024
1 parent 39d32ff commit 92755a1
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 12 deletions.
9 changes: 9 additions & 0 deletions ogc/bblocks/known-mimetypes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@ xml:
- application/xml
extensions:
- xml

yaml:
label: YAML
mimeType: application/x-yaml
aliases:
- text/yaml
extensions:
- yaml
- yml
17 changes: 13 additions & 4 deletions ogc/bblocks/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from mako import exceptions as mako_exceptions, template as mako_template
from ogc.na.util import is_url

from ogc.bblocks import mimetypes
from ogc.bblocks.models import BuildingBlock, BuildingBlockRegister
from ogc.bblocks.util import sanitize_filename
from ogc.bblocks.validation import Validator, ValidationItemSourceType, ValidationReportSection, ValidationItemSource, \
Expand Down Expand Up @@ -151,7 +152,8 @@ def _validate_resource(bblock: BuildingBlock,
require_fail: bool | None = None,
resource_url: str | None = None,
example_index: tuple[int, int] | None = None,
prefixes: dict[str, str] | None = None) -> ValidationReportItem | None:
prefixes: dict[str, str] | None = None,
file_format: str | None = None) -> ValidationReportItem | None:
if require_fail is None:
require_fail = filename.stem.endswith('-fail') and not example_index

Expand All @@ -165,7 +167,7 @@ def _validate_resource(bblock: BuildingBlock,
filename=output_filename,
example_index=int(example_idx),
snippet_index=int(snippet_idx),
language=filename.suffix[1:],
language=file_format,
source_url=resource_url,
)
else:
Expand All @@ -186,7 +188,8 @@ def _validate_resource(bblock: BuildingBlock,
base_uri=base_uri,
additional_shacl_closures=additional_shacl_closures,
schema_ref=schema_ref,
prefixes=prefixes)
prefixes=prefixes,
file_format=file_format)
any_validator_run = any_validator_run or (result is not False)

except Exception as unknown_exc:
Expand Down Expand Up @@ -279,6 +282,7 @@ def validate_test_resources(bblock: BuildingBlock,
resource_contents=extra_test_resource['contents'],
require_fail=extra_test_resource.get('require-fail', False),
resource_url=extra_test_resource['ref'] if isinstance(extra_test_resource['ref'], str) else None,
file_format=mimetypes.from_extension(fn.suffix[1:]),
)
if test_result:
all_results.append(test_result)
Expand All @@ -301,8 +305,9 @@ def validate_test_resources(bblock: BuildingBlock,
elif not add_snippets_formats:
add_snippets_formats = []

extension = FORMAT_ALIASES.get(snippet['language'], snippet['language']).replace('/', '.')
fn = bblock.files_path / (f"example_{example_id + 1}_{snippet_id + 1}"
f".{FORMAT_ALIASES.get(snippet['language'], snippet['language'])}")
f".{extension}")

output_fn = output_dir / sanitize_filename(example.get('base-output-filename', fn.name))
i = 0
Expand All @@ -314,6 +319,9 @@ def validate_test_resources(bblock: BuildingBlock,
f.write(code)

snippet['path'] = output_fn
snippet_language = snippet.get('language')
if snippet_language:
snippet_language = mimetypes.normalize(snippet_language)

example_result = _validate_resource(
bblock=bblock,
Expand All @@ -327,6 +335,7 @@ def validate_test_resources(bblock: BuildingBlock,
resource_url=snippet.get('ref'),
require_fail=False,
prefixes=example.get('prefixes'),
file_format=snippet_language,
)
if example_result:
all_results.append(example_result)
Expand Down
5 changes: 4 additions & 1 deletion ogc/bblocks/validation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ def __init__(self, bblock: BuildingBlock, register: BuildingBlockRegister):
self.register = register

@abstractmethod
def validate(self, filename: Path, output_filename: Path,
def validate(self,
filename: Path,
output_filename: Path,
report: ValidationReportItem,
contents: str | None = None,
schema_ref: str | None = None,
base_uri: str | None = None,
resource_url: str | None = None,
require_fail: bool | None = None,
prefixes: dict[str, str] | None = None,
file_format: str | None = None,
**kwargs) -> bool | None:
raise NotImplementedError

Expand Down
4 changes: 3 additions & 1 deletion ogc/bblocks/validation/json_.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@ def __init__(self, bblock: BuildingBlock, register: BuildingBlockRegister):
def validate(self, filename: Path, output_filename: Path, report: ValidationReportItem,
contents: str | None = None,
schema_ref: str | None = None,
file_format: str | None = None,
**kwargs) -> bool | None:

if filename.suffix not in ('.json', '.jsonld', '.yaml', '.yml'):
if filename.suffix not in ('.json', '.jsonld', '.yaml', '.yml')\
and file_format not in ('application/json', 'application/x-yaml'):
return False

file_from = 'examples' if report.source.type == ValidationItemSourceType.EXAMPLE else 'test resources'
Expand Down
24 changes: 18 additions & 6 deletions ogc/bblocks/validation/rdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
from ogc.bblocks.validation.uplift import Uplifter


NATIVE_RDF_LANGS = {
'application/ld+json': 'jsonld',
'text/turtle': 'ttl',
'application/rdf+xml': 'xml',
}


def shacl_validate(g: Graph, s: Graph, ont_graph: Graph | None = None) \
-> tuple[bool, Graph, str, dict[pyshacl.Shape, Sequence[Node]]]:
validator = pyshacl.Validator(g, shacl_graph=s, ont_graph=ont_graph, options={
Expand Down Expand Up @@ -131,9 +138,10 @@ def __init__(self, bblock: BuildingBlock, register: BuildingBlockRegister):
def _load_graph(self, filename: Path, output_filename: Path, report: ValidationReportItem,
contents: str | None = None,
base_uri: str | None = None,
prefixes: dict[str, str] | None = None) -> Graph | None | bool:
prefixes: dict[str, str] | None = None,
file_format: str | None = None) -> Graph | None | bool:
graph = False
if filename.suffix == '.json':
if filename.suffix == '.json' or file_format == 'application/json':
if self.jsonld_error:
report.add_entry(ValidationReportEntry(
section=ValidationReportSection.JSON_LD,
Expand Down Expand Up @@ -231,7 +239,7 @@ def _load_graph(self, filename: Path, output_filename: Path, report: ValidationR
if graph:
graph = self.uplifter.post_uplift(report, graph)

elif output_filename.suffix == '.jsonld':
elif output_filename.suffix == '.jsonld' or file_format == 'application/ld+json':

if contents:
jsonld_doc = load_yaml(content=contents)
Expand All @@ -258,9 +266,11 @@ def _load_graph(self, filename: Path, output_filename: Path, report: ValidationR
graph = Graph().parse(data=json.dumps(jsonld_doc), format='json-ld', base=base_uri)
graph = self.uplifter.post_uplift(report, graph)

elif output_filename.suffix in ('.ttl', '.jsonld'):
elif (output_filename.suffix in ('.ttl', '.jsonld', '.rdf')
or file_format in NATIVE_RDF_LANGS):
file_from = 'examples' if report.source.type == ValidationItemSourceType.EXAMPLE else 'test resources'
rdf_format = 'ttl' if output_filename.suffix == '.ttl' else 'json-ld'
rdf_format = NATIVE_RDF_LANGS.get(file_format,
'ttl' if output_filename.suffix == '.ttl' else 'json-ld')
try:
if contents:
# Prepend prefixes
Expand Down Expand Up @@ -299,8 +309,10 @@ def validate(self, filename: Path, output_filename: Path, report: ValidationRepo
base_uri: str | None = None,
additional_shacl_closures: list[str | Path] | None = None,
prefixes: dict[str, str] | None = None,
file_format: str | None = None,
**kwargs) -> bool | None:
graph = self._load_graph(filename, output_filename, report, contents, base_uri, prefixes)
graph = self._load_graph(filename, output_filename, report,
contents, base_uri, prefixes, file_format=file_format)

if graph is False:
return False
Expand Down

0 comments on commit 92755a1

Please sign in to comment.