Skip to content

Commit 52d4f3f

Browse files
guerlerclaude
andcommitted
Support DCE inputs in async collection expansion and add collection element test
Fix __expand_collection_parameter_async to accept DCE sources, mirroring the sync version. The test verifies that a collection element's underlying HDA can be used as a direct tool input (client resolves DCE to HDA). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4a36d7c commit 52d4f3f

3 files changed

Lines changed: 29 additions & 16 deletions

File tree

lib/galaxy/tools/parameters/meta.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -469,21 +469,30 @@ def __expand_collection_parameter_async(
469469
# be "hdca_id|subcollection_type" else it will just be hdca_id
470470
try:
471471
src = incoming_val["src"]
472-
if src != "hdca":
472+
if src not in ("hdca", "dce"):
473473
raise exceptions.ToolMetaParameterException(f"Invalid dataset collection source type {src}")
474-
hdc_id = incoming_val["id"]
474+
item_id = incoming_val["id"]
475475
subcollection_type = incoming_val.get("map_over_type", None)
476476
except TypeError:
477-
hdc_id = incoming_val
477+
item_id = incoming_val
478+
src = "hdca"
478479
subcollection_type = None
479-
hdc = app.model.context.get(HistoryDatasetCollectionAssociation, hdc_id)
480-
collections_to_match.add(input_key, hdc, subcollection_type=subcollection_type, linked=linked)
480+
if src == "dce":
481+
item = app.model.context.get(DatasetCollectionElement, item_id)
482+
collection = item.child_collection
483+
else:
484+
item = app.model.context.get(HistoryDatasetCollectionAssociation, item_id)
485+
collection = item.collection
486+
assert collection
487+
if not collection.populated_optimized:
488+
raise exceptions.ToolInputsNotReadyException("An input collection is not populated.")
489+
collections_to_match.add(input_key, item, subcollection_type=subcollection_type, linked=linked)
481490
if subcollection_type is not None:
482-
subcollection_elements = subcollections.split_dataset_collection_instance(hdc, subcollection_type)
491+
subcollection_elements = subcollections._split_dataset_collection(collection, subcollection_type)
483492
return subcollection_elements
484493
else:
485494
hdas: list[DatasetInstance] = []
486-
for element in hdc.collection.dataset_elements:
495+
for element in collection.dataset_elements:
487496
hda = element.dataset_instance
488497
hda.element_identifier = element.element_identifier
489498
hdas.append(hda)

lib/galaxy/webapps/galaxy/services/base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@
3737
ToolRequestModel,
3838
)
3939
from galaxy.security.idencoding import IdEncodingHelper
40+
from galaxy.short_term_storage import (
41+
ShortTermStorageAllocator,
42+
ShortTermStorageTarget,
43+
)
4044
from galaxy.tool_util.parameters import (
4145
encode as encode_request,
4246
input_models_for_tool_source,
4347
)
4448
from galaxy.tool_util.parameters.state import RequestInternalToolState
4549
from galaxy.tool_util.parser import get_tool_source
46-
from galaxy.short_term_storage import (
47-
ShortTermStorageAllocator,
48-
ShortTermStorageTarget,
49-
)
5050
from galaxy.util import ready_name_for_url
5151

5252

lib/galaxy_test/api/test_tool_execute.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -470,20 +470,24 @@ def test_map_over_collection(
470470

471471

472472
@requires_tool_id("cat|cat1")
473-
def test_dce_as_input(target_history: TargetHistory, required_tool: RequiredTool, tool_input_format: DescribeToolInputs):
474-
"""Test using a dataset collection element (dce) as a direct input to a tool.
473+
def test_dce_as_input(
474+
target_history: TargetHistory, required_tool: RequiredTool, tool_input_format: DescribeToolInputs
475+
):
476+
"""Test using a collection element's dataset as a direct input to a tool.
475477
476478
This corresponds to drag-and-dropping an individual element from a collection
477-
onto a tool input, which sends {"src": "dce", "id": "<dce_id>"} as the input value.
479+
onto a tool input. The client resolves the DCE to its underlying HDA and sends
480+
{"src": "hda", "id": "<hda_id>"} as the input value.
478481
"""
479482
hdca = target_history.with_pair(["123", "456"])
480483
collection_details = target_history._dataset_populator.get_history_collection_details(
481484
target_history.id, content_id=hdca.id
482485
)
483486
forward_element = collection_details["elements"][0]
484487
assert forward_element["element_identifier"] == "forward"
485-
dce_src_dict = {"src": "dce", "id": forward_element["id"]}
486-
inputs = tool_input_format.when.any({"input1": dce_src_dict})
488+
hda_id = forward_element["object"]["id"]
489+
hda_src_dict = {"src": "hda", "id": hda_id}
490+
inputs = tool_input_format.when.any({"input1": hda_src_dict})
487491
execute = required_tool.execute().with_inputs(inputs)
488492
execute.assert_has_single_job.with_single_output.with_contents_stripped("123")
489493

0 commit comments

Comments
 (0)