From af4d4021ba8b25f44b2fe351b32392d3ccccdca1 Mon Sep 17 00:00:00 2001 From: Martin Cech Date: Thu, 18 Apr 2024 15:35:27 -0700 Subject: [PATCH 1/3] remove deprecated bco export endpoint instead clients shall POST api/invocations/{id}/prepare_store_download with payload: { model_store_format: bco.json } --- client/src/api/schema/schema.ts | 140 ------------------ lib/galaxy/webapps/galaxy/api/workflows.py | 87 ----------- .../webapps/galaxy/services/invocations.py | 24 --- lib/galaxy_test/api/test_workflows.py | 9 -- lib/galaxy_test/base/populators.py | 5 - 5 files changed, 265 deletions(-) diff --git a/client/src/api/schema/schema.ts b/client/src/api/schema/schema.ts index 190abb1ad1ea..22f30a75bdae 100644 --- a/client/src/api/schema/schema.ts +++ b/client/src/api/schema/schema.ts @@ -956,52 +956,6 @@ export interface paths { /** Cancel the specified workflow invocation. */ delete: operations["cancel_invocation_api_invocations__invocation_id__delete"]; }; - "/api/invocations/{invocation_id}/biocompute": { - /** - * Return a BioCompute Object for the workflow invocation. - * @deprecated - * @description The BioCompute Object endpoints are in beta - important details such - * as how inputs and outputs are represented, how the workflow is encoded, - * and how author and version information is encoded, and how URLs are - * generated will very likely change in important ways over time. - * - * **Deprecation Notice**: please use the asynchronous short_term_storage export system instead. - * - * 1. call POST `api/invocations/{id}/prepare_store_download` with payload: - * ``` - * { - * model_store_format: bco.json - * } - * ``` - * 2. Get `storageRequestId` from response and poll GET `api/short_term_storage/${storageRequestId}/ready` until `SUCCESS` - * - * 3. Get the resulting file with `api/short_term_storage/${storageRequestId}` - */ - get: operations["export_invocation_bco_api_invocations__invocation_id__biocompute_get"]; - }; - "/api/invocations/{invocation_id}/biocompute/download": { - /** - * Return a BioCompute Object for the workflow invocation as a file for download. - * @deprecated - * @description The BioCompute Object endpoints are in beta - important details such - * as how inputs and outputs are represented, how the workflow is encoded, - * and how author and version information is encoded, and how URLs are - * generated will very likely change in important ways over time. - * - * **Deprecation Notice**: please use the asynchronous short_term_storage export system instead. - * - * 1. call POST `api/invocations/{id}/prepare_store_download` with payload: - * ``` - * { - * model_store_format: bco.json - * } - * ``` - * 2. Get `storageRequestId` from response and poll GET `api/short_term_storage/${storageRequestId}/ready` until `SUCCESS` - * - * 3. Get the resulting file with `api/short_term_storage/${storageRequestId}` - */ - get: operations["download_invocation_bco_api_invocations__invocation_id__biocompute_download_get"]; - }; "/api/invocations/{invocation_id}/jobs_summary": { /** * Get job state summary info aggregated across all current jobs of the workflow invocation. @@ -18784,100 +18738,6 @@ export interface operations { }; }; }; - export_invocation_bco_api_invocations__invocation_id__biocompute_get: { - /** - * Return a BioCompute Object for the workflow invocation. - * @deprecated - * @description The BioCompute Object endpoints are in beta - important details such - * as how inputs and outputs are represented, how the workflow is encoded, - * and how author and version information is encoded, and how URLs are - * generated will very likely change in important ways over time. - * - * **Deprecation Notice**: please use the asynchronous short_term_storage export system instead. - * - * 1. call POST `api/invocations/{id}/prepare_store_download` with payload: - * ``` - * { - * model_store_format: bco.json - * } - * ``` - * 2. Get `storageRequestId` from response and poll GET `api/short_term_storage/${storageRequestId}/ready` until `SUCCESS` - * - * 3. Get the resulting file with `api/short_term_storage/${storageRequestId}` - */ - parameters: { - query?: { - merge_history_metadata?: boolean | null; - }; - /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ - header?: { - "run-as"?: string | null; - }; - /** @description The encoded database identifier of the Invocation. */ - path: { - invocation_id: string; - }; - }; - responses: { - /** @description Successful Response */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @description Validation Error */ - 422: { - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; - download_invocation_bco_api_invocations__invocation_id__biocompute_download_get: { - /** - * Return a BioCompute Object for the workflow invocation as a file for download. - * @deprecated - * @description The BioCompute Object endpoints are in beta - important details such - * as how inputs and outputs are represented, how the workflow is encoded, - * and how author and version information is encoded, and how URLs are - * generated will very likely change in important ways over time. - * - * **Deprecation Notice**: please use the asynchronous short_term_storage export system instead. - * - * 1. call POST `api/invocations/{id}/prepare_store_download` with payload: - * ``` - * { - * model_store_format: bco.json - * } - * ``` - * 2. Get `storageRequestId` from response and poll GET `api/short_term_storage/${storageRequestId}/ready` until `SUCCESS` - * - * 3. Get the resulting file with `api/short_term_storage/${storageRequestId}` - */ - parameters: { - query?: { - merge_history_metadata?: boolean | null; - }; - /** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */ - header?: { - "run-as"?: string | null; - }; - /** @description The encoded database identifier of the Invocation. */ - path: { - invocation_id: string; - }; - }; - responses: { - /** @description Successful Response */ - 200: never; - /** @description Validation Error */ - 422: { - content: { - "application/json": components["schemas"]["HTTPValidationError"]; - }; - }; - }; - }; invocation_jobs_summary_api_invocations__invocation_id__jobs_summary_get: { /** * Get job state summary info aggregated across all current jobs of the workflow invocation. diff --git a/lib/galaxy/webapps/galaxy/api/workflows.py b/lib/galaxy/webapps/galaxy/api/workflows.py index 54386e7596c6..c17381150060 100644 --- a/lib/galaxy/webapps/galaxy/api/workflows.py +++ b/lib/galaxy/webapps/galaxy/api/workflows.py @@ -52,7 +52,6 @@ ) from galaxy.model.base import transaction from galaxy.model.item_attrs import UsesAnnotations -from galaxy.model.store import BcoExportOptions from galaxy.schema.fields import DecodedDatabaseIdField from galaxy.schema.invocation import ( CreateInvocationFromStore, @@ -88,7 +87,6 @@ from galaxy.tools.parameters import populate_state from galaxy.tools.parameters.workflow_utils import workflow_building_modes from galaxy.util.sanitize_html import sanitize_html -from galaxy.version import VERSION from galaxy.web import ( expose_api, expose_api_raw_anonymous_and_sessionless, @@ -1712,88 +1710,3 @@ def workflow_invocation_jobs_summary( ) -> InvocationJobsResponse: """An alias for `GET /api/invocations/{invocation_id}/jobs_summary`. `workflow_id` is ignored.""" return self.invocation_jobs_summary(trans=trans, invocation_id=invocation_id) - - # TODO: remove this endpoint after 23.1 release - @router.get( - "/api/invocations/{invocation_id}/biocompute", - summary="Return a BioCompute Object for the workflow invocation.", - deprecated=True, - ) - def export_invocation_bco( - self, - invocation_id: InvocationIDPathParam, - trans: ProvidesUserContext = DependsOnTrans, - merge_history_metadata: Optional[bool] = Query(default=False), - ): - """ - The BioCompute Object endpoints are in beta - important details such - as how inputs and outputs are represented, how the workflow is encoded, - and how author and version information is encoded, and how URLs are - generated will very likely change in important ways over time. - - **Deprecation Notice**: please use the asynchronous short_term_storage export system instead. - - 1. call POST `api/invocations/{id}/prepare_store_download` with payload: - ``` - { - model_store_format: bco.json - } - ``` - 2. Get `storageRequestId` from response and poll GET `api/short_term_storage/${storageRequestId}/ready` until `SUCCESS` - - 3. Get the resulting file with `api/short_term_storage/${storageRequestId}` - """ - bco = self._deprecated_generate_bco(trans, invocation_id, merge_history_metadata) - return json.loads(bco) - - # TODO: remove this endpoint after 23.1 release - @router.get( - "/api/invocations/{invocation_id}/biocompute/download", - summary="Return a BioCompute Object for the workflow invocation as a file for download.", - response_class=StreamingResponse, - deprecated=True, - ) - def download_invocation_bco( - self, - invocation_id: InvocationIDPathParam, - trans: ProvidesUserContext = DependsOnTrans, - merge_history_metadata: Optional[bool] = Query(default=False), - ): - """ - The BioCompute Object endpoints are in beta - important details such - as how inputs and outputs are represented, how the workflow is encoded, - and how author and version information is encoded, and how URLs are - generated will very likely change in important ways over time. - - **Deprecation Notice**: please use the asynchronous short_term_storage export system instead. - - 1. call POST `api/invocations/{id}/prepare_store_download` with payload: - ``` - { - model_store_format: bco.json - } - ``` - 2. Get `storageRequestId` from response and poll GET `api/short_term_storage/${storageRequestId}/ready` until `SUCCESS` - - 3. Get the resulting file with `api/short_term_storage/${storageRequestId}` - """ - bco = self._deprecated_generate_bco(trans, invocation_id, merge_history_metadata) - return StreamingResponse( - content=BytesIO(bco), - media_type="application/json", - headers={ - "Content-Disposition": f'attachment; filename="bco_{trans.security.encode_id(invocation_id)}.json"', - "Access-Control-Expose-Headers": "Content-Disposition", - }, - ) - - # TODO: remove this after 23.1 release - def _deprecated_generate_bco( - self, trans, invocation_id: DecodedDatabaseIdField, merge_history_metadata: Optional[bool] - ): - export_options = BcoExportOptions( - galaxy_url=trans.request.url_path, - galaxy_version=VERSION, - merge_history_metadata=merge_history_metadata or False, - ) - return self.invocations_service.deprecated_generate_invocation_bco(trans, invocation_id, export_options) diff --git a/lib/galaxy/webapps/galaxy/services/invocations.py b/lib/galaxy/webapps/galaxy/services/invocations.py index f6d7b1c1a60d..9b18db8f1b2d 100644 --- a/lib/galaxy/webapps/galaxy/services/invocations.py +++ b/lib/galaxy/webapps/galaxy/services/invocations.py @@ -1,5 +1,4 @@ import logging -from tempfile import NamedTemporaryFile from typing import ( Any, Dict, @@ -28,10 +27,6 @@ WorkflowInvocation, WorkflowInvocationStep, ) -from galaxy.model.store import ( - BcoExportOptions, - get_export_store_factory, -) from galaxy.schema.fields import DecodedDatabaseIdField from galaxy.schema.invocation import ( CreateInvocationFromStore, @@ -235,25 +230,6 @@ def serialize_workflow_invocation_step( ): return invocation_step.to_dict("element") - # TODO: remove this after 23.1 release - def deprecated_generate_invocation_bco( - self, - trans, - invocation_id: DecodedDatabaseIdField, - export_options: BcoExportOptions, - ): - workflow_invocation = self._workflows_manager.get_invocation(trans, invocation_id, eager=True) - if not workflow_invocation: - raise ObjectNotFound() - - with NamedTemporaryFile() as export_target: - with get_export_store_factory(trans.app, "bco.json", bco_export_options=export_options)( - export_target.name - ) as export_store: - export_store.export_workflow_invocation(workflow_invocation) - export_target.seek(0) - return export_target.read() - def create_from_store( self, trans: ProvidesHistoryContext, diff --git a/lib/galaxy_test/api/test_workflows.py b/lib/galaxy_test/api/test_workflows.py index 36549c820015..4eec65904541 100644 --- a/lib/galaxy_test/api/test_workflows.py +++ b/lib/galaxy_test/api/test_workflows.py @@ -3082,15 +3082,6 @@ def test_workflow_invocation_report_custom(self): assert "## Workflow Inputs" in markdown_content assert "## About This Report" in markdown_content - @skip_without_tool("cat1") - def test_export_invocation_bco(self): - with self.dataset_populator.test_history() as history_id: - summary = self._run_workflow(WORKFLOW_SIMPLE, test_data={"input1": "hello world"}, history_id=history_id) - invocation_id = summary.invocation_id - bco = self.workflow_populator.get_biocompute_object(invocation_id) - self.workflow_populator.validate_biocompute_object(bco) - assert bco["provenance_domain"]["name"] == "Simple Workflow" - @skip_without_tool("cat1") def test_export_invocation_ro_crate(self): with self.dataset_populator.test_history() as history_id: diff --git a/lib/galaxy_test/base/populators.py b/lib/galaxy_test/base/populators.py index e4fd0026245f..1f7db516e50e 100644 --- a/lib/galaxy_test/base/populators.py +++ b/lib/galaxy_test/base/populators.py @@ -1829,11 +1829,6 @@ def create_invocation_from_store( api_asserts.assert_status_code_is_ok(create_response) return create_response.json() - def get_biocompute_object(self, invocation_id): - bco_response = self._get(f"invocations/{invocation_id}/biocompute") - bco_response.raise_for_status() - return bco_response.json() - def validate_biocompute_object( self, bco, expected_schema_version="https://w3id.org/ieee/ieee-2791-schema/2791object.json" ): From 5fa26177275e6e74e77b69c0f18dcc06d2ece207 Mon Sep 17 00:00:00 2001 From: Martin Cech Date: Mon, 22 Apr 2024 12:49:01 -0700 Subject: [PATCH 2/3] readd a bco.json invocation export API test --- lib/galaxy_test/api/test_workflows.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/galaxy_test/api/test_workflows.py b/lib/galaxy_test/api/test_workflows.py index 4eec65904541..89129d1dcb68 100644 --- a/lib/galaxy_test/api/test_workflows.py +++ b/lib/galaxy_test/api/test_workflows.py @@ -3082,6 +3082,15 @@ def test_workflow_invocation_report_custom(self): assert "## Workflow Inputs" in markdown_content assert "## About This Report" in markdown_content + @skip_without_tool("cat1") + def test_export_invocation_bco(self): + with self.dataset_populator.test_history() as history_id: + summary = self._run_workflow(WORKFLOW_SIMPLE, test_data={"input1": "hello world"}, history_id=history_id) + invocation_id = summary.invocation_id + bco = self.workflow_populator.download_invocation_to_store(invocation_id, extension="bco.json") + self.workflow_populator.validate_biocompute_object(bco) + assert bco["provenance_domain"]["name"] == "Simple Workflow" + @skip_without_tool("cat1") def test_export_invocation_ro_crate(self): with self.dataset_populator.test_history() as history_id: From bf14bcdaa389b094b0a3784b2ef810cb9a685d27 Mon Sep 17 00:00:00 2001 From: Martin Cech Date: Mon, 22 Apr 2024 15:50:34 -0700 Subject: [PATCH 3/3] validate the contents, not the path to file --- lib/galaxy_test/api/test_workflows.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/galaxy_test/api/test_workflows.py b/lib/galaxy_test/api/test_workflows.py index 89129d1dcb68..76ba3674e20f 100644 --- a/lib/galaxy_test/api/test_workflows.py +++ b/lib/galaxy_test/api/test_workflows.py @@ -3087,7 +3087,9 @@ def test_export_invocation_bco(self): with self.dataset_populator.test_history() as history_id: summary = self._run_workflow(WORKFLOW_SIMPLE, test_data={"input1": "hello world"}, history_id=history_id) invocation_id = summary.invocation_id - bco = self.workflow_populator.download_invocation_to_store(invocation_id, extension="bco.json") + bco_path = self.workflow_populator.download_invocation_to_store(invocation_id, extension="bco.json") + with open(bco_path) as f: + bco = json.load(f) self.workflow_populator.validate_biocompute_object(bco) assert bco["provenance_domain"]["name"] == "Simple Workflow"