|
7 | 7 | from planemo import options |
8 | 8 | from planemo.cli import command_function |
9 | 9 | 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 | +) |
11 | 14 | from planemo.galaxy.workflows import remote_runnable_to_workflow_id |
12 | 15 | from planemo.io import ( |
13 | 16 | error, |
|
25 | 28 | @click.argument( |
26 | 29 | "workflow_identifier", |
27 | 30 | 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, |
28 | 51 | ) |
29 | 52 | @options.profile_option(required=True) |
30 | 53 | @command_function |
31 | | -def cli(ctx, workflow_identifier, **kwds): |
| 54 | +def cli(ctx, workflow_identifier, raw, max_items, offset_items, **kwds): |
32 | 55 | """ |
33 | 56 | Get a list of invocations for a particular workflow ID or alias. |
34 | 57 | """ |
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}...") |
37 | 60 | 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"]) |
41 | 68 | invocations = get_invocations( |
42 | | - url=profile["galaxy_url"], |
43 | | - key=profile["galaxy_admin_key"] or profile["galaxy_user_key"], |
| 69 | + gi=gi_client, |
44 | 70 | workflow_id=workflow_id, |
| 71 | + instance=True, |
| 72 | + max_items=max_items, |
| 73 | + offset_items=offset_items, |
45 | 74 | ) |
| 75 | + if raw: |
| 76 | + print(json.dumps(invocations, indent=4, sort_keys=True)) |
| 77 | + return |
46 | 78 | if tabulate is not None: |
47 | 79 | state_colors = { |
48 | 80 | "ok": "\033[92m", # green |
49 | 81 | "running": "\033[93m", # yellow |
50 | 82 | "error": "\033[91m", # red |
51 | 83 | "paused": "\033[96m", # cyan |
52 | 84 | "deleted": "\033[95m", # magenta |
| 85 | + "deleting": "\033[95m", # magenta |
53 | 86 | "deleted_new": "\033[95m", # magenta |
54 | 87 | "new": "\033[96m", # cyan |
55 | 88 | "queued": "\033[93m", # yellow |
| 89 | + "skipped": "\033[90m", # gray |
56 | 90 | } |
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 | + ) |
77 | 125 | ) |
78 | | - ) |
79 | 126 | else: |
80 | 127 | error("The tabulate package is not installed, invocations could not be listed correctly.") |
81 | 128 | 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.") |
83 | 131 | return |
0 commit comments