cpg-utils 5.7.0__tar.gz → 5.7.2__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.
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/PKG-INFO +1 -1
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/config.py +15 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/cromwell.py +5 -24
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils.egg-info/PKG-INFO +1 -1
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/setup.py +1 -1
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/test/test_cromwell.py +1 -83
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/LICENSE +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/README.md +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/__init__.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/cloud.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/cloudpath_hail_az.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/constants.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/cromwell_model.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/dataproc.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/existence_checks.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/git.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/hail_batch.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/membership.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/metamist_registration.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/py.typed +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils/slack.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils.egg-info/SOURCES.txt +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils.egg-info/dependency_links.txt +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils.egg-info/requires.txt +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/cpg_utils.egg-info/top_level.txt +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/pyproject.toml +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/setup.cfg +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/test/__init__.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/test/test_config.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/test/test_doctests.py +0 -0
- {cpg_utils-5.7.0 → cpg_utils-5.7.2}/test/test_get_google_identity_token.py +0 -0
|
@@ -570,3 +570,18 @@ def get_gcloud_set_project(gcp_project: str | None = None) -> str:
|
|
|
570
570
|
gcp_project = gcp_project or get_gcp_project()
|
|
571
571
|
command = ['gcloud', 'config', 'set', 'project', gcp_project]
|
|
572
572
|
return ' '.join([quote(c) for c in command])
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
def dataset_for_access_level(dataset_name: str) -> str:
|
|
576
|
+
"""
|
|
577
|
+
Checks access_level in config, modifying dataset with "-test" suffix if appropriate.
|
|
578
|
+
|
|
579
|
+
>>> dataset_for_access_level('dataset') # with access_level != 'test'
|
|
580
|
+
'dataset'
|
|
581
|
+
>>> dataset_for_access_level('dataset') # with access_level == 'test'
|
|
582
|
+
'dataset-test'
|
|
583
|
+
"""
|
|
584
|
+
access_level = config_retrieve(['workflow', 'access_level'], 'standard')
|
|
585
|
+
if access_level == 'test' and not dataset_name.endswith('-test'):
|
|
586
|
+
return f'{dataset_name}-test'
|
|
587
|
+
return dataset_name
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Cromwell module contains helper code for submitting + watching
|
|
4
4
|
jobs from within Hail batch.
|
|
5
|
+
|
|
6
|
+
https://support.terra.bio/hc/en-us/articles/31190930435483-Cromwell-on-Google-Batch-API-released-May-19-Generally-Available-as-of-June-23
|
|
7
|
+
- As of June 23, 2025, Cromwell only allows users to run workflows on Google Batch API.
|
|
5
8
|
"""
|
|
6
9
|
|
|
7
10
|
import json
|
|
8
11
|
import os
|
|
9
12
|
import subprocess
|
|
10
|
-
from enum import Enum
|
|
11
13
|
from shlex import quote
|
|
12
14
|
from typing import Any
|
|
13
15
|
|
|
@@ -36,15 +38,6 @@ from cpg_utils.git import (
|
|
|
36
38
|
from cpg_utils.hail_batch import prepare_git_job, query_command
|
|
37
39
|
|
|
38
40
|
|
|
39
|
-
class CromwellBackend(Enum):
|
|
40
|
-
# the string value here, is the key of the backend in our cromwell.conf
|
|
41
|
-
batch = 'batch'
|
|
42
|
-
pipelines_api = 'papi'
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
DEFAULT_BACKEND = CromwellBackend.batch
|
|
46
|
-
|
|
47
|
-
|
|
48
41
|
class CromwellOutputType:
|
|
49
42
|
"""Declares output type for cromwell -> hail batch glue"""
|
|
50
43
|
|
|
@@ -164,7 +157,6 @@ def run_cromwell_workflow( # noqa: C901
|
|
|
164
157
|
project: str | None = None,
|
|
165
158
|
copy_outputs_to_gcp: bool = True,
|
|
166
159
|
ar_guid_override: str | None = None,
|
|
167
|
-
backend: CromwellBackend = DEFAULT_BACKEND,
|
|
168
160
|
):
|
|
169
161
|
"""
|
|
170
162
|
Run a cromwell workflow, and return a Batch.ResourceFile
|
|
@@ -229,26 +221,17 @@ def run_cromwell_workflow( # noqa: C901
|
|
|
229
221
|
)
|
|
230
222
|
|
|
231
223
|
workflow_options = {
|
|
232
|
-
|
|
233
|
-
'backend': backend.value,
|
|
224
|
+
'backend': 'batch',
|
|
234
225
|
# pass the user-service-account-json to cromwell to submit jobs as this user
|
|
235
226
|
'user_service_account_json': service_account_json,
|
|
236
227
|
'google_compute_service_account': service_account_email,
|
|
237
228
|
'google_project': _project,
|
|
238
|
-
# other config options that are useful
|
|
239
229
|
'google_labels': google_labels,
|
|
240
230
|
'final_call_logs_dir': logging_output_dir,
|
|
241
231
|
'final_workflow_log_dir': logging_output_dir,
|
|
232
|
+
'gcp_batch_gcs_root': intermediate_dir,
|
|
242
233
|
}
|
|
243
234
|
|
|
244
|
-
if backend == CromwellBackend.pipelines_api:
|
|
245
|
-
workflow_options['jes_gcs_root'] = intermediate_dir
|
|
246
|
-
|
|
247
|
-
if backend == CromwellBackend.batch:
|
|
248
|
-
# cromwell: /supportedBackends/google/batch/src/main/scala/cromwell/backend/google/batch/models/GcpBatchWorkflowPaths.scala#L20
|
|
249
|
-
# this was undocumented at the time of writing
|
|
250
|
-
workflow_options['gcp_batch_gcs_root'] = intermediate_dir
|
|
251
|
-
|
|
252
235
|
# if required, export the workflow outputs to GCS
|
|
253
236
|
if copy_outputs_to_gcp:
|
|
254
237
|
workflow_options['final_workflow_outputs_dir'] = workflow_output_dir
|
|
@@ -310,7 +293,6 @@ def run_cromwell_workflow_from_repo_and_get_outputs(
|
|
|
310
293
|
min_watch_poll_interval: int = 5,
|
|
311
294
|
max_watch_poll_interval: int = 60,
|
|
312
295
|
time_limit_seconds: int | None = None,
|
|
313
|
-
backend: CromwellBackend = DEFAULT_BACKEND,
|
|
314
296
|
) -> tuple[Job, dict[str, Resource | list[Resource]]]:
|
|
315
297
|
"""
|
|
316
298
|
This function needs to know the structure of the outputs you
|
|
@@ -363,7 +345,6 @@ def run_cromwell_workflow_from_repo_and_get_outputs(
|
|
|
363
345
|
labels=labels,
|
|
364
346
|
project=project,
|
|
365
347
|
copy_outputs_to_gcp=copy_outputs_to_gcp,
|
|
366
|
-
backend=backend,
|
|
367
348
|
)
|
|
368
349
|
|
|
369
350
|
outputs_dict = watch_workflow_and_get_output(
|
|
@@ -8,7 +8,7 @@ with open('README.md') as f:
|
|
|
8
8
|
setup(
|
|
9
9
|
name='cpg-utils',
|
|
10
10
|
# This tag is automatically updated by bumpversion
|
|
11
|
-
version='5.7.
|
|
11
|
+
version='5.7.2',
|
|
12
12
|
description='Library of convenience functions specific to the CPG',
|
|
13
13
|
long_description=long_description,
|
|
14
14
|
long_description_content_type='text/markdown',
|
|
@@ -2,93 +2,12 @@ import json
|
|
|
2
2
|
import unittest
|
|
3
3
|
from unittest.mock import MagicMock, patch
|
|
4
4
|
|
|
5
|
-
from cpg_utils.cromwell import
|
|
5
|
+
from cpg_utils.cromwell import run_cromwell_workflow
|
|
6
6
|
from cpg_utils.cromwell_model import WorkflowMetadataModel
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class TestCromwellWrapper(unittest.TestCase):
|
|
10
10
|
|
|
11
|
-
@patch('cpg_utils.config.get_config')
|
|
12
|
-
@patch('cpg_utils.cromwell.read_secret')
|
|
13
|
-
def test_workflow_options_papi(
|
|
14
|
-
self,
|
|
15
|
-
mock_read_secret: MagicMock,
|
|
16
|
-
mock_get_config: MagicMock,
|
|
17
|
-
):
|
|
18
|
-
"""
|
|
19
|
-
Test that the workflow options are generated correctly for the PAPI backend
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
mock_read_secret (MagicMock): _description_
|
|
23
|
-
mock_get_config (MagicMock): _description_
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
dataset = 'test-dataset'
|
|
27
|
-
dataset_buckets = {
|
|
28
|
-
'default': 'test://default-bucket',
|
|
29
|
-
'analysis': 'test://analysis-bucket',
|
|
30
|
-
'tmp': 'test://tmp-bucket',
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
mock_get_config.return_value = {
|
|
34
|
-
'workflow': {
|
|
35
|
-
'ar-guid': '<test-ar-guid>',
|
|
36
|
-
'access_level': 'test',
|
|
37
|
-
'dataset_gcp_project': 'test-gcp-project',
|
|
38
|
-
},
|
|
39
|
-
'storage': {
|
|
40
|
-
'default': dataset_buckets,
|
|
41
|
-
dataset: dataset_buckets,
|
|
42
|
-
},
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
mock_read_secret.return_value = '{"client_email": "<secret-client-email>"}'
|
|
46
|
-
|
|
47
|
-
job: MagicMock = MagicMock()
|
|
48
|
-
|
|
49
|
-
_ = run_cromwell_workflow(
|
|
50
|
-
job=job,
|
|
51
|
-
dataset=dataset,
|
|
52
|
-
access_level='test',
|
|
53
|
-
workflow='test-workflow',
|
|
54
|
-
cwd=None,
|
|
55
|
-
libs=[],
|
|
56
|
-
output_prefix='output-prefix',
|
|
57
|
-
backend=CromwellBackend.pipelines_api,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
mock_read_secret.assert_called_once_with(
|
|
61
|
-
'test-gcp-project',
|
|
62
|
-
f'{dataset}-cromwell-test-key',
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
# no inputs, hence there will only be one call to job.command
|
|
66
|
-
|
|
67
|
-
args, _ = job.command.call_args
|
|
68
|
-
command: str = args[0].strip()
|
|
69
|
-
|
|
70
|
-
# echo '{json.dumps(workflow_options)}' > workflow-options.json
|
|
71
|
-
wf_options_line = command.splitlines()[1]
|
|
72
|
-
wf_options_str = wf_options_line.split("'")[1]
|
|
73
|
-
wf_options = json.loads(wf_options_str)
|
|
74
|
-
|
|
75
|
-
self.assertEqual(
|
|
76
|
-
wf_options['jes_gcs_root'],
|
|
77
|
-
'test://tmp-bucket/cromwell',
|
|
78
|
-
)
|
|
79
|
-
self.assertEqual(
|
|
80
|
-
wf_options['final_call_logs_dir'],
|
|
81
|
-
'test://analysis-bucket/cromwell_logs/output-prefix',
|
|
82
|
-
)
|
|
83
|
-
self.assertEqual(
|
|
84
|
-
wf_options['final_workflow_log_dir'],
|
|
85
|
-
'test://analysis-bucket/cromwell_logs/output-prefix',
|
|
86
|
-
)
|
|
87
|
-
self.assertEqual(
|
|
88
|
-
wf_options['final_workflow_outputs_dir'],
|
|
89
|
-
'test://default-bucket/output-prefix',
|
|
90
|
-
)
|
|
91
|
-
|
|
92
11
|
@patch('cpg_utils.config.get_config')
|
|
93
12
|
@patch('cpg_utils.cromwell.read_secret')
|
|
94
13
|
def test_workflow_options_backend_batch(
|
|
@@ -135,7 +54,6 @@ class TestCromwellWrapper(unittest.TestCase):
|
|
|
135
54
|
cwd=None,
|
|
136
55
|
libs=[],
|
|
137
56
|
output_prefix='output-prefix',
|
|
138
|
-
backend=CromwellBackend.batch,
|
|
139
57
|
)
|
|
140
58
|
|
|
141
59
|
mock_read_secret.assert_called_once_with(
|
|
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
|