From ee710a4ed141c89f3ba6e38606bb86a7d5370154 Mon Sep 17 00:00:00 2001 From: Patrik Smeds Date: Wed, 7 May 2025 14:51:13 -0400 Subject: [PATCH 1/2] function used to import an invocation archive. Needs API updates before it can be merged. --- bioblend/_tests/TestGalaxyInvocations.py | 9 ++++++ bioblend/_tests/data/example3.rocrate.zip | Bin 0 -> 11109 bytes bioblend/galaxy/invocations/__init__.py | 34 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 bioblend/_tests/data/example3.rocrate.zip diff --git a/bioblend/_tests/TestGalaxyInvocations.py b/bioblend/_tests/TestGalaxyInvocations.py index 6f4b1a302..8dfd9fecc 100644 --- a/bioblend/_tests/TestGalaxyInvocations.py +++ b/bioblend/_tests/TestGalaxyInvocations.py @@ -112,6 +112,15 @@ def test_get_invocation_jobs_summary(self): assert len(step_jobs_summary) == 1 assert step_jobs_summary[0]["populated_state"] == "ok" + @test_util.skip_unless_galaxy("release_23.0") + def test_import_invocation_archive(self): + new_history = self.gi.histories.create_history(name="My History") + test_file = test_util.get_abspath(os.path.join("data", "example3.rocrate.zip")) + import_response = self.gi.invocations.import_invocation( + history_id=new_history["id"], model_store_format="rocrate.zip", file_path=test_file + ) + assert "model_class" in import_response[0] and import_response[0]["model_class"] == "WorkflowInvocation" + @test_util.skip_unless_galaxy("release_19.09") @test_util.skip_unless_tool("cat1") @test_util.skip_unless_tool("cat") diff --git a/bioblend/_tests/data/example3.rocrate.zip b/bioblend/_tests/data/example3.rocrate.zip new file mode 100644 index 0000000000000000000000000000000000000000..6ed84a307faba950b923017837aec4d2d3b937f8 GIT binary patch literal 11109 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 dict[str, Any]: url = self._make_url(invocation_id) return self._delete(url=url) + def import_invocation( + self, history_id: str, model_store_format: str, file_path: Optional[str] = None, url: Optional[str] = None + ) -> Any: + """ + Import a invocation from an archive on disk or a URL. + + :type history_id + :param history_id: id of the history where the invocation will be imported + + :type model_store_format + :param model_store_format: archive type that will be imported + + :type file_path: str + :param file_path: Path to exported history archive on disk. + + :type url: str + :param url: URL for an exported history archive + + :rtype: dict or list of dicts + :return: if the import is successful, a list of dictionaries will be returned; otherwise, a single dictionary will be returned. + """ + payload: dict[str, Any] = { + "history_id": history_id, + "model_store_format": model_store_format, + } + if file_path: + with open(file_path, "rb") as reader: + payload["store_content_uri"] = "base64://" + base64.b64encode(reader.read()).decode("utf-8") + else: + payload["store_content_uri"] = url + url = "/".join((self._make_url(), "from_store")) + return self._post(url=url, payload=payload) + def show_invocation_step(self, invocation_id: str, step_id: str) -> dict[str, Any]: """ See the details of a particular workflow invocation step. From e82eca98fdefcfb2da387bb19ad53b9b5d136bc1 Mon Sep 17 00:00:00 2001 From: Patrik Smeds Date: Fri, 30 May 2025 12:12:50 -0400 Subject: [PATCH 2/2] modify import function to use tus client to upload files, instead of reading it into memory --- bioblend/_tests/TestGalaxyInvocations.py | 7 +++++-- bioblend/galaxy/invocations/__init__.py | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/bioblend/_tests/TestGalaxyInvocations.py b/bioblend/_tests/TestGalaxyInvocations.py index 8dfd9fecc..669ad9da8 100644 --- a/bioblend/_tests/TestGalaxyInvocations.py +++ b/bioblend/_tests/TestGalaxyInvocations.py @@ -112,12 +112,15 @@ def test_get_invocation_jobs_summary(self): assert len(step_jobs_summary) == 1 assert step_jobs_summary[0]["populated_state"] == "ok" - @test_util.skip_unless_galaxy("release_23.0") + @test_util.skip_unless_galaxy("release_25.01") def test_import_invocation_archive(self): new_history = self.gi.histories.create_history(name="My History") test_file = test_util.get_abspath(os.path.join("data", "example3.rocrate.zip")) import_response = self.gi.invocations.import_invocation( - history_id=new_history["id"], model_store_format="rocrate.zip", file_path=test_file + history_id=new_history["id"], + model_store_format="rocrate.zip", + file_path=test_file, + upload_url="/upload/resumable_upload", ) assert "model_class" in import_response[0] and import_response[0]["model_class"] == "WorkflowInvocation" diff --git a/bioblend/galaxy/invocations/__init__.py b/bioblend/galaxy/invocations/__init__.py index 2bb7ff8ec..23b17ed04 100644 --- a/bioblend/galaxy/invocations/__init__.py +++ b/bioblend/galaxy/invocations/__init__.py @@ -2,7 +2,6 @@ Contains possible interactions with the Galaxy workflow invocations """ -import base64 import logging from typing import ( Any, @@ -269,7 +268,13 @@ def cancel_invocation(self, invocation_id: str) -> dict[str, Any]: return self._delete(url=url) def import_invocation( - self, history_id: str, model_store_format: str, file_path: Optional[str] = None, url: Optional[str] = None + self, + history_id: str, + model_store_format: str, + file_path: Optional[str] = None, + url: Optional[str] = None, + upload_url: str = "/invocations/resumable_upload", + chunk_size: int = CHUNK_SIZE, ) -> Any: """ Import a invocation from an archive on disk or a URL. @@ -286,6 +291,9 @@ def import_invocation( :type url: str :param url: URL for an exported history archive + :type chunk_size: int + :param chunk_size: Number of bytes to send in each chunk + :rtype: dict or list of dicts :return: if the import is successful, a list of dictionaries will be returned; otherwise, a single dictionary will be returned. """ @@ -294,8 +302,10 @@ def import_invocation( "model_store_format": model_store_format, } if file_path: - with open(file_path, "rb") as reader: - payload["store_content_uri"] = "base64://" + base64.b64encode(reader.read()).decode("utf-8") + uploader = self.gi.get_tus_uploader(path=file_path, url=upload_url, chunk_size=chunk_size) + uploader.upload() + assert uploader.session_id + payload["store_content_uri"] = f"tus://{uploader.session_id}" else: payload["store_content_uri"] = url url = "/".join((self._make_url(), "from_store"))