Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Changes here will be overwritten by Copier
_commit: v8.5.0
_commit: v8.5.0-3-g60fcc85
_src_path: gh:eccenca/cmem-plugin-template
author_mail: cmempy-developer@eccenca.com
author_name: eccenca GmbH
Expand Down
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ 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]
## [2.3.0] 2026-08-17

TODO: add at least one Added, Changed, Deprecated, Removed, Fixed or Security section
### Changed

- Use cmem-client instead of cmempy for all Corporate Memory access

### Removed

- Remove cmem-cmempy dependency and `setup_cmempy_user_access` calls

## [2.2.7] 2026-07-22

Expand Down
59 changes: 28 additions & 31 deletions cmem_plugin_reason/plugin_reason.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
from tempfile import TemporaryDirectory
from uuid import uuid4

from cmem.cmempy.dp.proxy.graph import get, get_graph_import_tree, get_graphs_list
from cmem.cmempy.dp.proxy.update import post
from cmem_plugin_base.dataintegration.client import get_client
from cmem_plugin_base.dataintegration.context import ExecutionContext, ExecutionReport
from cmem_plugin_base.dataintegration.description import Icon, Plugin, PluginParameter
from cmem_plugin_base.dataintegration.entity import Entities
Expand All @@ -17,7 +16,6 @@
from cmem_plugin_base.dataintegration.plugins import WorkflowPlugin
from cmem_plugin_base.dataintegration.ports import FixedNumberOfInputs
from cmem_plugin_base.dataintegration.types import BoolParameterType, StringParameterType
from cmem_plugin_base.dataintegration.utils import setup_cmempy_user_access

from cmem_plugin_reason.doc import REASON_DOC
from cmem_plugin_reason.utils import (
Expand All @@ -30,6 +28,7 @@
VALIDATE_PROFILES_PARAMETER,
cancel_workflow,
create_xml_catalog_file,
fetch_graph,
get_file_with_datetime,
get_output_graph_label,
is_valid_uri,
Expand Down Expand Up @@ -401,17 +400,19 @@ def underscore(word: str) -> str:
def get_graphs(self, graphs: dict, missing: list) -> None:
"""Get graphs from CMEM"""
for iri, filename in graphs.items():
with (Path(self.temp) / filename).open("w", encoding="utf-8") as file:
if iri not in missing:
self.log.info(f"Fetching graph {iri}.")
setup_cmempy_user_access(self.context.user)
file.write(get(iri).text)
if iri == self.data_graph_iri:
file.write(
f"\n<{iri}> "
"<http://www.w3.org/2002/07/owl#imports> "
f"<{self.ontology_graph_iri}> ."
)
path = Path(self.temp) / filename
if iri in missing:
path.touch()
continue
self.log.info(f"Fetching graph {iri}.")
fetch_graph(self.client, iri, path)
if iri == self.data_graph_iri:
with path.open("a", encoding="utf-8") as file:
file.write(
f"\n<{iri}> "
"<http://www.w3.org/2002/07/owl#imports> "
f"<{self.ontology_graph_iri}> ."
)

def get_graphs_tree(self) -> tuple[dict, list]: # noqa: C901
"""Get graph import tree. Last item in graph_iris is output_graph_iri which is excluded"""
Expand All @@ -420,15 +421,15 @@ def get_graphs_tree(self) -> tuple[dict, list]: # noqa: C901
for graph_iri in [self.data_graph_iri, self.ontology_graph_iri]:
if graph_iri not in graphs:
graphs[graph_iri] = f"{uuid4().hex}.nt"
tree = get_graph_import_tree(graph_iri)
for value in tree["tree"].values():
tree = self.client.graph_imports.get_import_tree(graph_iri)
for value in tree.tree.values():
for iri in value:
if iri not in graphs:
if iri == self.ontology_graph_iri:
self.data_imports_ontology = True
elif iri == self.output_graph_iri:
raise ImportError("Input graph imports output graph.")
if iri not in self.graphs_dict:
if iri not in self.client.graphs:
missing.append(iri)
graphs[iri] = f"{uuid4().hex}.nt"
if missing:
Expand Down Expand Up @@ -483,7 +484,7 @@ def add_result_import(self) -> None:
}}
}}
"""
post(query=query)
self.client.store.sparql.update(query)

def remove_ontology_import(self) -> None:
"""Remove ontology graph import from output graph"""
Expand All @@ -495,11 +496,10 @@ def remove_ontology_import(self) -> None:
}}
}}
"""
post(query=query)
self.client.store.sparql.update(query)

