diff --git a/lib/galaxy/managers/collections.py b/lib/galaxy/managers/collections.py index f84a80944c03..42a5e03be99c 100644 --- a/lib/galaxy/managers/collections.py +++ b/lib/galaxy/managers/collections.py @@ -25,7 +25,7 @@ log = logging.getLogger(__name__) ERROR_INVALID_ELEMENTS_SPECIFICATION = "Create called with invalid parameters, must specify element identifiers." -ERROR_NO_COLLECTION_TYPE = "Create called without specifing a collection type." +ERROR_NO_COLLECTION_TYPE = "Create called without specifying a collection type." class DatasetCollectionManager(object): @@ -46,11 +46,11 @@ def __init__(self, app): self.tag_manager = tags.GalaxyTagManager(app.model.context) self.ldda_manager = lddas.LDDAManager(app) - def precreate_dataset_collection_instance(self, trans, parent, name, structure, implicit_inputs=None, implicit_output_name=None): + def precreate_dataset_collection_instance(self, trans, parent, name, structure, implicit_inputs=None, implicit_output_name=None, tags=None): # TODO: prebuild all required HIDs and send them in so no need to flush in between. dataset_collection = self.precreate_dataset_collection(structure, allow_unitialized_element=implicit_output_name is not None) instance = self._create_instance_for_collection( - trans, parent, name, dataset_collection, implicit_inputs=implicit_inputs, implicit_output_name=implicit_output_name, flush=False + trans, parent, name, dataset_collection, implicit_inputs=implicit_inputs, implicit_output_name=implicit_output_name, flush=False, tags=tags ) return instance @@ -148,7 +148,14 @@ def _create_instance_for_collection(self, trans, parent, name, dataset_collectio log.exception(message) raise MessageException(message) - tags = self._append_tags(dataset_collection_instance, implicit_inputs, tags) + # Tags may be coming in as a dictionary of tag model objects if copying them from other + # existing Galaxy objects or as a list of strings if the tags are coming from user supplied + # values. + if isinstance(tags, list): + assert implicit_inputs is None, implicit_inputs + tags = self.tag_manager.add_tags_from_list(trans.user, dataset_collection_instance, tags) + else: + tags = self._append_tags(dataset_collection_instance, implicit_inputs, tags) return self.__persist(dataset_collection_instance, flush=flush) def create_dataset_collection(self, trans, collection_type, element_identifiers=None, elements=None, @@ -381,7 +388,7 @@ def __load_element(self, trans, element_identifier): the_object = context.query(type(the_object)).get(the_object.id) return the_object - # dateset_identifier is dict {src=hda|ldda|hdca|new_collection, id=} + # dataset_identifier is dict {src=hda|ldda|hdca|new_collection, id=} try: src_type = element_identifier.get('src', 'hda') except AttributeError: diff --git a/lib/galaxy/tools/actions/upload.py b/lib/galaxy/tools/actions/upload.py index afb669b4382b..e467561428d2 100644 --- a/lib/galaxy/tools/actions/upload.py +++ b/lib/galaxy/tools/actions/upload.py @@ -121,7 +121,8 @@ def _precreate_fetched_hdas(trans, history, target, outputs): uploaded_dataset = Bunch( type='file', name=name, file_type=file_type, dbkey=dbkey ) - data = upload_common.new_upload(trans, '', uploaded_dataset, library_bunch=None, history=history) + tag_list = item.get("tags", []) + data = upload_common.new_upload(trans, '', uploaded_dataset, library_bunch=None, history=history, tag_list=tag_list) outputs.append(data) item["object_id"] = data.id @@ -136,11 +137,12 @@ def _precreate_fetched_collection_instance(trans, history, target, outputs): if not name: return + tags = target.get("tags", []) collections_service = trans.app.dataset_collections_service collection_type_description = collections_service.collection_type_descriptions.for_collection_type(collection_type) structure = UninitializedTree(collection_type_description) hdca = collections_service.precreate_dataset_collection_instance( - trans, history, name, structure=structure + trans, history, name, structure=structure, tags=tags ) outputs.append(hdca) # Following flushed needed for an ID. diff --git a/lib/galaxy/tools/actions/upload_common.py b/lib/galaxy/tools/actions/upload_common.py index ed58059c1527..0d5677ae16be 100644 --- a/lib/galaxy/tools/actions/upload_common.py +++ b/lib/galaxy/tools/actions/upload_common.py @@ -271,11 +271,16 @@ def __new_library_upload(trans, cntrller, uploaded_dataset, library_bunch, state return ldda -def new_upload(trans, cntrller, uploaded_dataset, library_bunch=None, history=None, state=None): +def new_upload(trans, cntrller, uploaded_dataset, library_bunch=None, history=None, state=None, tag_list=None): if library_bunch: - return __new_library_upload(trans, cntrller, uploaded_dataset, library_bunch, state) + upload_target_dataset_instance = __new_library_upload(trans, cntrller, uploaded_dataset, library_bunch, state) else: - return __new_history_upload(trans, uploaded_dataset, history=history, state=state) + upload_target_dataset_instance = __new_history_upload(trans, uploaded_dataset, history=history, state=state) + + if tag_list: + trans.app.tag_handler.add_tags_from_list(trans.user, upload_target_dataset_instance, tag_list) + + return upload_target_dataset_instance def get_uploaded_datasets(trans, cntrller, params, dataset_upload_inputs, library_bunch=None, history=None): diff --git a/lib/galaxy/tools/data_fetch.py b/lib/galaxy/tools/data_fetch.py index dfcb3512047b..6db97fa18887 100644 --- a/lib/galaxy/tools/data_fetch.py +++ b/lib/galaxy/tools/data_fetch.py @@ -95,6 +95,7 @@ def _resolve_src(item): dbkey = item.get("dbkey", "?") requested_ext = item.get("ext", "auto") info = item.get("info", None) + tags = item.get("tags", []) object_id = item.get("object_id", None) link_data_only = upload_config.link_data_only if "link_data_only" in item: @@ -146,6 +147,8 @@ def _resolve_src(item): rval["info"] = info if object_id is not None: rval["object_id"] = object_id + if tags: + rval["tags"] = tags return rval elements = elements_tree_map(_resolve_src, items) diff --git a/lib/galaxy/tools/parameters/output_collect.py b/lib/galaxy/tools/parameters/output_collect.py index b0cc60cbfd3a..efbeba327cbf 100644 --- a/lib/galaxy/tools/parameters/output_collect.py +++ b/lib/galaxy/tools/parameters/output_collect.py @@ -407,7 +407,7 @@ def populate_collection_elements(self, collection, root_collection_builder, file dataset_name = fields_match.name or designation link_data = discovered_file.match.link_data - + tag_list = discovered_file.match.tag_list dataset = self.create_dataset( ext=ext, designation=designation, @@ -417,6 +417,7 @@ def populate_collection_elements(self, collection, root_collection_builder, file filename=filename, metadata_source_name=metadata_source_name, link_data=link_data, + tag_list=tag_list, ) log.debug( "(%s) Created dynamic collection dataset for path [%s] with element identifier [%s] for output [%s] %s", @@ -473,6 +474,7 @@ def create_dataset( library_folder=None, link_data=False, primary_data=None, + tag_list=[], ): app = self.app sa_session = self.sa_session @@ -493,6 +495,10 @@ def create_dataset( metadata_source = self.inp_data[metadata_source_name] sa_session.flush() + + if tag_list: + app.tag_handler.add_tags_from_list(self.job.user, primary_data, tag_list) + # Move data from temp location to dataset location if not link_data: app.object_store.update_from_file(primary_data.dataset, file_name=filename, create=True) @@ -873,6 +879,10 @@ def visible(self): def link_data(self): return bool(self.as_dict.get("link_data_only", False)) + @property + def tag_list(self): + return self.as_dict.get("tags", []) + @property def object_id(self): return self.as_dict.get("object_id", None) diff --git a/test/api/test_dataset_collections.py b/test/api/test_dataset_collections.py index 87752d2b9096..0108e1622100 100644 --- a/test/api/test_dataset_collections.py +++ b/test/api/test_dataset_collections.py @@ -189,12 +189,13 @@ def test_enforces_unique_names(self): self._assert_status_code_is(create_response, 400) def test_upload_collection(self): - elements = [{"src": "files", "dbkey": "hg19", "info": "my cool bed"}] + elements = [{"src": "files", "dbkey": "hg19", "info": "my cool bed", "tags": ["name:data1", "group:condition:treated", "machine:illumina"]}] targets = [{ "destination": {"type": "hdca"}, "elements": elements, "collection_type": "list", "name": "Test upload", + "tags": ["name:collection1"] }] payload = { "history_id": self.history_id, @@ -204,10 +205,16 @@ def test_upload_collection(self): self.dataset_populator.fetch(payload) hdca = self._assert_one_collection_created_in_history() self.assertEquals(hdca["name"], "Test upload") + hdca_tags = hdca["tags"] + assert len(hdca_tags) == 1 + assert "name:collection1" in hdca_tags assert len(hdca["elements"]) == 1, hdca element0 = hdca["elements"][0] assert element0["element_identifier"] == "4.bed" - assert element0["object"]["file_size"] == 61 + dataset0 = element0["object"] + assert dataset0["file_size"] == 61 + dataset_tags = dataset0["tags"] + assert len(dataset_tags) == 3, dataset0 def test_upload_nested(self): elements = [{"name": "samp1", "elements": [{"src": "files", "dbkey": "hg19", "info": "my cool bed"}]}] diff --git a/test/api/test_tools_upload.py b/test/api/test_tools_upload.py index c4c27576b036..9d6080a9828d 100644 --- a/test/api/test_tools_upload.py +++ b/test/api/test_tools_upload.py @@ -227,10 +227,15 @@ def test_upload_dbkey(self): datasets = run_response.json()["outputs"] assert datasets[0].get("genome_build") == "hg19", datasets[0] - def test_fetch_dbkey(self): + def test_fetch_metadata(self): table = ONE_TO_SIX_WITH_SPACES - details = self._upload_and_get_details(table, api='fetch', dbkey="hg19") + details = self._upload_and_get_details(table, api='fetch', dbkey="hg19", info="cool upload", tags=["name:data", "group:type:paired-end"]) assert details.get("genome_build") == "hg19" + assert details.get("misc_info") == "cool upload", details + tags = details.get("tags") + assert len(tags) == 2, details + assert "group:type:paired-end" in tags + assert "name:data" in tags def test_upload_multiple_files_1(self): with self.dataset_populator.test_history() as history_id: