mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Filter out subworkflow invocations
I think users don't need to see their nested invocations from the main invocation list. If needed they can be found through the invocation steps. The only exception we're making is that we show subworkflow invocations if filtering for a specific workflow id.
This commit is contained in:
@@ -16759,6 +16759,7 @@ export interface operations {
|
||||
instance?: boolean | null;
|
||||
view?: string | null;
|
||||
step_details?: boolean;
|
||||
include_nested_invocations?: boolean;
|
||||
};
|
||||
/** @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?: {
|
||||
|
||||
@@ -200,6 +200,8 @@ export default {
|
||||
const extraParams = this.ownerGrid ? {} : { include_terminal: false };
|
||||
if (this.storedWorkflowId) {
|
||||
extraParams["workflow_id"] = this.storedWorkflowId;
|
||||
} else {
|
||||
extraParams["include_nested_invocations"] = false;
|
||||
}
|
||||
if (this.historyId) {
|
||||
extraParams["history_id"] = this.historyId;
|
||||
|
||||
@@ -69,6 +69,7 @@ from galaxy.model import (
|
||||
Workflow,
|
||||
WorkflowInvocation,
|
||||
WorkflowInvocationStep,
|
||||
WorkflowInvocationToSubworkflowInvocationAssociation,
|
||||
)
|
||||
from galaxy.model.base import (
|
||||
ensure_object_added_to_session,
|
||||
@@ -486,6 +487,7 @@ class WorkflowsManager(sharable.SharableModelManager, deletable.DeletableManager
|
||||
offset=None,
|
||||
sort_by=None,
|
||||
sort_desc=None,
|
||||
include_nested_invocations=True,
|
||||
) -> Tuple[Query, int]:
|
||||
"""Get invocations owned by the current user."""
|
||||
|
||||
@@ -503,6 +505,16 @@ class WorkflowsManager(sharable.SharableModelManager, deletable.DeletableManager
|
||||
stmt = stmt.join(WorkflowInvocationStep).where(WorkflowInvocationStep.job_id == job_id)
|
||||
if not include_terminal:
|
||||
stmt = stmt.where(WorkflowInvocation.state.in_(WorkflowInvocation.non_terminal_states))
|
||||
if not include_nested_invocations:
|
||||
subquery = (
|
||||
select(WorkflowInvocationToSubworkflowInvocationAssociation.id)
|
||||
.where(
|
||||
WorkflowInvocationToSubworkflowInvocationAssociation.subworkflow_invocation_id
|
||||
== WorkflowInvocation.id
|
||||
)
|
||||
.exists()
|
||||
)
|
||||
stmt = stmt.where(~subquery)
|
||||
|
||||
total_matches = get_count(trans.sa_session, stmt)
|
||||
|
||||
@@ -2091,5 +2103,5 @@ def _get_invocation(session, eager, invocation_id):
|
||||
|
||||
|
||||
def get_count(session, statement):
|
||||
stmt = select(func.count()).select_from(statement)
|
||||
stmt = select(func.count()).select_from(statement.subquery())
|
||||
return session.scalar(stmt)
|
||||
|
||||
@@ -1452,6 +1452,7 @@ class InvocationIndexQueryPayload(Model):
|
||||
lt=1000,
|
||||
)
|
||||
offset: Optional[int] = Field(default=0, description="Number of invocations to skip")
|
||||
include_nested_invocations: bool = True
|
||||
|
||||
|
||||
PageSortByEnum = Literal["create_time", "title", "update_time", "username"]
|
||||
|
||||
@@ -1324,6 +1324,7 @@ class FastAPIInvocations:
|
||||
instance: InvocationsInstanceQueryParam = False,
|
||||
view: SerializationViewQueryParam = None,
|
||||
step_details: StepDetailQueryParam = False,
|
||||
include_nested_invocations: bool = True,
|
||||
trans: ProvidesUserContext = DependsOnTrans,
|
||||
) -> List[WorkflowInvocationResponse]:
|
||||
invocation_payload = InvocationIndexPayload(
|
||||
@@ -1337,6 +1338,7 @@ class FastAPIInvocations:
|
||||
limit=limit,
|
||||
offset=offset,
|
||||
instance=instance,
|
||||
include_nested_invocations=include_nested_invocations,
|
||||
)
|
||||
serialization_params = InvocationSerializationParams(
|
||||
view=view,
|
||||
|
||||
@@ -126,6 +126,7 @@ class InvocationsService(ServiceBase, ConsumesModelStores):
|
||||
offset=invocation_payload.offset,
|
||||
sort_by=invocation_payload.sort_by,
|
||||
sort_desc=invocation_payload.sort_desc,
|
||||
include_nested_invocations=invocation_payload.include_nested_invocations,
|
||||
)
|
||||
invocation_dict = self.serialize_workflow_invocations(invocations, serialization_params)
|
||||
return invocation_dict, total_matches
|
||||
|
||||
@@ -7145,6 +7145,20 @@ input_c:
|
||||
usage_details_response = self._get(f"workflows/{workflow_id}/usage/{invocation_id}")
|
||||
self._assert_status_code_is(usage_details_response, 403)
|
||||
|
||||
def test_invocation_filtering_exclude_subworkflow(self):
|
||||
with self.dataset_populator.test_history() as history_id:
|
||||
self._run_workflow(
|
||||
WORKFLOW_NESTED_SIMPLE,
|
||||
test_data="""
|
||||
outer_input:
|
||||
value: 1.bed
|
||||
type: File
|
||||
""",
|
||||
history_id=history_id,
|
||||
)
|
||||
assert len(self.workflow_populator.history_invocations(history_id)) == 2
|
||||
assert len(self.workflow_populator.history_invocations(history_id, include_nested_invocations=False)) == 1
|
||||
|
||||
def test_workflow_publishing(self):
|
||||
workflow_id = self.workflow_populator.simple_workflow("dummy")
|
||||
response = self._show_workflow(workflow_id)
|
||||
|
||||
@@ -1701,7 +1701,7 @@ class BaseWorkflowPopulator(BasePopulator):
|
||||
|
||||
return wait_on_state(workflow_state, desc="workflow invocation state", timeout=timeout, assert_ok=assert_ok)
|
||||
|
||||
def workflow_invocations(self, workflow_id: str) -> List[Dict[str, Any]]:
|
||||
def workflow_invocations(self, workflow_id: str, include_nested_invocations=True) -> List[Dict[str, Any]]:
|
||||
response = self._get(f"workflows/{workflow_id}/invocations")
|
||||
api_asserts.assert_status_code_is(response, 200)
|
||||
return response.json()
|
||||
@@ -1711,8 +1711,10 @@ class BaseWorkflowPopulator(BasePopulator):
|
||||
api_asserts.assert_status_code_is(response, 200)
|
||||
return response.json()
|
||||
|
||||
def history_invocations(self, history_id: str) -> List[Dict[str, Any]]:
|
||||
history_invocations_response = self._get("invocations", {"history_id": history_id})
|
||||
def history_invocations(self, history_id: str, include_nested_invocations: bool = True) -> List[Dict[str, Any]]:
|
||||
history_invocations_response = self._get(
|
||||
"invocations", {"history_id": history_id, "include_nested_invocations": include_nested_invocations}
|
||||
)
|
||||
api_asserts.assert_status_code_is(history_invocations_response, 200)
|
||||
return history_invocations_response.json()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user