def _execute(self) -> None:
"""`Execute plugin"""
setup_cmempy_user_access(self.context.user)
graphs, missing = self.get_graphs_tree()
self.get_graphs(graphs, missing)
if cancel_workflow(self):
Expand All @@ -508,8 +508,7 @@ def _execute(self) -> None:
self.reason(graphs)
if cancel_workflow(self):
return
setup_cmempy_user_access(self.context.user)
send_result(self.output_graph_iri, get_file_with_datetime(self))
send_result(self.client, self.output_graph_iri, get_file_with_datetime(self))
if self.validate_profile:
if self.input_profiles:
valid_profiles = self.valid_profiles.split(",")
Expand All @@ -518,7 +517,6 @@ def _execute(self) -> None:
post_profiles(self, valid_profiles)
post_provenance(self)

setup_cmempy_user_access(self.context.user)
if self.imports == "import_result":
self.add_result_import()
if self.imports != "import_ontology" and not self.data_imports_ontology:
Expand All @@ -534,17 +532,16 @@ def _execute(self) -> None:

def execute(self, inputs: Sequence[Entities], context: ExecutionContext) -> None: # noqa: ARG002
"""Execute plugin with temporary directory"""
setup_cmempy_user_access(context.user)
self.graphs_dict = {_["iri"]: _ for _ in get_graphs_list()}
not_exist = []
if self.data_graph_iri not in self.graphs_dict:
not_exist.append(self.data_graph_iri)
if self.ontology_graph_iri not in self.graphs_dict:
not_exist.append(self.ontology_graph_iri)
self.context = context
self.client = get_client(context)
not_exist = [
iri
for iri in (self.data_graph_iri, self.ontology_graph_iri)
if iri not in self.client.graphs
]
if not_exist:
raise ValueError(f"Graphs do not exist: {', '.join(not_exist)}")

