diff --git a/CHANGELOG.md b/CHANGELOG.md index 98747bb..ee41293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](https://semver.org/) +## [Unreleased] + +### Fixed + +- `prov:generatedBy` in output graphs now refers to a plugin IRI instead of a literal + +### Changed + +- Keep original output ("No explanations found.") if no inconsistencies found with Validate plugin + + ## [1.0.0beta1] 2024-07-01 ### Fixed @@ -13,14 +24,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p ### Changed - complete validation for IRI parameters -- Remove "Annnotate inferred subclass axioms" parameter +- remove "Annnotate inferred subclass axioms" parameter in Reason plugin ## [1.0.0alpha3] 2024-06-28 ### Added - "Annotate inferred axioms" parameter in Reason plugin -- "Maximum RAM percentage" parameter in Reason and Validate plugins +- "Maximum RAM percentage" parameter ### Changed diff --git a/README.md b/README.md index 370a27b..4aeae68 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Maximum heap size for the Java virtual machine in the DI container running the r # Validate -In case ontology inconsistencies are found, the plugin outputs the explanation as text in Markdown format using the path "text". +The plugin outputs the explanation as text in Markdown format using the path "text". ## Options @@ -122,6 +122,10 @@ The IRI of the output graph for the reasoning result. If enabled, an explanation markdown file is written to the project. +### Output filename + +The filename of the Markdown file with the explanation of inconsistencies. + :warning: Existing files will be overwritten. ### Stop at inconsistencies diff --git a/cmem_plugin_reason/plugin_reason.py b/cmem_plugin_reason/plugin_reason.py index ab5908c..969c81f 100644 --- a/cmem_plugin_reason/plugin_reason.py +++ b/cmem_plugin_reason/plugin_reason.py @@ -29,6 +29,8 @@ send_result, ) +PLUGIN_IRI = "https://plugin.eccenca.com/cmem-plugin-reason/reason" + @Plugin( label="Reason", @@ -266,8 +268,7 @@ def reason(self, graphs: dict) -> None: f"--language-annotation rdfs:comment " f'"Reasoning result set of <{self.data_graph_iri}> and ' f'<{self.ontology_graph_iri}>" en ' - f"--language-annotation prov:wasGeneratedBy " - f'"cmem-plugin-reason ({self.reasoner})" en ' + f'--link-annotation prov:wasGeneratedBy "{PLUGIN_IRI}/{self.reasoner}" ' f'--link-annotation prov:wasDerivedFrom "{self.data_graph_iri}" ' f"--link-annotation prov:wasDerivedFrom " f'"{self.ontology_graph_iri}" ' @@ -291,4 +292,4 @@ def execute(self, inputs: tuple, context: ExecutionContext) -> None: # noqa: AR self.reason(graphs) setup_cmempy_user_access(context.user) send_result(self.result_graph_iri, Path(self.temp) / "result.ttl") - remove_temp(self, ["catalog-v001.xml", "result.ttl", *graphs.values()]) + remove_temp(self) diff --git a/cmem_plugin_reason/plugin_validate.py b/cmem_plugin_reason/plugin_validate.py index eea52ca..30b935a 100644 --- a/cmem_plugin_reason/plugin_validate.py +++ b/cmem_plugin_reason/plugin_validate.py @@ -36,9 +36,11 @@ send_result, ) +PLUGIN_IRI = "https://plugin.eccenca.com/cmem-plugin-reason/validate" + @Plugin( - label="Validate ontology consistency", + label="Validate", description="", documentation="""""", icon=Icon(package=__package__, file_name="obofoundry.png"), @@ -50,8 +52,7 @@ param_type=BoolParameterType(), name="write_md", label="Write Markdown explanation file", - description="Write Markdown file with explanation to project. ⚠️ Existing files will " - "be overwritten.", + description="Write Markdown file with explanation to project.", default_value=False, ), PluginParameter( @@ -73,7 +74,7 @@ name="md_filename", label="Output filename", description="The filename of the Markdown file with the explanation of " - "inconsistencies.", + "inconsistencies.⚠️ Existing files will be overwritten.", ), PluginParameter( param_type=BoolParameterType(), @@ -151,8 +152,7 @@ def validate(self, graphs: dict) -> None: f'--language-annotation rdfs:label "Ontology Validation Result {utctime}" en ' f"--language-annotation rdfs:comment " f'"Ontology validation of <{self.ontology_graph_iri}>" en ' - f"--language-annotation prov:wasGeneratedBy " - f'"cmem-plugin-validate ({self.reasoner})" en ' + f'--link-annotation prov:wasGeneratedBy "{PLUGIN_IRI}/{self.reasoner}" ' f'--link-annotation prov:wasDerivedFrom "{self.ontology_graph_iri}" ' f'--typed-annotation dc:created "{utctime}" xsd:dateTime ' f'--output "{self.temp}/output.ttl"' @@ -182,26 +182,18 @@ def execute(self, inputs: tuple, context: ExecutionContext) -> Entities | None: self.get_graphs(graphs, context) create_xml_catalog_file(self.temp, graphs) self.validate(graphs) - files = ["catalog-v001.xml", self.md_filename, *graphs.values()] - if self.produce_graph: - files.append("output.ttl") - - text = (Path(self.temp) / self.md_filename).read_text() - if text == "No explanations found.": - remove_temp(self, files) - return None if self.produce_graph: setup_cmempy_user_access(context.user) send_result(self.output_graph_iri, Path(self.temp) / "output.ttl") - if self.write_md: setup_cmempy_user_access(context.user) self.make_resource(context) + text = (Path(self.temp) / self.md_filename).read_text() - remove_temp(self, files) + remove_temp(self) - if self.stop_at_inconsistencies: + if self.stop_at_inconsistencies and text != "No explanations found.": raise RuntimeError("Inconsistencies found in Ontology.") entities = [ diff --git a/cmem_plugin_reason/utils.py b/cmem_plugin_reason/utils.py index eea73a7..627b637 100644 --- a/cmem_plugin_reason/utils.py +++ b/cmem_plugin_reason/utils.py @@ -4,6 +4,7 @@ import unicodedata from collections import OrderedDict from pathlib import Path +from shutil import rmtree from xml.etree.ElementTree import Element, SubElement, tostring from cmem.cmempy.dp.proxy.graph import get_graph_import_tree, post_streamed @@ -108,14 +109,9 @@ def send_result(iri: str, filepath: Path) -> None: ) -def remove_temp(plugin: WorkflowPlugin, files: list) -> None: - """Remove temproray files""" - for file in files: - try: - (Path(plugin.temp) / file).unlink() - except (OSError, FileNotFoundError) as err: - plugin.log.warning(f"Cannot remove file {file} ({err})") +def remove_temp(plugin: WorkflowPlugin) -> None: + """Remove temporary files""" try: - Path(plugin.temp).rmdir() + rmtree(plugin.temp) except (OSError, FileNotFoundError) as err: plugin.log.warning(f"Cannot remove directory {plugin.temp} ({err})") diff --git a/tests/test_elk.ttl b/tests/test_elk.ttl index 8eb0e56..21dc22b 100644 --- a/tests/test_elk.ttl +++ b/tests/test_elk.ttl @@ -13,7 +13,7 @@ rdfs:comment "Reasoning result set of and "@en ; prov:wasDerivedFrom , ; - prov:wasGeneratedBy "cmem-plugin-reason (elk)"@en . + prov:wasGeneratedBy . ################################################################# # Individuals diff --git a/tests/test_emr.ttl b/tests/test_emr.ttl index bb10014..22130a0 100644 --- a/tests/test_emr.ttl +++ b/tests/test_emr.ttl @@ -13,7 +13,7 @@ rdfs:comment "Reasoning result set of and "@en ; prov:wasDerivedFrom , ; - prov:wasGeneratedBy "cmem-plugin-reason (emr)"@en . + prov:wasGeneratedBy . ################################################################# # Individuals diff --git a/tests/test_hermit.ttl b/tests/test_hermit.ttl index e1e865e..376fcf9 100644 --- a/tests/test_hermit.ttl +++ b/tests/test_hermit.ttl @@ -13,7 +13,7 @@ rdfs:comment "Reasoning result set of and "@en ; prov:wasDerivedFrom , ; - prov:wasGeneratedBy "cmem-plugin-reason (hermit)"@en . + prov:wasGeneratedBy . ################################################################# # Individuals diff --git a/tests/test_jfact.ttl b/tests/test_jfact.ttl index f13d8f3..6f8a857 100644 --- a/tests/test_jfact.ttl +++ b/tests/test_jfact.ttl @@ -13,7 +13,7 @@ rdfs:comment "Reasoning result set of and "@en ; prov:wasDerivedFrom , ; - prov:wasGeneratedBy "cmem-plugin-reason (jfact)"@en . + prov:wasGeneratedBy . ################################################################# # Individuals diff --git a/tests/test_structural.ttl b/tests/test_structural.ttl index 8d7f980..ce025bf 100644 --- a/tests/test_structural.ttl +++ b/tests/test_structural.ttl @@ -13,7 +13,7 @@ rdfs:comment "Reasoning result set of and "@en ; prov:wasDerivedFrom , ; - prov:wasGeneratedBy "cmem-plugin-reason (structural)"@en . + prov:wasGeneratedBy . ################################################################# # Individuals diff --git a/tests/test_validate_output.ttl b/tests/test_validate_output.ttl index 6c7508b..4b777ad 100644 --- a/tests/test_validate_output.ttl +++ b/tests/test_validate_output.ttl @@ -8,7 +8,7 @@ a owl:Ontology ; rdfs:comment "Ontology validation of "@en ; prov:wasDerivedFrom ; - prov:wasGeneratedBy "cmem-plugin-validate (elk)"@en . + prov:wasGeneratedBy . a owl:NamedIndividual, . diff --git a/tests/test_whelk.ttl b/tests/test_whelk.ttl index 8212b53..eccd0d9 100644 --- a/tests/test_whelk.ttl +++ b/tests/test_whelk.ttl @@ -13,7 +13,7 @@ rdfs:comment "Reasoning result set of and "@en ; prov:wasDerivedFrom , ; - prov:wasGeneratedBy "cmem-plugin-reason (whelk)"@en . + prov:wasGeneratedBy . ################################################################# # Individuals