From 7d88c688739bf5ff739a0a44551585b2bd4d9cd5 Mon Sep 17 00:00:00 2001 From: woutdenolf Date: Mon, 20 Dec 2021 13:04:57 +0100 Subject: [PATCH] handle links without explicit data mapping --- ewoksorange/bindings/owsconvert.py | 46 +++++++++++++++++++++++++++--- ewoksorange/tests/test_examples.py | 12 ++++++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ewoksorange/bindings/owsconvert.py b/ewoksorange/bindings/owsconvert.py index b8824cd..47d9d06 100644 --- a/ewoksorange/bindings/owsconvert.py +++ b/ewoksorange/bindings/owsconvert.py @@ -1,3 +1,5 @@ +import json +import logging from collections import namedtuple from typing import IO, Iterator, List, Optional, Tuple, Type, Union @@ -32,6 +34,8 @@ __all__ = ["ows_to_ewoks", "ewoks_to_ows"] ReadSchemeType = readwrite._scheme +logger = logging.getLogger(__name__) + def widget_to_task(widget_qualname: str) -> Tuple[OWBaseWidget, dict, Optional[Task]]: try: @@ -107,6 +111,14 @@ def ows_to_ewoks( ) -> TaskGraph: """Load an Orange Workflow Scheme from a file or stream and convert it to a `TaskGraph`.""" ows = read_ows(source) + + description = ows.description + try: + ewoksinfo = json.loads(description) + description = ewoksinfo["description"] + except Exception: + ewoksinfo = dict() + nodes = list() widget_classes = dict() if title_as_node_id: @@ -131,9 +143,11 @@ def ows_to_ewoks( if preserve_ows_info: node_attrs["ows"] = owsinfo if widget_class is not None: - node_attrs["default_inputs"] = node_data_to_default_inputs( + default_inputs = node_data_to_default_inputs( ows_node.data, widget_class, ewokstaskclass ) + if default_inputs: + node_attrs["default_inputs"] = default_inputs widget_classes[ows_node.id] = widget_class nodes.append(node_attrs) @@ -162,10 +176,12 @@ def ows_to_ewoks( } links.append(link) + links += ewoksinfo.get("missing_links", list()) + graph_attrs = dict() if ows.title: graph_attrs["id"] = ows.title - graph_attrs["label"] = ows.description + graph_attrs["label"] = description graph = { "graph": graph_attrs, @@ -246,7 +262,7 @@ class OwsSchemeWrapper: varinfo = dict() self.title = graph["graph"].get("id", "") - self.description = graph["graph"].get("label", "") + self._description = graph["graph"].get("label", "") self._nodes = dict() # the keys of this dictionary never used self._widget_classes = dict() @@ -263,6 +279,7 @@ class OwsSchemeWrapper: self._widget_classes[node_attrs["id"]] = widget_class self.links = list() + self.missing_links = list() for link in graph["links"]: self._convert_link(link) @@ -274,12 +291,33 @@ class OwsSchemeWrapper: def annotations(self): return list() + @property + def description(self): + if self.missing_links: + description = { + "description": self._description, + "missing_links": self.missing_links, + } + return json.dumps(description) + else: + return self._description + def _convert_link(self, link): + """In Orange, a link must transfer data""" source_node = self._nodes[link["source"]] sink_node = self._nodes[link["target"]] source_class = self._widget_classes[link["source"]] sink_class = self._widget_classes[link["target"]] - for item in link["data_mapping"]: + data_mapping = link.get("data_mapping", None) + if not data_mapping: + logger.warning( + "link '%s' -> '%s' cannot be created in Orange because it has not data transfer", + source_node, + sink_node, + ) + self.missing_links.append(link) + return + for item in data_mapping: target_name = item["target_input"] source_name = item["source_output"] target_name = signal_ewoks_to_orange_name(sink_class, "inputs", target_name) diff --git a/ewoksorange/tests/test_examples.py b/ewoksorange/tests/test_examples.py index 6722d95..2e06e84 100644 --- a/ewoksorange/tests/test_examples.py +++ b/ewoksorange/tests/test_examples.py @@ -21,7 +21,15 @@ def test_execute_graph(graph_name, tmpdir, ewoks_orange_canvas): graph, expected = get_graph(graph_name) ewoksgraph = load_graph(graph) varinfo = {"root_uri": str(tmpdir)} - if ewoksgraph.is_cyclic or ewoksgraph.has_conditional_links: + no_explicit_datamapping = any( + not link_attrs.get("data_mapping") + for link_attrs in ewoksgraph.graph.edges.values() + ) + if ( + ewoksgraph.is_cyclic + or ewoksgraph.has_conditional_links + or no_explicit_datamapping + ): pytest.skip("graph not supported by orange") else: with tempfile.TemporaryDirectory() as tmpdirname: @@ -30,6 +38,6 @@ def test_execute_graph(graph_name, tmpdir, ewoks_orange_canvas): ewoksgraph, filename, varinfo=varinfo, error_on_duplicates=False ) ewoks_orange_canvas.load_ows(filename) - ewoks_orange_canvas.wait_widgets(timeout=60) + ewoks_orange_canvas.wait_widgets(timeout=10) assert_taskgraph_result(ewoksgraph, expected, varinfo=varinfo) -- GitLab