cloudos-cli 2.19.0__tar.gz → 2.20.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.
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/PKG-INFO +23 -5
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/README.md +22 -4
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/__main__.py +71 -3
- cloudos_cli-2.20.0/cloudos_cli/_version.py +1 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/clos.py +30 -2
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/jobs/job.py +1 -1
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/utils/requests.py +34 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli.egg-info/PKG-INFO +23 -5
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli.egg-info/SOURCES.txt +1 -0
- cloudos_cli-2.20.0/tests/test_clos/test_abort_job.py +68 -0
- cloudos_cli-2.19.0/cloudos_cli/_version.py +0 -1
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/LICENSE +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/__init__.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/jobs/__init__.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/queue/__init__.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/queue/queue.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/utils/__init__.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli/utils/errors.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli.egg-info/dependency_links.txt +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli.egg-info/entry_points.txt +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli.egg-info/requires.txt +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/cloudos_cli.egg-info/top_level.txt +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/setup.cfg +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/setup.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/__init__.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/functions_for_pytest.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/__init__.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_create_cromwell_header.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_cromwell_switch.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_detect_workflow.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_get_cromwell_status.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_get_curated_workflow_list.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_get_job_list.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_get_job_status.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_get_project_list.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_get_user_info.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_get_workflow_list.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_is_module.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_process_job_list.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_process_project_list.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_process_workflow_list.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_wait_job_completion.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_clos/test_workflow_import.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_jobs/__init__.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_jobs/test_convert_nextflow_to_json.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_jobs/test_project_id.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_jobs/test_send_job.py +0 -0
- {cloudos_cli-2.19.0 → cloudos_cli-2.20.0}/tests/test_jobs/test_workflow_id.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudos_cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.20.0
|
|
4
4
|
Summary: Python package for interacting with CloudOS
|
|
5
5
|
Home-page: https://github.com/lifebit-ai/cloudos-cli
|
|
6
6
|
Author: David Piñeyro
|
|
@@ -285,10 +285,10 @@ If everything went well, you should see something like:
|
|
|
285
285
|
|
|
286
286
|
```console
|
|
287
287
|
Executing run...
|
|
288
|
-
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/
|
|
288
|
+
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355
|
|
289
289
|
Your assigned job id is: 62c83a1191fe06013b7ef355
|
|
290
290
|
Your current job status is: initializing
|
|
291
|
-
To further check your job status you can either go to https://cloudos.lifebit.ai/app/
|
|
291
|
+
To further check your job status you can either go to https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355 or use the following command:
|
|
292
292
|
cloudos job status \
|
|
293
293
|
--apikey $MY_API_KEY \
|
|
294
294
|
--cloudos-url https://cloudos.lifebit.ai \
|
|
@@ -321,7 +321,7 @@ previous command should have an output similar to:
|
|
|
321
321
|
|
|
322
322
|
```console
|
|
323
323
|
Executing run...
|
|
324
|
-
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/
|
|
324
|
+
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a6191fe06013b7ef363
|
|
325
325
|
Your assigned job id is: 62c83a6191fe06013b7ef363
|
|
326
326
|
Please, wait until job completion or max wait time of 3600 seconds is reached.
|
|
327
327
|
Your current job status is: initializing.
|
|
@@ -329,6 +329,24 @@ Executing run...
|
|
|
329
329
|
Your job took 420 seconds to complete successfully.
|
|
330
330
|
```
|
|
331
331
|
|
|
332
|
+
#### Abort single or multiple jobs from CloudOS
|
|
333
|
+
|
|
334
|
+
Aborts jobs in the CloudOS workspace that are either running or initialising. It can be used with one or more job IDs provided as a comma separated string using the `--job-ids` parameter.
|
|
335
|
+
|
|
336
|
+
Example:
|
|
337
|
+
```console
|
|
338
|
+
cloudos job abort \
|
|
339
|
+
--cloudos-url $CLOUDOS \
|
|
340
|
+
--apikey $MY_API_KEY \
|
|
341
|
+
--workspace-id $WORKSPACE_ID \
|
|
342
|
+
--job-ids "680a3cf80e56949775c02f16"
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
Aborting jobs...
|
|
346
|
+
Job 680a3cf80e56949775c02f16 aborted successfully.
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
|
|
332
350
|
#### Executor support
|
|
333
351
|
|
|
334
352
|
CloudOS supports [AWS batch](https://www.nextflow.io/docs/latest/executor.html?highlight=executors#aws-batch) executor by default.
|
|
@@ -423,7 +441,7 @@ The expected output should be something similar to:
|
|
|
423
441
|
Executing status...
|
|
424
442
|
Your current job status is: completed
|
|
425
443
|
|
|
426
|
-
To further check your job status you can either go to https://cloudos.lifebit.ai/app/
|
|
444
|
+
To further check your job status you can either go to https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355 or repeat the command you just used.
|
|
427
445
|
```
|
|
428
446
|
|
|
429
447
|
#### Get a list of your jobs from a CloudOS workspace
|
|
@@ -250,10 +250,10 @@ If everything went well, you should see something like:
|
|
|
250
250
|
|
|
251
251
|
```console
|
|
252
252
|
Executing run...
|
|
253
|
-
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/
|
|
253
|
+
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355
|
|
254
254
|
Your assigned job id is: 62c83a1191fe06013b7ef355
|
|
255
255
|
Your current job status is: initializing
|
|
256
|
-
To further check your job status you can either go to https://cloudos.lifebit.ai/app/
|
|
256
|
+
To further check your job status you can either go to https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355 or use the following command:
|
|
257
257
|
cloudos job status \
|
|
258
258
|
--apikey $MY_API_KEY \
|
|
259
259
|
--cloudos-url https://cloudos.lifebit.ai \
|
|
@@ -286,7 +286,7 @@ previous command should have an output similar to:
|
|
|
286
286
|
|
|
287
287
|
```console
|
|
288
288
|
Executing run...
|
|
289
|
-
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/
|
|
289
|
+
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a6191fe06013b7ef363
|
|
290
290
|
Your assigned job id is: 62c83a6191fe06013b7ef363
|
|
291
291
|
Please, wait until job completion or max wait time of 3600 seconds is reached.
|
|
292
292
|
Your current job status is: initializing.
|
|
@@ -294,6 +294,24 @@ Executing run...
|
|
|
294
294
|
Your job took 420 seconds to complete successfully.
|
|
295
295
|
```
|
|
296
296
|
|
|
297
|
+
#### Abort single or multiple jobs from CloudOS
|
|
298
|
+
|
|
299
|
+
Aborts jobs in the CloudOS workspace that are either running or initialising. It can be used with one or more job IDs provided as a comma separated string using the `--job-ids` parameter.
|
|
300
|
+
|
|
301
|
+
Example:
|
|
302
|
+
```console
|
|
303
|
+
cloudos job abort \
|
|
304
|
+
--cloudos-url $CLOUDOS \
|
|
305
|
+
--apikey $MY_API_KEY \
|
|
306
|
+
--workspace-id $WORKSPACE_ID \
|
|
307
|
+
--job-ids "680a3cf80e56949775c02f16"
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
Aborting jobs...
|
|
311
|
+
Job 680a3cf80e56949775c02f16 aborted successfully.
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
|
|
297
315
|
#### Executor support
|
|
298
316
|
|
|
299
317
|
CloudOS supports [AWS batch](https://www.nextflow.io/docs/latest/executor.html?highlight=executors#aws-batch) executor by default.
|
|
@@ -388,7 +406,7 @@ The expected output should be something similar to:
|
|
|
388
406
|
Executing status...
|
|
389
407
|
Your current job status is: completed
|
|
390
408
|
|
|
391
|
-
To further check your job status you can either go to https://cloudos.lifebit.ai/app/
|
|
409
|
+
To further check your job status you can either go to https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355 or repeat the command you just used.
|
|
392
410
|
```
|
|
393
411
|
|
|
394
412
|
#### Get a list of your jobs from a CloudOS workspace
|
|
@@ -24,6 +24,7 @@ HPC_NEXTFLOW_VERSIONS = ['22.10.8']
|
|
|
24
24
|
AWS_NEXTFLOW_LATEST = '24.04.4'
|
|
25
25
|
AZURE_NEXTFLOW_LATEST = '22.11.1-edge'
|
|
26
26
|
HPC_NEXTFLOW_LATEST = '22.10.8'
|
|
27
|
+
ABORT_JOB_STATES = ['running', 'initializing']
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
def ssl_selector(disable_ssl_verification, ssl_cert):
|
|
@@ -68,7 +69,7 @@ def run_cloudos_cli():
|
|
|
68
69
|
|
|
69
70
|
@run_cloudos_cli.group()
|
|
70
71
|
def job():
|
|
71
|
-
"""CloudOS job functionality: run and
|
|
72
|
+
"""CloudOS job functionality: run, check and abort jobs in CloudOS."""
|
|
72
73
|
print(job.__doc__ + '\n')
|
|
73
74
|
|
|
74
75
|
|
|
@@ -466,7 +467,7 @@ def run(apikey,
|
|
|
466
467
|
docker_login=docker_login,
|
|
467
468
|
verify=verify_ssl)
|
|
468
469
|
print(f'\tYour assigned job id is: {j_id}\n')
|
|
469
|
-
j_url = f'{cloudos_url}/app/
|
|
470
|
+
j_url = f'{cloudos_url}/app/advanced-analytics/analyses/{j_id}'
|
|
470
471
|
if wait_completion:
|
|
471
472
|
print('\tPlease, wait until job completion (max wait time of ' +
|
|
472
473
|
f'{wait_time} seconds).\n')
|
|
@@ -752,7 +753,7 @@ def job_status(apikey,
|
|
|
752
753
|
j_status = cl.get_job_status(job_id, verify_ssl)
|
|
753
754
|
j_status_h = json.loads(j_status.content)["status"]
|
|
754
755
|
print(f'\tYour current job status is: {j_status_h}\n')
|
|
755
|
-
j_url = f'{cloudos_url}/app/
|
|
756
|
+
j_url = f'{cloudos_url}/app/advanced-analytics/analyses/{job_id}'
|
|
756
757
|
print(f'\tTo further check your job status you can either go to {j_url} ' +
|
|
757
758
|
'or repeat the command you just used.')
|
|
758
759
|
|
|
@@ -859,6 +860,73 @@ def list_jobs(apikey,
|
|
|
859
860
|
print(f'\tJob list saved to {outfile}')
|
|
860
861
|
|
|
861
862
|
|
|
863
|
+
@job.command('abort')
|
|
864
|
+
@click.option('-k',
|
|
865
|
+
'--apikey',
|
|
866
|
+
help='Your CloudOS API key',
|
|
867
|
+
required=True)
|
|
868
|
+
@click.option('-c',
|
|
869
|
+
'--cloudos-url',
|
|
870
|
+
help=('The CloudOS url you are trying to access to. ' +
|
|
871
|
+
'Default=https://cloudos.lifebit.ai.'),
|
|
872
|
+
default='https://cloudos.lifebit.ai')
|
|
873
|
+
@click.option('--workspace-id',
|
|
874
|
+
help='The specific CloudOS workspace id.',
|
|
875
|
+
required=True)
|
|
876
|
+
@click.option('--job-ids',
|
|
877
|
+
help=('One or more job ids to abort. If more than ' +
|
|
878
|
+
'one is provided, they must be provided as ' +
|
|
879
|
+
'a comma separated list of ids. E.g. id1,id2,id3'),
|
|
880
|
+
required=True)
|
|
881
|
+
@click.option('--verbose',
|
|
882
|
+
help='Whether to print information messages or not.',
|
|
883
|
+
is_flag=True)
|
|
884
|
+
@click.option('--disable-ssl-verification',
|
|
885
|
+
help=('Disable SSL certificate verification. Please, remember that this option is ' +
|
|
886
|
+
'not generally recommended for security reasons.'),
|
|
887
|
+
is_flag=True)
|
|
888
|
+
@click.option('--ssl-cert',
|
|
889
|
+
help='Path to your SSL certificate file.')
|
|
890
|
+
def abort_jobs(apikey,
|
|
891
|
+
cloudos_url,
|
|
892
|
+
workspace_id,
|
|
893
|
+
job_ids,
|
|
894
|
+
verbose,
|
|
895
|
+
disable_ssl_verification,
|
|
896
|
+
ssl_cert):
|
|
897
|
+
"""Abort all specified jobs from a CloudOS workspace."""
|
|
898
|
+
cloudos_url = cloudos_url.rstrip('/')
|
|
899
|
+
verify_ssl = ssl_selector(disable_ssl_verification, ssl_cert)
|
|
900
|
+
print('Aborting jobs...')
|
|
901
|
+
if verbose:
|
|
902
|
+
print('\t...Preparing objects')
|
|
903
|
+
cl = Cloudos(cloudos_url, apikey, None)
|
|
904
|
+
if verbose:
|
|
905
|
+
print('\tThe following Cloudos object was created:')
|
|
906
|
+
print('\t' + str(cl) + '\n')
|
|
907
|
+
print('\tSearching for jobs in the following workspace: ' +
|
|
908
|
+
f'{workspace_id}')
|
|
909
|
+
# check if the user provided an empty job list
|
|
910
|
+
jobs = job_ids.replace(' ', '')
|
|
911
|
+
if not jobs:
|
|
912
|
+
raise ValueError('No job IDs provided. Please specify at least one job ID to abort.')
|
|
913
|
+
jobs = jobs.split(',')
|
|
914
|
+
|
|
915
|
+
for job in jobs:
|
|
916
|
+
try:
|
|
917
|
+
j_status = cl.get_job_status(job, verify_ssl)
|
|
918
|
+
except Exception as e:
|
|
919
|
+
print(f"[WARNING] Failed to get status for job {job}, please make sure it exists in the workspace: {e}")
|
|
920
|
+
continue
|
|
921
|
+
j_status_content = json.loads(j_status.content)
|
|
922
|
+
# check if job id is valid & is in working state (initial, running)
|
|
923
|
+
if j_status_content['status'] not in ABORT_JOB_STATES:
|
|
924
|
+
print(f"[WARNING] Job {job} is not in a state that can be aborted and is ignored. Current status: {j_status_content['status']}")
|
|
925
|
+
else:
|
|
926
|
+
cl.abort_job(job, workspace_id, verify_ssl)
|
|
927
|
+
print(f"\tJob '{job}' aborted successfully.")
|
|
928
|
+
|
|
929
|
+
|
|
862
930
|
@workflow.command('list')
|
|
863
931
|
@click.option('-k',
|
|
864
932
|
'--apikey',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.20.0'
|
|
@@ -7,7 +7,7 @@ import time
|
|
|
7
7
|
import json
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from cloudos_cli.utils.errors import BadRequestException
|
|
10
|
-
from cloudos_cli.utils.requests import retry_requests_get, retry_requests_post
|
|
10
|
+
from cloudos_cli.utils.requests import retry_requests_get, retry_requests_post, retry_requests_put
|
|
11
11
|
import pandas as pd
|
|
12
12
|
|
|
13
13
|
# GLOBAL VARS
|
|
@@ -87,7 +87,7 @@ class Cloudos:
|
|
|
87
87
|
: dict
|
|
88
88
|
A dict with three elements collected from the job status: 'name', 'id', 'status'.
|
|
89
89
|
"""
|
|
90
|
-
j_url = f'{self.cloudos_url}/app/
|
|
90
|
+
j_url = f'{self.cloudos_url}/app/advanced-analytics/analyses/{job_id}'
|
|
91
91
|
elapsed = 0
|
|
92
92
|
j_status_h_old = ''
|
|
93
93
|
# make sure user doesn't surpass the wait time
|
|
@@ -757,3 +757,31 @@ class Cloudos:
|
|
|
757
757
|
if r.status_code >= 400:
|
|
758
758
|
raise BadRequestException(r)
|
|
759
759
|
return json.loads(r.content)
|
|
760
|
+
|
|
761
|
+
def abort_job(self, job, workspace_id, verify=True):
|
|
762
|
+
"""Abort a job.
|
|
763
|
+
|
|
764
|
+
Parameters
|
|
765
|
+
----------
|
|
766
|
+
job : string
|
|
767
|
+
The CloudOS job id of the job to abort.
|
|
768
|
+
verify: [bool|string]
|
|
769
|
+
Whether to use SSL verification or not. Alternatively, if
|
|
770
|
+
a string is passed, it will be interpreted as the path to
|
|
771
|
+
the SSL certificate file.
|
|
772
|
+
|
|
773
|
+
Returns
|
|
774
|
+
-------
|
|
775
|
+
r : requests.models.Response
|
|
776
|
+
The server response
|
|
777
|
+
"""
|
|
778
|
+
cloudos_url = self.cloudos_url
|
|
779
|
+
apikey = self.apikey
|
|
780
|
+
headers = {
|
|
781
|
+
"Content-type": "application/json",
|
|
782
|
+
"apikey": apikey
|
|
783
|
+
}
|
|
784
|
+
r = retry_requests_put("{}/api/v1/jobs/{}/abort?teamId={}".format(cloudos_url, job, workspace_id), headers=headers, verify=verify)
|
|
785
|
+
if r.status_code >= 400:
|
|
786
|
+
raise BadRequestException(r)
|
|
787
|
+
return r
|
|
@@ -544,5 +544,5 @@ class Job(Cloudos):
|
|
|
544
544
|
raise BadRequestException(r)
|
|
545
545
|
j_id = json.loads(r.content)["_id"]
|
|
546
546
|
print('\tJob successfully launched to CloudOS, please check the ' +
|
|
547
|
-
f'following link: {cloudos_url}/app/
|
|
547
|
+
f'following link: {cloudos_url}/app/advanced-analytics/analyses/{j_id}')
|
|
548
548
|
return j_id
|
|
@@ -73,3 +73,37 @@ def retry_requests_post(url, total=5, status_forcelist=[429, 500, 502, 503, 504]
|
|
|
73
73
|
# Make a request using the session object
|
|
74
74
|
response = session.post(url, **kwargs)
|
|
75
75
|
return response
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def retry_requests_put(url, total=5, status_forcelist=[429, 500, 502, 503, 504], **kwargs):
|
|
79
|
+
"""Wrap normal requests put with an error strategy.
|
|
80
|
+
|
|
81
|
+
Parameters
|
|
82
|
+
----------
|
|
83
|
+
url : string
|
|
84
|
+
The request URL
|
|
85
|
+
total : int
|
|
86
|
+
Total number of retries
|
|
87
|
+
status_forcelist : list
|
|
88
|
+
A list of ints with the status codes to trigger the retries
|
|
89
|
+
|
|
90
|
+
Return
|
|
91
|
+
------
|
|
92
|
+
response : requests.Response
|
|
93
|
+
The Response object returned by the API server
|
|
94
|
+
"""
|
|
95
|
+
retry_strategy = Retry(
|
|
96
|
+
total=total,
|
|
97
|
+
status_forcelist=status_forcelist
|
|
98
|
+
)
|
|
99
|
+
# Create an HTTP adapter with the retry strategy and mount it to session
|
|
100
|
+
adapter = HTTPAdapter(max_retries=retry_strategy)
|
|
101
|
+
|
|
102
|
+
# Create a new session object
|
|
103
|
+
session = requests.Session()
|
|
104
|
+
session.mount('http://', adapter)
|
|
105
|
+
session.mount('https://', adapter)
|
|
106
|
+
|
|
107
|
+
# Make a request using the session object
|
|
108
|
+
response = session.put(url, **kwargs)
|
|
109
|
+
return response
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudos_cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.20.0
|
|
4
4
|
Summary: Python package for interacting with CloudOS
|
|
5
5
|
Home-page: https://github.com/lifebit-ai/cloudos-cli
|
|
6
6
|
Author: David Piñeyro
|
|
@@ -285,10 +285,10 @@ If everything went well, you should see something like:
|
|
|
285
285
|
|
|
286
286
|
```console
|
|
287
287
|
Executing run...
|
|
288
|
-
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/
|
|
288
|
+
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355
|
|
289
289
|
Your assigned job id is: 62c83a1191fe06013b7ef355
|
|
290
290
|
Your current job status is: initializing
|
|
291
|
-
To further check your job status you can either go to https://cloudos.lifebit.ai/app/
|
|
291
|
+
To further check your job status you can either go to https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355 or use the following command:
|
|
292
292
|
cloudos job status \
|
|
293
293
|
--apikey $MY_API_KEY \
|
|
294
294
|
--cloudos-url https://cloudos.lifebit.ai \
|
|
@@ -321,7 +321,7 @@ previous command should have an output similar to:
|
|
|
321
321
|
|
|
322
322
|
```console
|
|
323
323
|
Executing run...
|
|
324
|
-
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/
|
|
324
|
+
Job successfully launched to CloudOS, please check the following link: https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a6191fe06013b7ef363
|
|
325
325
|
Your assigned job id is: 62c83a6191fe06013b7ef363
|
|
326
326
|
Please, wait until job completion or max wait time of 3600 seconds is reached.
|
|
327
327
|
Your current job status is: initializing.
|
|
@@ -329,6 +329,24 @@ Executing run...
|
|
|
329
329
|
Your job took 420 seconds to complete successfully.
|
|
330
330
|
```
|
|
331
331
|
|
|
332
|
+
#### Abort single or multiple jobs from CloudOS
|
|
333
|
+
|
|
334
|
+
Aborts jobs in the CloudOS workspace that are either running or initialising. It can be used with one or more job IDs provided as a comma separated string using the `--job-ids` parameter.
|
|
335
|
+
|
|
336
|
+
Example:
|
|
337
|
+
```console
|
|
338
|
+
cloudos job abort \
|
|
339
|
+
--cloudos-url $CLOUDOS \
|
|
340
|
+
--apikey $MY_API_KEY \
|
|
341
|
+
--workspace-id $WORKSPACE_ID \
|
|
342
|
+
--job-ids "680a3cf80e56949775c02f16"
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
Aborting jobs...
|
|
346
|
+
Job 680a3cf80e56949775c02f16 aborted successfully.
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
|
|
332
350
|
#### Executor support
|
|
333
351
|
|
|
334
352
|
CloudOS supports [AWS batch](https://www.nextflow.io/docs/latest/executor.html?highlight=executors#aws-batch) executor by default.
|
|
@@ -423,7 +441,7 @@ The expected output should be something similar to:
|
|
|
423
441
|
Executing status...
|
|
424
442
|
Your current job status is: completed
|
|
425
443
|
|
|
426
|
-
To further check your job status you can either go to https://cloudos.lifebit.ai/app/
|
|
444
|
+
To further check your job status you can either go to https://cloudos.lifebit.ai/app/advanced-analytics/analyses/62c83a1191fe06013b7ef355 or repeat the command you just used.
|
|
427
445
|
```
|
|
428
446
|
|
|
429
447
|
#### Get a list of your jobs from a CloudOS workspace
|
|
@@ -21,6 +21,7 @@ cloudos_cli/utils/requests.py
|
|
|
21
21
|
tests/__init__.py
|
|
22
22
|
tests/functions_for_pytest.py
|
|
23
23
|
tests/test_clos/__init__.py
|
|
24
|
+
tests/test_clos/test_abort_job.py
|
|
24
25
|
tests/test_clos/test_create_cromwell_header.py
|
|
25
26
|
tests/test_clos/test_cromwell_switch.py
|
|
26
27
|
tests/test_clos/test_detect_workflow.py
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Pytest added for function abort_job"""
|
|
2
|
+
import json
|
|
3
|
+
import mock
|
|
4
|
+
import pytest
|
|
5
|
+
import requests
|
|
6
|
+
import responses
|
|
7
|
+
from cloudos_cli.clos import Cloudos
|
|
8
|
+
from cloudos_cli.utils.errors import BadRequestException
|
|
9
|
+
from tests.functions_for_pytest import load_json_file
|
|
10
|
+
|
|
11
|
+
APIKEY = 'vnoiweur89u2ongs'
|
|
12
|
+
CLOUDOS_URL = 'http://cloudos.lifebit.ai'
|
|
13
|
+
WORKSPACE_ID = 'lv89ufc838sdig'
|
|
14
|
+
JOB_ID = "616ee9681b866a01d69fa1cd"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@mock.patch('cloudos_cli.clos', mock.MagicMock())
|
|
18
|
+
@responses.activate
|
|
19
|
+
def test_abort_job_correct_response():
|
|
20
|
+
"""
|
|
21
|
+
Test 'abort_job' to work as intended
|
|
22
|
+
API request is mocked and replicated with json files
|
|
23
|
+
"""
|
|
24
|
+
header = {
|
|
25
|
+
"Content-type": "application/json",
|
|
26
|
+
"apikey": APIKEY
|
|
27
|
+
}
|
|
28
|
+
# mock GET method with the .json
|
|
29
|
+
responses.add(
|
|
30
|
+
responses.PUT,
|
|
31
|
+
url=f"{CLOUDOS_URL}/api/v1/jobs/{JOB_ID}/abort?teamId={WORKSPACE_ID}",
|
|
32
|
+
headers=header,
|
|
33
|
+
status=200)
|
|
34
|
+
# start cloudOS service
|
|
35
|
+
clos = Cloudos(apikey=APIKEY, cromwell_token=None, cloudos_url=CLOUDOS_URL)
|
|
36
|
+
# get mock response
|
|
37
|
+
response = clos.abort_job(JOB_ID, WORKSPACE_ID)
|
|
38
|
+
assert response.status_code == 200
|
|
39
|
+
assert isinstance(response, requests.models.Response)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@mock.patch('cloudos_cli.clos', mock.MagicMock())
|
|
43
|
+
@responses.activate
|
|
44
|
+
def test_abort_job_incorrect_response():
|
|
45
|
+
"""
|
|
46
|
+
Test 'abort_job' to fail with '400' response
|
|
47
|
+
"""
|
|
48
|
+
# prepare error message
|
|
49
|
+
error_message = {"statusCode": 400, "code": "BadRequest",
|
|
50
|
+
"message": "Bad Request.", "time": "2025-04-25_17:31:07"}
|
|
51
|
+
error_json = json.dumps(error_message)
|
|
52
|
+
header = {
|
|
53
|
+
"Content-type": "application/json",
|
|
54
|
+
"apikey": APIKEY
|
|
55
|
+
}
|
|
56
|
+
# mock GET method with the .json
|
|
57
|
+
responses.add(
|
|
58
|
+
responses.PUT,
|
|
59
|
+
url=f"{CLOUDOS_URL}/api/v1/jobs/{JOB_ID}/abort?teamId={WORKSPACE_ID}",
|
|
60
|
+
body=error_json,
|
|
61
|
+
headers=header,
|
|
62
|
+
status=400)
|
|
63
|
+
# raise 400 error
|
|
64
|
+
with pytest.raises(BadRequestException) as error:
|
|
65
|
+
# check if it failed
|
|
66
|
+
clos = Cloudos(apikey=APIKEY, cromwell_token=None, cloudos_url=CLOUDOS_URL)
|
|
67
|
+
clos.abort_job(JOB_ID, WORKSPACE_ID)
|
|
68
|
+
assert "Bad Request" in (str(error))
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '2.19.0'
|
|
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
|
|
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
|