terralab-cli 3.1.8__tar.gz → 3.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/PKG-INFO +1 -1
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/pyproject.toml +1 -1
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/commands/pipeline_runs_commands.py +31 -1
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/logic/pipeline_runs_logic.py +1 -1
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/utils.py +12 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/LICENSE +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/README.md +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/.terralab-cli-config +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/__init__.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/auth_helper.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/cli.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/client.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/commands/__init__.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/commands/account_commands.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/commands/auth_commands.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/commands/pipelines_commands.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/commands/quotas_commands.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/config.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/constants.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/log.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/logic/__init__.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/logic/account_logic.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/logic/auth_logic.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/logic/pipelines_logic.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/logic/quotas_logic.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/sam_helper.py +0 -0
- {terralab_cli-3.1.8 → terralab_cli-3.2.0}/terralab/version_utils.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "terralab-cli"
|
|
3
3
|
# version is auto-incremented. do not edit.
|
|
4
|
-
version = "3.
|
|
4
|
+
version = "3.2.0"
|
|
5
5
|
description = "Command line interface for interacting with the Terra Scientific Pipelines Service, or Teaspoons."
|
|
6
6
|
authors = ["Terra Scientific Services <teaspoons-developers@broadinstitute.org>"]
|
|
7
7
|
readme = "README.md"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# commands/pipeline_runs_commands.py
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from typing import Any
|
|
4
5
|
import uuid
|
|
5
6
|
|
|
6
7
|
import click
|
|
@@ -15,6 +16,7 @@ from terralab.log import (
|
|
|
15
16
|
)
|
|
16
17
|
from terralab.logic import pipeline_runs_logic, pipelines_logic
|
|
17
18
|
from terralab.utils import (
|
|
19
|
+
convert_file_size_to_human_readable,
|
|
18
20
|
handle_api_exceptions,
|
|
19
21
|
process_inputs_to_dict,
|
|
20
22
|
validate_job_id,
|
|
@@ -117,7 +119,8 @@ def details(job_id: str) -> None:
|
|
|
117
119
|
|
|
118
120
|
LOGGER.info(indented("Inputs:"))
|
|
119
121
|
for input_name, input_value in response.pipeline_run_report.user_inputs.items():
|
|
120
|
-
LOGGER.info(indented(f"{input_name}:
|
|
122
|
+
LOGGER.info(indented(f"{input_name}:", n_spaces=4))
|
|
123
|
+
LOGGER.info(indented(input_value, n_spaces=6))
|
|
121
124
|
|
|
122
125
|
if response.pipeline_run_report.input_size:
|
|
123
126
|
LOGGER.info(
|
|
@@ -141,6 +144,7 @@ def details(job_id: str) -> None:
|
|
|
141
144
|
LOGGER.info(indented(f"Quota Consumed: {quota_consumed}"))
|
|
142
145
|
|
|
143
146
|
if response.job_report.status == SUCCEEDED_KEY:
|
|
147
|
+
display_outputs(response.pipeline_run_report.outputs)
|
|
144
148
|
LOGGER.info(
|
|
145
149
|
indented(
|
|
146
150
|
f"File Download Expiration: {format_timestamp(response.pipeline_run_report.output_expiration_date, timestamp_format)}"
|
|
@@ -148,6 +152,32 @@ def details(job_id: str) -> None:
|
|
|
148
152
|
)
|
|
149
153
|
|
|
150
154
|
|
|
155
|
+
def display_outputs(outputs: dict[str, dict[str, Any]] | None) -> None:
|
|
156
|
+
if not outputs:
|
|
157
|
+
return
|
|
158
|
+
LOGGER.info(indented("Outputs:"))
|
|
159
|
+
for (
|
|
160
|
+
output_name,
|
|
161
|
+
output_value,
|
|
162
|
+
) in outputs.items():
|
|
163
|
+
if "metadata" in output_value and "sizeInBytes" in output_value["metadata"]:
|
|
164
|
+
output_size_string = f"({convert_file_size_to_human_readable(output_value['metadata']['sizeInBytes'])})"
|
|
165
|
+
else:
|
|
166
|
+
output_size_string = ""
|
|
167
|
+
LOGGER.info(
|
|
168
|
+
indented(
|
|
169
|
+
f"{output_name}:",
|
|
170
|
+
n_spaces=4,
|
|
171
|
+
)
|
|
172
|
+
)
|
|
173
|
+
LOGGER.info(
|
|
174
|
+
indented(
|
|
175
|
+
f"{output_value['value']} {output_size_string}",
|
|
176
|
+
n_spaces=6,
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
151
181
|
@jobs.command(name="list", short_help="List your jobs")
|
|
152
182
|
@click.option(
|
|
153
183
|
"--num_results",
|
|
@@ -82,7 +82,7 @@ def get_pipeline_run_status(job_id: uuid.UUID) -> AsyncPipelineRunResponseV2:
|
|
|
82
82
|
|
|
83
83
|
with ClientWrapper() as api_client:
|
|
84
84
|
pipeline_runs_client = PipelineRunsApi(api_client=api_client)
|
|
85
|
-
return pipeline_runs_client.
|
|
85
|
+
return pipeline_runs_client.get_pipeline_run_result_v3(str(job_id))
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
def get_pipeline_run_output_signed_urls(
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import datetime
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
|
+
import math
|
|
6
7
|
import os
|
|
7
8
|
import uuid
|
|
8
9
|
from concurrent.futures import ThreadPoolExecutor
|
|
@@ -165,6 +166,17 @@ def validate_file_size(file_path: str) -> str | None:
|
|
|
165
166
|
return None
|
|
166
167
|
|
|
167
168
|
|
|
169
|
+
def convert_file_size_to_human_readable(size_bytes: int) -> str:
|
|
170
|
+
"""Convert a file size in bytes to a human-readable string with appropriate units."""
|
|
171
|
+
if size_bytes == 0:
|
|
172
|
+
return "0 B"
|
|
173
|
+
size_name = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB")
|
|
174
|
+
i = int(math.floor(math.log(size_bytes, 1024)))
|
|
175
|
+
p = math.pow(1024, i)
|
|
176
|
+
s = round(size_bytes / p, 1) if p > 1 else size_bytes
|
|
177
|
+
return "%s %s" % (s, size_name[i])
|
|
178
|
+
|
|
179
|
+
|
|
168
180
|
## upload and download methods
|
|
169
181
|
PROGRESS_BAR_FORMAT = "{desc}: {percentage:3.0f}%|{bar}| {n_fmt}/{total_fmt} [elapsed: {elapsed} ETA: {remaining} ({rate_fmt}{postfix})]"
|
|
170
182
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|