Skip to content

Commit ee6245b

Browse files
Smedsmvdbeek
authored andcommitted
this update will make it possible to list all invocations without knowing the workflow id, invocations will then be grouped by workflow. The user will also have to option of outputing the list as a json.
1 parent ede0085 commit ee6245b

File tree

2 files changed

+92
-35
lines changed

2 files changed

+92
-35
lines changed

planemo/commands/cmd_list_invocations.py

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
from planemo import options
88
from planemo.cli import command_function
99
from planemo.galaxy import profiles
10-
from planemo.galaxy.api import get_invocations
10+
from planemo.galaxy.api import (
11+
get_invocations,
12+
gi,
13+
)
1114
from planemo.galaxy.workflows import remote_runnable_to_workflow_id
1215
from planemo.io import (
1316
error,
@@ -25,59 +28,104 @@
2528
@click.argument(
2629
"workflow_identifier",
2730
type=click.STRING,
31+
required=False,
32+
default="",
33+
)
34+
@click.option(
35+
"--raw",
36+
is_flag=True,
37+
help="output will be a json structure.",
38+
default=False,
39+
)
40+
@click.option(
41+
"--max_items",
42+
type=click.INT,
43+
help="max number of items returned.",
44+
default=100,
45+
)
46+
@click.option(
47+
"--offset_items",
48+
type=click.INT,
49+
help="skip first X items.",
50+
default=0,
2851
)
2952
@options.profile_option(required=True)
3053
@command_function
31-
def cli(ctx, workflow_identifier, **kwds):
54+
def cli(ctx, workflow_identifier, raw, max_items, offset_items, **kwds):
3255
"""
3356
Get a list of invocations for a particular workflow ID or alias.
3457
"""
35-
info(f"Looking for invocations for workflow {workflow_identifier}...")
36-
runnable = for_runnable_identifier(ctx, workflow_identifier, kwds)
58+
if not raw:
59+
info(f"Looking for invocations for workflow {workflow_identifier}...")
3760
profile = profiles.ensure_profile(ctx, kwds.get("profile"))
38-
assert runnable.is_remote_workflow_uri
39-
workflow_id = remote_runnable_to_workflow_id(runnable)
40-
61+
if workflow_identifier:
62+
runnable = for_runnable_identifier(ctx, workflow_identifier, kwds)
63+
assert runnable.is_remote_workflow_uri
64+
workflow_id = remote_runnable_to_workflow_id(runnable)
65+
else:
66+
workflow_id = ""
67+
gi_client = gi(None, profile["galaxy_url"], profile["galaxy_admin_key"] or profile["galaxy_user_key"])
4168
invocations = get_invocations(
42-
url=profile["galaxy_url"],
43-
key=profile["galaxy_admin_key"] or profile["galaxy_user_key"],
69+
gi=gi_client,
4470
workflow_id=workflow_id,
71+
instance=True,
72+
max_items=max_items,
73+
offset_items=offset_items,
4574
)
75+
if raw:
76+
print(json.dumps(invocations, indent=4, sort_keys=True))
77+
return
4678
if tabulate is not None:
4779
state_colors = {
4880
"ok": "\033[92m", # green
4981
"running": "\033[93m", # yellow
5082
"error": "\033[91m", # red
5183
"paused": "\033[96m", # cyan
5284
"deleted": "\033[95m", # magenta
85+
"deleting": "\033[95m", # magenta
5386
"deleted_new": "\033[95m", # magenta
5487
"new": "\033[96m", # cyan
5588
"queued": "\033[93m", # yellow
89+
"skipped": "\033[90m", # gray
5690
}
57-
print(
58-
tabulate(
59-
{
60-
"Invocation ID": invocations.keys(),
61-
"Jobs status": [
62-
", ".join([f"{state_colors[k]}{v} jobs {k}\033[0m" for k, v in inv["states"].items()])
63-
for inv in invocations.values()
64-
],
65-
"Invocation report URL": [
66-
"{}/workflows/invocations/report?id={}".format(profile["galaxy_url"].strip("/"), inv_id)
67-
for inv_id in invocations
68-
],
69-
"History URL": [
70-
"{}/histories/view?id={}".format(
71-
profile["galaxy_url"].strip("/"), invocations[inv_id]["history_id"]
72-
)
73-
for inv_id in invocations
74-
],
75-
},
76-
headers="keys",
91+
92+
grouped_invocations = {}
93+
workflows = {}
94+
for inv_id, inv in invocations.items():
95+
wf_id = inv["workflow_id"]
96+
if wf_id not in grouped_invocations:
97+
workflow = gi_client.workflows.show_workflow(workflow_id=wf_id, instance=True)
98+
workflows[wf_id] = (workflow["name"], workflow["id"])
99+
grouped_invocations.setdefault(wf_id, {})[inv_id] = inv
100+
for workflow_id, data in grouped_invocations.items():
101+
header = f"Workflow: {workflows[workflow_id][0]} : {profile['galaxy_url'].strip('/')}/workflows/run?id={workflows[workflow_id][1]}"
102+
print(f"\n{header}")
103+
print(len(header) * "=")
104+
print(
105+
tabulate(
106+
{
107+
"Invocation ID": data.keys(),
108+
"Invocation report URL": [
109+
"{}/workflows/invocations/report?id={}".format(profile["galaxy_url"].strip("/"), inv_id)
110+
for inv_id in data
111+
],
112+
"History URL": [
113+
"{}/histories/view?id={}".format(
114+
profile["galaxy_url"].strip("/"), invocations[inv_id]["history_id"]
115+
)
116+
for inv_id in data
117+
],
118+
"Jobs status": [
119+
", ".join([f"{state_colors[k]}{v} jobs {k}\033[0m" for k, v in inv["states"].items()])
120+
for inv in data.values()
121+
],
122+
},
123+
headers="keys",
124+
)
77125
)
78-
)
79126
else:
80127
error("The tabulate package is not installed, invocations could not be listed correctly.")
81128
print(json.dumps(invocations, indent=4, sort_keys=True))
82-
info(f"{len(invocations)} invocations found.")
129+
if not raw:
130+
info(f"{len(invocations)} invocations found.")
83131
return

planemo/galaxy/api.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,21 @@ def summarize_history(ctx, gi, history_id):
116116
print("|")
117117

118118

119-
def get_invocations(url, key, workflow_id):
120-
inv_gi = gi(None, url, key)
121-
invocations = inv_gi.workflows.get_invocations(workflow_id)
119+
def get_invocations(gi, workflow_id, instance=False, max_items=100, items_per_request=20, offset_items=0):
120+
invocations = []
121+
while len(invocations) < max_items:
122+
if workflow_id:
123+
items = gi.invocations.get_invocations(workflow_id, limit=min(items_per_request, max_items), offset=len(invocations) + offset_items)
124+
else:
125+
items = gi.invocations.get_invocations(instance=instance, limit=min(items_per_request, max_items), offset=len(invocations) + offset_items)
126+
if (items is None) or (len(items) == 0):
127+
break
128+
else:
129+
invocations.extend(items)
122130
return {
123131
invocation["id"]: {
124-
"states": inv_gi.invocations.get_invocation_summary(invocation["id"])["states"],
132+
"states": gi.invocations.get_invocation_summary(invocation["id"])["states"],
133+
"workflow_id": invocation["workflow_id"],
125134
"history_id": invocation["history_id"],
126135
}
127136
for invocation in invocations

0 commit comments

Comments
 (0)