From 58e6011407e4327fcf8e0094dfc1ebb90496d5c3 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Wed, 25 Sep 2024 20:24:44 +0200 Subject: [PATCH 1/6] Allow cors in biom and q2view display applications --- .../datatypes/display_applications/configs/biom/biom_simple.xml | 2 +- .../display_applications/configs/qiime/qiime2/q2view.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/datatypes/display_applications/configs/biom/biom_simple.xml b/lib/galaxy/datatypes/display_applications/configs/biom/biom_simple.xml index 787a4b3ef4dc..4c5d4e10f159 100644 --- a/lib/galaxy/datatypes/display_applications/configs/biom/biom_simple.xml +++ b/lib/galaxy/datatypes/display_applications/configs/biom/biom_simple.xml @@ -2,6 +2,6 @@ ${ url % { 'biom_file_url_qp': $biom_file.qp } } - + diff --git a/lib/galaxy/datatypes/display_applications/configs/qiime/qiime2/q2view.xml b/lib/galaxy/datatypes/display_applications/configs/qiime/qiime2/q2view.xml index 1035cbb679a0..5cbba046610c 100644 --- a/lib/galaxy/datatypes/display_applications/configs/qiime/qiime2/q2view.xml +++ b/lib/galaxy/datatypes/display_applications/configs/qiime/qiime2/q2view.xml @@ -2,6 +2,6 @@ ${ url % { 'q2view_file_url_qp': $q2view_file.qp } } - + From d3b6d695c050f91d634f9ae5710cb8eb1e16aa4f Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Thu, 26 Sep 2024 15:45:15 +0200 Subject: [PATCH 2/6] Allow dynamic options to be filtered in workflow_building_mode This is fine for reference data or other static artefacts. Only return an empty list if we actually have a runtime value. This fixes displaying data tables that have an attached filter in the workflow editor and run forms. --- lib/galaxy/tools/parameters/dynamic_options.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/galaxy/tools/parameters/dynamic_options.py b/lib/galaxy/tools/parameters/dynamic_options.py index b8cd20dab37d..42e177a58042 100644 --- a/lib/galaxy/tools/parameters/dynamic_options.py +++ b/lib/galaxy/tools/parameters/dynamic_options.py @@ -286,14 +286,12 @@ def get_dependency_name(self): return self.ref_name def filter_options(self, options, trans, other_values): - if trans is not None and trans.workflow_building_mode: - return [] ref = other_values.get(self.ref_name, None) - if ref is None: + if ref is None or is_runtime_value(ref): ref = [] # - for HDCAs the list of contained HDAs is extracted - # - single values are transformed in a single eleent list + # - single values are transformed in a single element list # - remaining cases are already lists (select and data parameters with multiple=true) if isinstance(ref, HistoryDatasetCollectionAssociation): ref = ref.to_hda_representative(multiple=True) From bfbca7466de7e835d55d0fa2a4efffa6923e28d6 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Thu, 26 Sep 2024 15:49:08 +0200 Subject: [PATCH 3/6] Enable value restriction to look at parameter references --- lib/galaxy/workflow/modules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/galaxy/workflow/modules.py b/lib/galaxy/workflow/modules.py index a5fadafeb28a..2cdef868d4ee 100644 --- a/lib/galaxy/workflow/modules.py +++ b/lib/galaxy/workflow/modules.py @@ -1414,7 +1414,7 @@ def restrict_options(self, step, connections: Iterable[WorkflowStepConnection], def callback(input, prefixed_name, context, **kwargs): if prefixed_name == connection.input_name and hasattr(input, "get_options"): # noqa: B023 - static_options.append(input.get_options(self.trans, {})) + static_options.append(input.get_options(self.trans, context)) visit_input_values(tool_inputs, module.state.inputs, callback) elif isinstance(module, SubWorkflowModule): From cd19148e70c0d1f3ec3b1c8b141ce78bc4484dd4 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 30 Sep 2024 10:45:15 +0200 Subject: [PATCH 4/6] Fix url short term cache for legacy trans object --- lib/galaxy/managers/context.py | 10 ++++++++++ lib/galaxy/webapps/base/webapp.py | 2 ++ lib/galaxy/work/context.py | 6 ------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/galaxy/managers/context.py b/lib/galaxy/managers/context.py index 24c29567a80b..4d55fcffbadb 100644 --- a/lib/galaxy/managers/context.py +++ b/lib/galaxy/managers/context.py @@ -39,10 +39,13 @@ import string from json import dumps from typing import ( + Any, Callable, cast, + Dict, List, Optional, + Tuple, ) from sqlalchemy import select @@ -204,6 +207,13 @@ class ProvidesUserContext(ProvidesAppContext): galaxy_session: Optional[GalaxySession] = None _tag_handler: Optional[GalaxyTagHandlerSession] = None + _short_term_cache: Dict[Tuple[str, ...], Any] + + def set_cache_value(self, args: Tuple[str, ...], value: Any): + self._short_term_cache[args] = value + + def get_cache_value(self, args: Tuple[str, ...], default: Any = None) -> Any: + return self._short_term_cache.get(args, default) @property def tag_handler(self): diff --git a/lib/galaxy/webapps/base/webapp.py b/lib/galaxy/webapps/base/webapp.py index 822e5b7ec236..75a14f04e301 100644 --- a/lib/galaxy/webapps/base/webapp.py +++ b/lib/galaxy/webapps/base/webapp.py @@ -14,6 +14,7 @@ Any, Dict, Optional, + Tuple, ) from urllib.parse import urlparse @@ -325,6 +326,7 @@ def __init__( self.galaxy_session = None self.error_message = None self.host = self.request.host + self._short_term_cache: Dict[Tuple[str, ...], Any] = {} # set any cross origin resource sharing headers if configured to do so self.set_cors_headers() diff --git a/lib/galaxy/work/context.py b/lib/galaxy/work/context.py index 8e4fc74afc21..ec1146adc102 100644 --- a/lib/galaxy/work/context.py +++ b/lib/galaxy/work/context.py @@ -49,12 +49,6 @@ def __init__( self.workflow_building_mode = workflow_building_mode self.galaxy_session = galaxy_session - def set_cache_value(self, args: Tuple[str, ...], value: Any): - self._short_term_cache[args] = value - - def get_cache_value(self, args: Tuple[str, ...], default: Any = None) -> Any: - return self._short_term_cache.get(args, default) - @property def app(self): return self._app From 2fc820917139ecb3cca5ff3e495f5884325328ba Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 30 Sep 2024 10:47:31 +0200 Subject: [PATCH 5/6] Enable filters on from_url options --- lib/galaxy/tools/parameters/dynamic_options.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/tools/parameters/dynamic_options.py b/lib/galaxy/tools/parameters/dynamic_options.py index 42e177a58042..e354c93eabb5 100644 --- a/lib/galaxy/tools/parameters/dynamic_options.py +++ b/lib/galaxy/tools/parameters/dynamic_options.py @@ -833,6 +833,9 @@ def get_field_by_name_for_value(self, field_name, value, trans, other_values): return rval def get_options(self, trans, other_values): + + rval = [] + def to_triple(values): if len(values) == 2: return [str(values[0]), str(values[1]), False] @@ -875,8 +878,7 @@ def to_triple(values): data = [] # We only support the very specific ["name", "value", "selected"] format for now. - return [to_triple(d) for d in data] - rval = [] + rval = [to_triple(d) for d in data] if ( self.file_fields is not None or self.tool_data_table is not None From b5d46aa9435a54d05a35ec38163607703288033d Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 30 Sep 2024 11:57:30 +0200 Subject: [PATCH 6/6] Test workflow module building with dynamic parameters and parameter references and validators. --- lib/galaxy/tools/__init__.py | 11 +++++++++++ .../api/test_workflow_build_module.py | 19 +++++++++++++++++++ lib/galaxy_test/base/populators.py | 6 ++++++ test/functional/tools/select_from_url.xml | 7 +++++++ 4 files changed, 43 insertions(+) create mode 100644 lib/galaxy_test/api/test_workflow_build_module.py diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index d1f50b945c28..1fae939dd5d1 100644 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -3670,6 +3670,17 @@ def element_is_valid(element: model.DatasetCollectionElement): return False +class FilterNullTool(FilterDatasetsTool): + tool_type = "filter_null" + require_dataset_ok = True + + @staticmethod + def element_is_valid(element: model.DatasetCollectionElement): + element_object = element.element_object + assert isinstance(element_object, model.DatasetInstance) + return element_object.extension == "expression.json" and element_object.blurb == "skipped" + + class FlattenTool(DatabaseOperationTool): tool_type = "flatten_collection" require_terminal_states = False diff --git a/lib/galaxy_test/api/test_workflow_build_module.py b/lib/galaxy_test/api/test_workflow_build_module.py new file mode 100644 index 000000000000..546f6192e397 --- /dev/null +++ b/lib/galaxy_test/api/test_workflow_build_module.py @@ -0,0 +1,19 @@ +from galaxy_test.base.populators import ( + skip_without_tool, + WorkflowPopulator, +) +from ._framework import ApiTestCase + + +class TestBuildWorkflowModule(ApiTestCase): + + def setUp(self): + super().setUp() + self.workflow_populator = WorkflowPopulator(self.galaxy_interactor) + + @skip_without_tool("select_from_url") + def test_build_module_filter_dynamic_select(self): + # Verify that filtering on parameters that depend on parameter and validators works + # fine in workflow building mode. + module = self.workflow_populator.build_module(step_type="tool", content_id="select_from_url") + assert not module["errors"], module["errors"] diff --git a/lib/galaxy_test/base/populators.py b/lib/galaxy_test/base/populators.py index 014880ebd1e6..bd5feaa01592 100644 --- a/lib/galaxy_test/base/populators.py +++ b/lib/galaxy_test/base/populators.py @@ -2298,6 +2298,12 @@ def import_tool(self, tool) -> Dict[str, Any]: assert upload_response.status_code == 200, upload_response return upload_response.json() + def build_module(self, step_type: str, content_id: Optional[str] = None, inputs: Optional[Dict[str, Any]] = None): + payload = {"inputs": inputs or {}, "type": step_type, "content_id": content_id} + response = self._post("workflows/build_module", data=payload, json=True) + assert response.status_code == 200, response + return response.json() + def _import_tool_response(self, tool) -> Response: using_requirement("admin") tool_str = json.dumps(tool, indent=4) diff --git a/test/functional/tools/select_from_url.xml b/test/functional/tools/select_from_url.xml index 60a712e74631..488055677e85 100644 --- a/test/functional/tools/select_from_url.xml +++ b/test/functional/tools/select_from_url.xml @@ -10,6 +10,13 @@ echo '$url_param_value_header_and_body' > '$param_value_header_and_body' + + + + + + +