qmenta-client 2.1.dev1515__py3-none-any.whl → 2.1.dev1517__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.
- qmenta/client/Project.py +57 -67
- {qmenta_client-2.1.dev1515.dist-info → qmenta_client-2.1.dev1517.dist-info}/METADATA +1 -1
- {qmenta_client-2.1.dev1515.dist-info → qmenta_client-2.1.dev1517.dist-info}/RECORD +4 -4
- {qmenta_client-2.1.dev1515.dist-info → qmenta_client-2.1.dev1517.dist-info}/WHEEL +0 -0
qmenta/client/Project.py
CHANGED
|
@@ -257,20 +257,20 @@ class Project:
|
|
|
257
257
|
|
|
258
258
|
def upload_file(
|
|
259
259
|
self,
|
|
260
|
-
file_path,
|
|
261
|
-
subject_name,
|
|
262
|
-
ssid="",
|
|
263
|
-
date_of_scan="",
|
|
264
|
-
description="",
|
|
265
|
-
result=False,
|
|
266
|
-
name="",
|
|
267
|
-
input_data_type="
|
|
268
|
-
add_to_container_id=0,
|
|
269
|
-
chunk_size=2**24, # Optimized for GCS Bucket Storage
|
|
270
|
-
max_retries=5,
|
|
271
|
-
split_data=False,
|
|
272
|
-
mock_response=None,
|
|
273
|
-
):
|
|
260
|
+
file_path: str,
|
|
261
|
+
subject_name: str,
|
|
262
|
+
ssid: str = "",
|
|
263
|
+
date_of_scan: str = "",
|
|
264
|
+
description: str = "",
|
|
265
|
+
result: bool = False,
|
|
266
|
+
name: str = "",
|
|
267
|
+
input_data_type: str = "",
|
|
268
|
+
add_to_container_id: int = 0,
|
|
269
|
+
chunk_size: int = 2**24, # Optimized for GCS Bucket Storage
|
|
270
|
+
max_retries: int = 5,
|
|
271
|
+
split_data: bool = False,
|
|
272
|
+
mock_response: Any = None,
|
|
273
|
+
) -> bool:
|
|
274
274
|
"""
|
|
275
275
|
Upload a ZIP file to the platform.
|
|
276
276
|
|
|
@@ -291,7 +291,8 @@ class Project:
|
|
|
291
291
|
name : str
|
|
292
292
|
Name of the file in the platform
|
|
293
293
|
input_data_type : str
|
|
294
|
-
|
|
294
|
+
upload tool to be used, default is empty which means the Platform
|
|
295
|
+
will decide.
|
|
295
296
|
add_to_container_id : int
|
|
296
297
|
ID of the container to which this file should be added (if id > 0)
|
|
297
298
|
chunk_size : int
|
|
@@ -459,7 +460,7 @@ class Project:
|
|
|
459
460
|
"The name of the file to download (file_name) should be of "
|
|
460
461
|
"type string."
|
|
461
462
|
)
|
|
462
|
-
if not isinstance(local_filename, str):
|
|
463
|
+
if local_filename is not None and not isinstance(local_filename, str):
|
|
463
464
|
raise ValueError(
|
|
464
465
|
"The name of the output file (local_filename) should be of "
|
|
465
466
|
"type string."
|
|
@@ -485,7 +486,6 @@ class Project:
|
|
|
485
486
|
data=params,
|
|
486
487
|
stream=True,
|
|
487
488
|
) as response, open(local_filename, "wb") as f:
|
|
488
|
-
|
|
489
489
|
for chunk in response.iter_content(chunk_size=2**9 * 1024):
|
|
490
490
|
f.write(chunk)
|
|
491
491
|
f.flush()
|
|
@@ -535,7 +535,7 @@ class Project:
|
|
|
535
535
|
|
|
536
536
|
if files_not_in_container:
|
|
537
537
|
msg = (
|
|
538
|
-
|
|
538
|
+
"The following files are missing in container "
|
|
539
539
|
f"{container_id}: {', '.join(files_not_in_container)}"
|
|
540
540
|
)
|
|
541
541
|
raise Exception(msg)
|
|
@@ -551,7 +551,6 @@ class Project:
|
|
|
551
551
|
data=params,
|
|
552
552
|
stream=True,
|
|
553
553
|
) as response, open(zip_name, "wb") as f:
|
|
554
|
-
|
|
555
554
|
for chunk in response.iter_content(chunk_size=2**9 * 1024):
|
|
556
555
|
f.write(chunk)
|
|
557
556
|
f.flush()
|
|
@@ -874,19 +873,17 @@ class Project:
|
|
|
874
873
|
if len(items) != 2:
|
|
875
874
|
raise ValueError(
|
|
876
875
|
f"The number of elements in items '{len(items)}' "
|
|
877
|
-
|
|
876
|
+
"should be equal to two."
|
|
878
877
|
)
|
|
879
878
|
|
|
880
879
|
if not all([isinstance(item, int) for item in items]):
|
|
881
|
-
raise ValueError(
|
|
882
|
-
f"All values in items " f"'{items}' must be integers"
|
|
883
|
-
)
|
|
880
|
+
raise ValueError(f"All values in items '{items}' must be integers")
|
|
884
881
|
|
|
885
882
|
if search_criteria != {} and not all(
|
|
886
883
|
[item.startswith("pars_") for item in search_criteria.keys()]
|
|
887
884
|
):
|
|
888
885
|
raise ValueError(
|
|
889
|
-
|
|
886
|
+
"All keys of the search_criteria dictionary "
|
|
890
887
|
f"'{search_criteria.keys()}' must start with 'pars_'."
|
|
891
888
|
)
|
|
892
889
|
|
|
@@ -946,7 +943,7 @@ class Project:
|
|
|
946
943
|
except ValueError:
|
|
947
944
|
raise ValueError(
|
|
948
945
|
f"'patient_id': '{patient_id}' not valid. Must be convertible "
|
|
949
|
-
|
|
946
|
+
"to int."
|
|
950
947
|
)
|
|
951
948
|
|
|
952
949
|
if not isinstance(tags, list) or not all(
|
|
@@ -977,7 +974,7 @@ class Project:
|
|
|
977
974
|
if not (all(has_md_prefix) or not any(has_md_prefix)):
|
|
978
975
|
raise ValueError(
|
|
979
976
|
f"metadata: '{metadata}' must be a dictionary whose keys are "
|
|
980
|
-
|
|
977
|
+
"either all starting with 'md_' or none."
|
|
981
978
|
)
|
|
982
979
|
|
|
983
980
|
metadata_keys = []
|
|
@@ -1279,7 +1276,7 @@ class Project:
|
|
|
1279
1276
|
if not session_to_del:
|
|
1280
1277
|
logger.error(
|
|
1281
1278
|
f"Session {subject_name}/{session_id} could not be found in "
|
|
1282
|
-
|
|
1279
|
+
"this project."
|
|
1283
1280
|
)
|
|
1284
1281
|
return False
|
|
1285
1282
|
elif len(session_to_del) > 1:
|
|
@@ -1310,13 +1307,13 @@ class Project:
|
|
|
1310
1307
|
except errors.PlatformError:
|
|
1311
1308
|
logger.error(
|
|
1312
1309
|
f"Session \"{subject_name}/{session['ssid']}\" could "
|
|
1313
|
-
|
|
1310
|
+
"not be deleted."
|
|
1314
1311
|
)
|
|
1315
1312
|
return False
|
|
1316
1313
|
|
|
1317
1314
|
logger.info(
|
|
1318
1315
|
f"Session \"{subject_name}/{session['ssid']}\" successfully "
|
|
1319
|
-
|
|
1316
|
+
"deleted."
|
|
1320
1317
|
)
|
|
1321
1318
|
return True
|
|
1322
1319
|
|
|
@@ -1433,7 +1430,7 @@ class Project:
|
|
|
1433
1430
|
if len(items) != 2:
|
|
1434
1431
|
raise ValueError(
|
|
1435
1432
|
f"The number of elements in items '{len(items)}' "
|
|
1436
|
-
|
|
1433
|
+
"should be equal to two."
|
|
1437
1434
|
)
|
|
1438
1435
|
if not all(isinstance(item, int) for item in items):
|
|
1439
1436
|
raise ValueError(
|
|
@@ -1662,7 +1659,7 @@ class Project:
|
|
|
1662
1659
|
]
|
|
1663
1660
|
if any(excluded_bool):
|
|
1664
1661
|
raise Exception(
|
|
1665
|
-
|
|
1662
|
+
"p_n does not allow "
|
|
1666
1663
|
f"characters {ANALYSIS_NAME_EXCLUDED_CHARACTERS}"
|
|
1667
1664
|
)
|
|
1668
1665
|
else:
|
|
@@ -1740,7 +1737,7 @@ class Project:
|
|
|
1740
1737
|
if len(items) != 2:
|
|
1741
1738
|
raise ValueError(
|
|
1742
1739
|
f"The number of elements in items '{len(items)}' "
|
|
1743
|
-
|
|
1740
|
+
"should be equal to two."
|
|
1744
1741
|
)
|
|
1745
1742
|
if not all(isinstance(item, int) for item in items):
|
|
1746
1743
|
raise ValueError(
|
|
@@ -1764,20 +1761,16 @@ class Project:
|
|
|
1764
1761
|
for key in search_condition.keys():
|
|
1765
1762
|
if key not in search_keys.keys():
|
|
1766
1763
|
raise Exception(
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
f"condition"
|
|
1770
|
-
)
|
|
1764
|
+
f"This key '{key}' is not accepted by this search "
|
|
1765
|
+
"condition"
|
|
1771
1766
|
)
|
|
1772
1767
|
if (
|
|
1773
1768
|
not isinstance(search_condition[key], search_keys[key])
|
|
1774
1769
|
and search_condition[key] is not None
|
|
1775
1770
|
):
|
|
1776
1771
|
raise Exception(
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
f"{search_keys[key]}"
|
|
1780
|
-
)
|
|
1772
|
+
f"The key {key} in the search condition is not type "
|
|
1773
|
+
f"{search_keys[key]}"
|
|
1781
1774
|
)
|
|
1782
1775
|
if "p_n" == key:
|
|
1783
1776
|
excluded_bool = [
|
|
@@ -2013,7 +2006,7 @@ class Project:
|
|
|
2013
2006
|
|
|
2014
2007
|
if not res.ok:
|
|
2015
2008
|
logger.error(
|
|
2016
|
-
|
|
2009
|
+
"The log file could not be extracted for Analysis ID:"
|
|
2017
2010
|
f" {analysis_id}."
|
|
2018
2011
|
)
|
|
2019
2012
|
return False
|
|
@@ -2057,7 +2050,7 @@ class Project:
|
|
|
2057
2050
|
except ValueError:
|
|
2058
2051
|
raise ValueError(
|
|
2059
2052
|
f"analysis_id: '{analysis_id}' not valid. Must be convertible "
|
|
2060
|
-
|
|
2053
|
+
"to int."
|
|
2061
2054
|
)
|
|
2062
2055
|
|
|
2063
2056
|
try:
|
|
@@ -2075,7 +2068,7 @@ class Project:
|
|
|
2075
2068
|
)
|
|
2076
2069
|
except Exception:
|
|
2077
2070
|
logger.error(
|
|
2078
|
-
|
|
2071
|
+
"It was not possible to change the QC status of Analysis ID:"
|
|
2079
2072
|
f" {analysis_id}"
|
|
2080
2073
|
)
|
|
2081
2074
|
return False
|
|
@@ -2114,7 +2107,7 @@ class Project:
|
|
|
2114
2107
|
except ValueError:
|
|
2115
2108
|
raise ValueError(
|
|
2116
2109
|
f"'patient_id': '{patient_id}' not valid. Must be convertible"
|
|
2117
|
-
|
|
2110
|
+
" to int."
|
|
2118
2111
|
)
|
|
2119
2112
|
|
|
2120
2113
|
try:
|
|
@@ -2132,7 +2125,7 @@ class Project:
|
|
|
2132
2125
|
)
|
|
2133
2126
|
except Exception:
|
|
2134
2127
|
logger.error(
|
|
2135
|
-
|
|
2128
|
+
"It was not possible to change the QC status of Patient ID:"
|
|
2136
2129
|
f" {patient_id}"
|
|
2137
2130
|
)
|
|
2138
2131
|
return False
|
|
@@ -2166,14 +2159,14 @@ class Project:
|
|
|
2166
2159
|
except IndexError:
|
|
2167
2160
|
# Handle the case where no matching analysis is found
|
|
2168
2161
|
logging.error(
|
|
2169
|
-
|
|
2162
|
+
"No analysis was found with such Analysis ID: "
|
|
2170
2163
|
f"'{analysis_id}'."
|
|
2171
2164
|
)
|
|
2172
2165
|
return False, False
|
|
2173
2166
|
except Exception:
|
|
2174
2167
|
# Handle other potential exceptions
|
|
2175
2168
|
logging.error(
|
|
2176
|
-
|
|
2169
|
+
"It was not possible to extract the QC status from Analysis "
|
|
2177
2170
|
f"ID: {analysis_id}"
|
|
2178
2171
|
)
|
|
2179
2172
|
return False, False
|
|
@@ -2340,7 +2333,7 @@ class Project:
|
|
|
2340
2333
|
|
|
2341
2334
|
if "rules" not in res or project_has_no_rules:
|
|
2342
2335
|
logger.error(
|
|
2343
|
-
|
|
2336
|
+
"There was an error extracting the protocol adherence rules"
|
|
2344
2337
|
f" from {self._project_name}."
|
|
2345
2338
|
)
|
|
2346
2339
|
logger.error(platform.parse_response(res))
|
|
@@ -2355,7 +2348,7 @@ class Project:
|
|
|
2355
2348
|
json.dump(res["rules"], fr, indent=4)
|
|
2356
2349
|
except FileNotFoundError:
|
|
2357
2350
|
logger.error(
|
|
2358
|
-
|
|
2351
|
+
"Protocol adherence rules could not be exported to file: "
|
|
2359
2352
|
f"'{rules_file_path}'."
|
|
2360
2353
|
)
|
|
2361
2354
|
return False
|
|
@@ -2583,7 +2576,6 @@ class Project:
|
|
|
2583
2576
|
)
|
|
2584
2577
|
|
|
2585
2578
|
for qc_results in qc_results_list:
|
|
2586
|
-
|
|
2587
2579
|
# Count passed files distribution
|
|
2588
2580
|
for rule in qc_results["passed"]:
|
|
2589
2581
|
num_files = len(rule["files"])
|
|
@@ -2618,17 +2610,15 @@ class Project:
|
|
|
2618
2610
|
# Calculate condition failure percentages
|
|
2619
2611
|
for condition in stats["condition_failure_rates"]:
|
|
2620
2612
|
if total_failures > 0:
|
|
2621
|
-
stats["condition_failure_rates"][condition][
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
/ total_failures
|
|
2628
|
-
)
|
|
2629
|
-
* 100,
|
|
2630
|
-
2,
|
|
2613
|
+
stats["condition_failure_rates"][condition][
|
|
2614
|
+
"percentage"
|
|
2615
|
+
] = round(
|
|
2616
|
+
(
|
|
2617
|
+
stats["condition_failure_rates"][condition]["count"]
|
|
2618
|
+
/ total_failures
|
|
2631
2619
|
)
|
|
2620
|
+
* 100,
|
|
2621
|
+
2,
|
|
2632
2622
|
)
|
|
2633
2623
|
|
|
2634
2624
|
# Calculate rule success rates
|
|
@@ -2679,8 +2669,8 @@ class Project:
|
|
|
2679
2669
|
logger = logging.getLogger(logger_name)
|
|
2680
2670
|
if n_calls > call_limit:
|
|
2681
2671
|
logger.error(
|
|
2682
|
-
|
|
2683
|
-
|
|
2672
|
+
"__handle_start_analysis_response called itself more "
|
|
2673
|
+
f" than {n_calls} times: aborting."
|
|
2684
2674
|
)
|
|
2685
2675
|
return None
|
|
2686
2676
|
response = None
|
|
@@ -2706,7 +2696,7 @@ class Project:
|
|
|
2706
2696
|
"requirements and parameter ignore_file_selection==True."
|
|
2707
2697
|
)
|
|
2708
2698
|
logger.error(
|
|
2709
|
-
|
|
2699
|
+
"Unable to start the analysis: "
|
|
2710
2700
|
f"{post_data['script_name']}:"
|
|
2711
2701
|
f"{post_data['version']} with input "
|
|
2712
2702
|
f"{post_data['as_input']}."
|
|
@@ -2775,7 +2765,7 @@ class Project:
|
|
|
2775
2765
|
chosen_files = {}
|
|
2776
2766
|
for settings_key in choose_data.data_to_choose:
|
|
2777
2767
|
logger.warning(
|
|
2778
|
-
|
|
2768
|
+
"Type next the file/s for the input with ID: "
|
|
2779
2769
|
f"'{settings_key}'."
|
|
2780
2770
|
)
|
|
2781
2771
|
chosen_files[settings_key] = {}
|
|
@@ -2831,7 +2821,7 @@ class Project:
|
|
|
2831
2821
|
)
|
|
2832
2822
|
logger.error(
|
|
2833
2823
|
f"Selected: {len(names)} vs. "
|
|
2834
|
-
|
|
2824
|
+
"Number of files to select: "
|
|
2835
2825
|
f"{number_of_files_to_select}."
|
|
2836
2826
|
)
|
|
2837
2827
|
logger.error("Cancelling analysis.")
|
|
@@ -2840,7 +2830,7 @@ class Project:
|
|
|
2840
2830
|
elif any([name not in save_file_ids for name in names]):
|
|
2841
2831
|
logger.error(
|
|
2842
2832
|
f"Some selected file/s '{', '.join(names)}' "
|
|
2843
|
-
|
|
2833
|
+
"do not exist. Cancelling analysis..."
|
|
2844
2834
|
)
|
|
2845
2835
|
post_data["cancel"] = "1"
|
|
2846
2836
|
else:
|
|
@@ -2992,7 +2982,7 @@ class Project:
|
|
|
2992
2982
|
modalities = value.split(";")[1].split(",")
|
|
2993
2983
|
if len(modalities) != 1:
|
|
2994
2984
|
raise ValueError(
|
|
2995
|
-
|
|
2985
|
+
"A file can only have one modality. "
|
|
2996
2986
|
f"Provided Modalities: {', '.join(modalities)}."
|
|
2997
2987
|
)
|
|
2998
2988
|
modality = modalities[0]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
qmenta/__init__.py,sha256=ED6jHcYiuYpr_0vjGz0zx2lrrmJT9sDJCzIljoDfmlM,65
|
|
2
2
|
qmenta/client/Account.py,sha256=7oockGEJpbOfESCBXS4I5dWHP78CSJmW1c2F7abpwwY,9936
|
|
3
3
|
qmenta/client/File.py,sha256=kEa6-a6jRz9QGoC186Pu1t6Thn5_XZ1PGrp-zAt1V0M,5440
|
|
4
|
-
qmenta/client/Project.py,sha256=
|
|
4
|
+
qmenta/client/Project.py,sha256=XHuEiwJf870MJpD2T5LI7BzBbmEVo2Pyv0oM5xN6prE,108271
|
|
5
5
|
qmenta/client/Subject.py,sha256=madwhqFpz9su5OAynoLzIRQ6F1camzi6NOlbpWvs4Qk,8803
|
|
6
6
|
qmenta/client/__init__.py,sha256=Mtqe4zf8n3wuwMXSALENQgp5atQY5VcsyXWs2hjBs28,133
|
|
7
7
|
qmenta/client/utils.py,sha256=5DK2T_HQprrCwLS0Ycm2CjseaYmAUKaJkJvYoW-Rqzc,2479
|
|
8
|
-
qmenta_client-2.1.
|
|
9
|
-
qmenta_client-2.1.
|
|
10
|
-
qmenta_client-2.1.
|
|
8
|
+
qmenta_client-2.1.dev1517.dist-info/METADATA,sha256=NqTundGCqwD14HwrccyeoklgF4wAaaup04I8v3ioTnU,706
|
|
9
|
+
qmenta_client-2.1.dev1517.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
10
|
+
qmenta_client-2.1.dev1517.dist-info/RECORD,,
|
|
File without changes
|