self.context = context
context.report.update(
ExecutionReport(
operation="reason",
Expand Down
44 changes: 19 additions & 25 deletions cmem_plugin_reason/plugin_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from tempfile import TemporaryDirectory
from uuid import uuid4

from cmem.cmempy.dp.proxy.graph import get, get_graph_import_tree, get_graphs_list
from cmem.cmempy.workspace.projects.resources.resource import create_resource
from cmem_client.repositories.protocols.import_item import ImportConflictPolicy
from cmem_plugin_base.dataintegration.client import get_client
from cmem_plugin_base.dataintegration.context import ExecutionContext, ExecutionReport
from cmem_plugin_base.dataintegration.description import Icon, Plugin, PluginParameter
from cmem_plugin_base.dataintegration.entity import Entities, Entity, EntityPath, EntitySchema
Expand All @@ -16,7 +16,6 @@
from cmem_plugin_base.dataintegration.plugins import WorkflowPlugin
from cmem_plugin_base.dataintegration.ports import FixedNumberOfInputs, FixedSchemaPort
from cmem_plugin_base.dataintegration.types import BoolParameterType, StringParameterType
from cmem_plugin_base.dataintegration.utils import setup_cmempy_user_access
from pathvalidate import is_valid_filepath

from cmem_plugin_reason.doc import VALIDATE_DOC
Expand All @@ -30,6 +29,7 @@
VALIDATE_REASONER_PARAMETER,
cancel_workflow,
create_xml_catalog_file,
fetch_graph,
get_file_with_datetime,
get_output_graph_label,
is_valid_uri,
Expand Down Expand Up @@ -183,26 +183,26 @@ def generate_output_schema(self) -> EntitySchema:
def get_graphs(self, graphs: dict, missing: list) -> None:
"""Get graphs from CMEM"""
for iri, filename in graphs.items():
path = Path(self.temp) / filename
if iri in missing:
path.touch()
continue
self.log.info(f"Fetching graph {iri}.")
with (Path(self.temp) / filename).open("w", encoding="utf-8") as file:
if iri not in missing:
self.log.info(f"Fetching graph {iri}.")
setup_cmempy_user_access(self.context.user)
file.write(get(iri).text)
fetch_graph(self.client, iri, path)

def get_graphs_tree(self) -> tuple[dict, list]:
"""Get graph import tree. Last item in graph_iris is output_graph_iri which is excluded"""
missing = []
graphs = {}
if self.ontology_graph_iri not in graphs:
graphs[self.ontology_graph_iri] = f"{uuid4().hex}.nt"
tree = get_graph_import_tree(self.ontology_graph_iri)
for value in tree["tree"].values():
tree = self.client.graph_imports.get_import_tree(self.ontology_graph_iri)
for value in tree.tree.values():
for iri in value:
if iri not in graphs:
if iri == self.output_graph_iri:
raise ImportError("Input graph imports output graph.")
if iri not in self.graphs_dict:
if iri not in self.client.graphs:
missing.append(iri)
graphs[iri] = f"{uuid4().hex}.nt"
if missing:
Expand Down Expand Up @@ -241,11 +241,10 @@ def explain(self, graphs: dict) -> None:

def make_resource(self, context: ExecutionContext) -> None:
"""Make MD resource in project"""
create_resource(
project_name=context.task.project_id(),
resource_name=self.md_filename,
file_resource=(Path(self.temp) / self.md_filename).open("r", encoding="utf-8"),
replace=True,
self.client.files.import_item(
path=Path(self.temp) / self.md_filename,
key=f"{context.task.project_id()}:{self.md_filename}",
on_conflict=ImportConflictPolicy.REPLACE,
)

def add_profiles(self, valid_profiles: list) -> list:
Expand Down Expand Up @@ -274,7 +273,6 @@ def make_entities(self, text: str, valid_profiles: list) -> Entities:

def _execute(self) -> Entities | None:
"""Run the workflow operator."""
setup_cmempy_user_access(self.context.user)
graphs, missing = self.get_graphs_tree()
self.get_graphs(graphs, missing)
if cancel_workflow(self):
Expand All @@ -284,9 +282,7 @@ def _execute(self) -> Entities | None:
if cancel_workflow(self):
return None
if self.output_graph_iri:
setup_cmempy_user_access(self.context.user)
send_result(self.output_graph_iri, get_file_with_datetime(self))
setup_cmempy_user_access(self.context.user)
send_result(self.client, self.output_graph_iri, get_file_with_datetime(self))
post_provenance(self)
if cancel_workflow(self):
return None
Expand All @@ -296,7 +292,6 @@ def _execute(self) -> Entities | None:
if cancel_workflow(self):
return None
if self.write_md:
setup_cmempy_user_access(self.context.user)
self.make_resource(self.context)

text = (Path(self.temp) / self.md_filename).read_text()
Expand Down Expand Up @@ -326,12 +321,11 @@ def _execute(self) -> Entities | None:

def execute(self, inputs: Sequence[Entities], context: ExecutionContext) -> Entities | None: # noqa: ARG002
"""Execute plugin with temporary directory"""
setup_cmempy_user_access(context.user)
self.graphs_dict = {_["iri"]: _ for _ in get_graphs_list()}
if self.ontology_graph_iri not in self.graphs_dict:
self.context = context
self.client = get_client(context)
if self.ontology_graph_iri not in self.client.graphs:
raise ValueError(f"Ontology graph does not exist: {self.ontology_graph_iri}")

self.context = context
context.report.update(
ExecutionReport(
operation="validate",
Expand Down
Binary file modified cmem_plugin_reason/robot.jar
Binary file not shown.
Loading
Loading