miqatools 2.0.0rc0__py3-none-any.whl

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.
miqatools/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,180 @@
1
+ from ...utilities.miqa_client import api_get, api_post
2
+
3
+
4
+ def get_ds_ids_by_name(pipeline_id, **kwargs):
5
+ """
6
+ Gets a lookup of dataset names and corresponding IDs for a particular pipeline
7
+
8
+ :param pipeline_id: Miqa pipeline ID to get dataset info for
9
+ :return: A lookup of dataset information
10
+ :rtype: dict
11
+ """
12
+ info = get_ds_ids_by_name_internal(pipeline_id, **kwargs)
13
+ return info
14
+
15
+
16
+ def get_ds_ids_by_name_internal(pipeline_id, **kwargs):
17
+ endpoint = "get_ds_ids_by_name"
18
+ params = {"pipeline_id": pipeline_id}
19
+ return api_get(endpoint, params=params, **kwargs)
20
+
21
+
22
+ def tag_ds_ids_by_name(pipeline_id, name, tag, **kwargs):
23
+ """
24
+ Tags dataset(s) matching the name provided with the tag provided
25
+
26
+ :param pipeline_id: Miqa pipeline ID to get dataset info for
27
+ :param str name: Dataset name corresponding to the dataset to apply the tag to
28
+ :param str tag: Tag to use for the dataset
29
+ :return: Response from the API call
30
+ :rtype: object
31
+ """
32
+ info = get_ds_ids_by_name_internal(pipeline_id, **kwargs)
33
+ source_ids_lookup = info.get("data", {})
34
+
35
+ if source_ids_lookup and source_ids_lookup.get(name):
36
+ endpoint = f"/batch_tag_datasources/{tag}"
37
+ params = {"inline": 1, "source_ids": source_ids_lookup.get(name)}
38
+ return api_get(endpoint, params=params, **kwargs)
39
+ else:
40
+ raise Exception("No matching datasource IDs found")
41
+
42
+
43
+ def tag_ds_ids_by_names(pipeline_id, names, tag, raise_if_names_not_found=False, **kwargs):
44
+ """
45
+ Tags dataset(s) matching the names provided with the tag provided
46
+
47
+ :param pipeline_id: Miqa pipeline ID to get dataset info for
48
+ :param list name: Dataset name corresponding to the dataset to apply the tag to
49
+ :param str tag: Tag to use for the dataset
50
+ :param bool raise_if_names_not_found: Whether to raise an exception if no datasets are found
51
+ matching one of the provided names
52
+ :return: Response from the API call
53
+ :rtype: object
54
+ """
55
+ info = get_ds_ids_by_name_internal(pipeline_id, **kwargs)
56
+ source_ids_lookup = info.get("data", {})
57
+ source_ids_for_names = [source_ids_lookup.get(name) for name in names]
58
+ source_ids_for_names = [str(i) for i in source_ids_for_names if i]
59
+
60
+ if source_ids_for_names and (
61
+ not raise_if_names_not_found or len(source_ids_for_names) == len(names)
62
+ ):
63
+ tag_url = (
64
+ f"/batch_tag_datasources/{tag}"
65
+ f"?inline=1"
66
+ f"&source_ids={','.join(source_ids_for_names)}"
67
+ )
68
+ resp = api_get(tag_url, **kwargs)
69
+ return resp
70
+ else:
71
+ raise Exception("Matching datasource IDs not found")
72
+
73
+
74
+ def batch_create_datasets_and_tag_or_group(
75
+ org_id, pipeline_id, new_ds_names, tags, dsg_name=None, **kwargs
76
+ ):
77
+ """
78
+ Create stand-in datasets (i.e. no data upload) and tag them
79
+
80
+ :param int org_id: Miqa organization ID
81
+ :param int pipeline_id: Miqa pipeline ID to add the datasets to
82
+ :param list new_ds_names: Names for new datasets
83
+ :param list tags: Tags to use for the dataset
84
+ :param str dsg_name: Name to use to create a dataset group,
85
+ if wanting to create a group (Optional)
86
+ :return: Response from the API call
87
+ :rtype: Response
88
+ """
89
+ tag_url = (
90
+ f"/batch_create_dataset_and_tag"
91
+ f"?org_id={org_id}"
92
+ f"&pipeline_id={pipeline_id}"
93
+ f"&names={','.join(new_ds_names)}"
94
+ )
95
+
96
+ if tags:
97
+ tag_url += f"&tags={','.join(tags)}"
98
+ if dsg_name:
99
+ tag_url += f"&create_dsg={dsg_name}"
100
+
101
+ resp = api_get(tag_url, **kwargs)
102
+ return resp
103
+
104
+
105
+ def add_truths_to_dataset(dataset_id, pipeline_id, truth_file_path, **kwargs):
106
+ """
107
+ Create a single stand-in dataset (i.e. no data upload) and optionally tag it
108
+
109
+ :param int dataset_id: Miqa dataset ID to add the truths to
110
+ :param int pipeline_id: Miqa pipeline ID corresponding to the dataset and truth type
111
+ :param str truth_file_path: Filepath pointing to the truth TSV file. Should be a tab-delimited
112
+ file with columns and headers corresponding to your pipeline's truth type,
113
+ e.g. "chr pos ref alt"
114
+ """
115
+ upload_truths_url = (
116
+ f"/datasource/{dataset_id}/upload_truths" f"?pipeline_id={pipeline_id}" f"&inline=1"
117
+ )
118
+ response = api_post(
119
+ upload_truths_url, files={"file": open(truth_file_path, "rb")}, data={}, **kwargs
120
+ )
121
+ if response:
122
+ raise Exception(
123
+ f"Unable to add truths to dataset {dataset_id}: received an error response from the "
124
+ f"server at url {upload_truths_url}. Response: {response}"
125
+ )
126
+ return response
127
+
128
+
129
+ def create_dataset_with_name(org_id, pipeline_id, dataset_name, tags=None, **kwargs):
130
+ """
131
+ Create a single stand-in dataset (i.e. no data upload) and optionally tag it
132
+
133
+ :param int org_id: Miqa organization ID
134
+ :param int pipeline_id: Miqa pipeline ID to add the datasets to
135
+ :param str dataset_name: Name for new dataset
136
+ :param list tags: Tags to use for the dataset (optional)
137
+
138
+ :return: New Dataset ID
139
+ :rtype: int
140
+ """
141
+ create_ds_response = batch_create_datasets_and_tag_or_group(
142
+ org_id,
143
+ pipeline_id,
144
+ new_ds_names=[dataset_name],
145
+ tags=tags if tags else [],
146
+ **kwargs,
147
+ ) # Add tags if desired
148
+ if create_ds_response:
149
+ create_ds_response = create_ds_response.json()
150
+ ds_id_lookup = create_ds_response.get("data")
151
+ ds_id = ds_id_lookup.get(dataset_name)
152
+ return ds_id
153
+ else:
154
+ raise Exception(
155
+ f"Unable to create dataset with name '{dataset_name}': received an error response from "
156
+ f"the endpoint. Response: {create_ds_response}"
157
+ )
158
+
159
+
160
+ def create_dataset_and_add_truths(
161
+ org_id, pipeline_id, dataset_name, truth_file_path, tags=None, **kwargs
162
+ ):
163
+ """
164
+ Create a single stand-in dataset (i.e. no input file upload), add truth data,
165
+ and optionally tag it
166
+
167
+ :param int org_id: Miqa organization ID
168
+ :param int pipeline_id: Miqa pipeline ID corresponding to the dataset and truth type
169
+ :param str dataset_name: Name for new dataset
170
+ :param str truth_file_path: Filepath pointing to the truth TSV file. Should be a tab-delimited
171
+ file with columns and headers corresponding to your pipeline's truth type,
172
+ e.g. "chr pos ref alt"
173
+ :param list tags: Tags to use for the dataset (optional)
174
+
175
+ :return: New Dataset ID
176
+ :rtype: int
177
+ """
178
+ dataset_id = create_dataset_with_name(org_id, pipeline_id, dataset_name, tags=tags, **kwargs)
179
+ add_truths_to_dataset(dataset_id, pipeline_id, truth_file_path, **kwargs)
180
+ return dataset_id
File without changes
@@ -0,0 +1,230 @@
1
+ from ...datamanagement.datasethelpers import get_ds_ids_by_name
2
+ from ...utilities.miqa_client import api_get
3
+ from ..executionhelpers import complete_exec
4
+ from ..offlineexecution import upload_files_or_folder_for_exec
5
+ from ..triggertest_helpers import update_execution_start_time
6
+
7
+
8
+ def create_workflow_version(workflow_id, version_name, **kwargs):
9
+ """
10
+ Create a new manual-upload version for the specified workflow
11
+
12
+ :param int workflow_id: Miqa implemented workflow ID
13
+ :param str version_name: Name for new version
14
+ :param kwargs: Additional parameters including miqa_server and api_key
15
+
16
+ :return: New workflow version ID
17
+ :rtype: int
18
+ """
19
+ create_version_url = (
20
+ f"/api/create_uploadable_version" f"?pskel_id={workflow_id}" f"&version_name={version_name}"
21
+ )
22
+ headers = {"accept": "application/json"}
23
+ try:
24
+ create_version_response = api_get(create_version_url, headers=headers, **kwargs)
25
+ wfv_id = create_version_response.get("workflowversion_id")
26
+ return wfv_id
27
+ except Exception as e:
28
+ raise Exception(
29
+ f"Unable to create workflow version with name '{version_name}' for {workflow_id}: "
30
+ f"received an error response from the endpoint. Error: {e}"
31
+ )
32
+
33
+
34
+ def create_execution(workflowversion_id, dataset_id, org_config_id, **kwargs):
35
+ """
36
+ Create a new execution for the specified dataset on the specified workflow version
37
+
38
+ :param int workflowversion_id: Miqa workflow version ID
39
+ :param int dataset_id: Miqa dataset ID
40
+ :param int org_config_id: Miqa organization configuration ID
41
+ :param kwargs: Additional parameters including miqa_server and api_key
42
+
43
+ :return: New execution ID
44
+ :rtype: int
45
+ """
46
+ create_execution_url = (
47
+ f"/api/workflowversion/{workflowversion_id}/execute_on_dataset/{dataset_id}" # noqa
48
+ f"?org_config_id={org_config_id}"
49
+ )
50
+ headers = {"accept": "application/json"}
51
+ try:
52
+ create_execution_response = api_get(create_execution_url, headers=headers, **kwargs)
53
+ exec_id = create_execution_response.get("exec_id")
54
+ return exec_id
55
+ except Exception as e:
56
+ raise Exception(
57
+ f"Unable to create execution for {dataset_id} on {workflowversion_id}: "
58
+ f"received an error response from the endpoint. Error: {e}"
59
+ )
60
+
61
+
62
+ def create_and_upload_to_new_version_for_ds(
63
+ version_name,
64
+ dataset_name,
65
+ pipeline_id,
66
+ workflow_id,
67
+ org_config_id,
68
+ directory_containing_outputs,
69
+ raise_on_fail=False,
70
+ filepattern_end=None,
71
+ filepattern_start=None,
72
+ exclude_filepattern_end=None,
73
+ max_filesize=None,
74
+ max_connections=None,
75
+ filepatterns=None,
76
+ quiet=True,
77
+ per_request_timeout=None,
78
+ parallel_file_upload=True,
79
+ detailed_file_logs=False,
80
+ **kwargs,
81
+ ):
82
+ """
83
+ Create and execute a new version for an existing dataset, retrieved by name
84
+
85
+ :param str version_name: Name for new version
86
+ :param str dataset_name: Name for new dataset
87
+ :param int pipeline_id: Miqa pipeline ID to add the datasets to
88
+ :param int workflow_id: Miqa implemented workflow ID for the new version
89
+ :param int org_config_id: Miqa organization configuration ID
90
+ :param str directory_containing_outputs: Folder containing files to upload (Optional)
91
+ :param bool raise_on_fail: Whether to raise an exception if the file upload fails.
92
+ Default: False, the execution will be failed but an exception won't be raised (Optional)
93
+ :param str filepattern_end: Pattern to match in the file suffix, e.g. '.bam' (Optional)
94
+ :param str filepattern_start: Pattern to match in the file prefix, e.g. 'Analysis/' (Optional)
95
+ :param str exclude_filepattern_end:
96
+ Pattern to exclude in the file suffix, e.g. '.bam' (Optional)
97
+ :param int max_connections: Maximum number of connections for parallel upload (Optional)
98
+ :param int max_filesize: Max filesize to upload, i.e. if avoiding very large files (Optional)
99
+ :param filepatterns:
100
+ List of regex strings representing file patterns to match, e.g. ['*.csv','*.vcf'] (Optional)
101
+ :param bool quiet: Whether to skip logging. Default True. (Optional)
102
+ :param int per_request_timeout: Timeout for individual requests made during uploading.
103
+ Default None. (Optional)
104
+ :param int parallel_file_upload: Whether to allow uploads of each file to proceed in parallel.
105
+ Default True. (Optional)
106
+ :param bool detailed_file_logs: If not in quiet mode, whether to show detailed logs of each file
107
+ uploaded. Default False. (Optional)
108
+ :param kwargs: Additional parameters including miqa_server and api_key
109
+
110
+ """
111
+ exec_id = create_and_execute_for_new_version_for_ds(
112
+ version_name, dataset_name, pipeline_id, workflow_id, org_config_id, **kwargs
113
+ )
114
+ upload_and_complete_execution(
115
+ exec_id,
116
+ directory_containing_outputs,
117
+ raise_on_fail=raise_on_fail,
118
+ filepattern_end=filepattern_end,
119
+ filepattern_start=filepattern_start,
120
+ exclude_filepattern_end=exclude_filepattern_end,
121
+ max_filesize=max_filesize,
122
+ max_connections=max_connections,
123
+ filepatterns=filepatterns,
124
+ quiet=quiet,
125
+ per_request_timeout=per_request_timeout,
126
+ parallel_file_upload=parallel_file_upload,
127
+ detailed_file_logs=detailed_file_logs,
128
+ **kwargs,
129
+ )
130
+ return exec_id
131
+
132
+
133
+ def upload_and_complete_execution(
134
+ exec_id,
135
+ directory_containing_outputs,
136
+ raise_on_fail=False,
137
+ filepattern_end=None,
138
+ filepattern_start=None,
139
+ exclude_filepattern_end=None,
140
+ max_filesize=None,
141
+ max_connections=None,
142
+ filepatterns=None,
143
+ quiet=True,
144
+ per_request_timeout=None,
145
+ parallel_file_upload=True,
146
+ detailed_file_logs=False,
147
+ **kwargs,
148
+ ):
149
+ """
150
+ Uploads the test output files for each specified dataset, from the specified filepath to the
151
+ corresponding Miqa execution, and then marks that execution as complete.
152
+
153
+ :param int exec_id: Miqa execution ID
154
+ :param str directory_containing_outputs: Folder containing files to upload (Optional)
155
+ :param bool raise_on_fail: Whether to raise an exception if the file upload fails.
156
+ Default: False, the execution will be failed but an exception won't be raised (Optional)
157
+ :param str filepattern_end: Pattern to match in the file suffix, e.g. '.bam' (Optional)
158
+ :param str filepattern_start: Pattern to match in the file prefix, e.g. 'Analysis/' (Optional)
159
+ :param str exclude_filepattern_end:
160
+ Pattern to exclude in the file suffix, e.g. '.bam' (Optional)
161
+ :param int max_connections: Maximum number of connections for parallel upload (Optional)
162
+ :param int max_filesize: Max filesize to upload, i.e. if avoiding very large files (Optional)
163
+ :param filepatterns: List of regex strings representing file patterns to match,
164
+ e.g. ['*.csv','*.vcf'] (Optional)
165
+ :param bool quiet: Whether to skip logging. Default True. (Optional)
166
+ :param int per_request_timeout: Timeout for individual requests made during uploading.
167
+ Default None. (Optional)
168
+ :param int parallel_file_upload: Whether to allow uploads of each file to proceed in parallel.
169
+ Default True. (Optional)
170
+ :param bool detailed_file_logs: If not in quiet mode, whether to show detailed logs of each file
171
+ uploaded. Default False. (Optional)
172
+ :param kwargs: Additional parameters including miqa_server and api_key
173
+ """
174
+ update_execution_start_time(exec_id, quiet=quiet, **kwargs)
175
+ failed = False
176
+ try:
177
+ upload_files_or_folder_for_exec(
178
+ exec_id,
179
+ directory_containing_outputs,
180
+ args_files=None,
181
+ filepattern_end=filepattern_end,
182
+ filepattern_start=filepattern_start,
183
+ exclude_filepattern_end=exclude_filepattern_end,
184
+ max_filesize=max_filesize,
185
+ max_connections=max_connections,
186
+ filepatterns=filepatterns,
187
+ quiet=quiet,
188
+ per_request_timeout=per_request_timeout,
189
+ parallel_file_upload=parallel_file_upload,
190
+ detailed_file_logs=detailed_file_logs,
191
+ **kwargs,
192
+ )
193
+
194
+ except Exception as e2:
195
+ if raise_on_fail:
196
+ raise
197
+ failed = True
198
+ if not quiet:
199
+ print(
200
+ f"Failing execution {exec_id} due to unhandled exception (see below). Will mark "
201
+ "execution as failed and continue any remaining samples."
202
+ )
203
+ print(e2)
204
+ complete_exec(exec_id, quiet=quiet, failed=failed, **kwargs)
205
+ complete_exec(exec_id, quiet=quiet, failed=failed, **kwargs)
206
+
207
+
208
+ def create_and_execute_for_new_version_for_ds(
209
+ version_name, dataset_name, pipeline_id, workflow_id, org_config_id, **kwargs
210
+ ):
211
+ """
212
+ Create and execute a new version for an existing dataset, retrieved by name
213
+
214
+ :param str version_name: Name for new version
215
+ :param str dataset_name: Name for new dataset
216
+ :param int pipeline_id: Miqa pipeline ID to add the datasets to
217
+ :param int workflow_id: Miqa implemented workflow ID for the new version
218
+ :param int org_config_id: Miqa organization configuration ID
219
+ :param kwargs: Additional parameters including miqa_server and api_key
220
+ """
221
+ ds_ids_by_name = get_ds_ids_by_name(pipeline_id, **kwargs)
222
+ ds_id = ds_ids_by_name.get("data", {}).get(dataset_name)
223
+ if not ds_id:
224
+ raise Exception(
225
+ f"Could not find a dataset by the name '{dataset_name}' for the provided pipeline "
226
+ f"(id={pipeline_id}). Do you have a typo or the wrong pipeline?"
227
+ )
228
+ wfv_id = create_workflow_version(workflow_id, version_name, **kwargs)
229
+ exec_id = create_execution(wfv_id, ds_id, org_config_id, **kwargs)
230
+ return exec_id