qmenta-sdk-lib 2.0.1.dev3463__tar.gz → 2.0.1.dev3465__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.
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/PKG-INFO +1 -1
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/pyproject.toml +1 -1
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/bids/wrapper.py +38 -11
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/client.py +18 -5
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/communication.py +29 -6
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/context.py +505 -132
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/executor.py +26 -8
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/init.py +36 -7
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/local/client.py +6 -2
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/local/context.py +131 -32
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/local/executor.py +33 -8
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/local/parse_settings.py +26 -6
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/make_entrypoint.py +6 -1
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/context.py +19 -11
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/file_filter.py +18 -5
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/inputs.py +69 -40
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/integration_ui.py +119 -34
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/integration_workflow_ui.py +87 -25
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/launch_gui.py +37 -10
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/make_files.py +10 -2
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/outputs.py +64 -48
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/run_test_docker.py +45 -20
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/tool_maker.py +156 -40
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/__init__.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/__init__.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/bids/__init__.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/bids/make_entrypoint.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/directory_utils.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/local/__init__.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/log_capture.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/__init__.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/modalities.py +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/templates_tool_maker/Dockerfile_schema +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/templates_tool_maker/description_schema +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/templates_tool_maker/qmenta.png +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/templates_tool_maker/test_tool_schema +0 -0
- {qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/tool_maker/templates_tool_maker/tool_schema +0 -0
{qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/bids/wrapper.py
RENAMED
|
@@ -70,7 +70,10 @@ def generate_file_path(original_name, sub_name, modality_name, cat_dir):
|
|
|
70
70
|
|
|
71
71
|
# Automatically generate a BIDS compatible name for the file
|
|
72
72
|
extension = "." + ".".join(original_name.split(".")[1:])
|
|
73
|
-
if extension in [
|
|
73
|
+
if extension in [
|
|
74
|
+
".bval",
|
|
75
|
+
".bvec",
|
|
76
|
+
]: # In BIDS, bval and bvec use dwi as modality
|
|
74
77
|
target_name = "{}_dwi{}".format(sub_name, extension)
|
|
75
78
|
else:
|
|
76
79
|
target_name = "{}_{}{}".format(sub_name, modality_name, extension)
|
|
@@ -130,22 +133,31 @@ def format_input_data(context, subject, session, path):
|
|
|
130
133
|
for category in list(bids_ff_names.keys()):
|
|
131
134
|
for modality_name in bids_ff_names[category]:
|
|
132
135
|
try:
|
|
133
|
-
file_handlers = context.get_files(
|
|
136
|
+
file_handlers = context.get_files(
|
|
137
|
+
"input",
|
|
138
|
+
file_filter_condition_name="c_{}".format(modality_name),
|
|
139
|
+
)
|
|
134
140
|
except: # noqa: E731,E123,E722
|
|
135
141
|
continue
|
|
136
142
|
|
|
137
143
|
for fh in file_handlers:
|
|
138
144
|
|
|
139
145
|
# NIFTI IS A MUST FOR BIDS
|
|
140
|
-
if any(
|
|
146
|
+
if any(
|
|
147
|
+
[fh.name.endswith(ext) for ext in supported_extensions]
|
|
148
|
+
):
|
|
141
149
|
cat_dir = os.path.join(sub_path, category)
|
|
142
150
|
mkdirs(cat_dir)
|
|
143
151
|
|
|
144
|
-
target_path = generate_file_path(
|
|
152
|
+
target_path = generate_file_path(
|
|
153
|
+
fh.name, subject, modality_name, cat_dir
|
|
154
|
+
)
|
|
145
155
|
|
|
146
156
|
if os.path.isfile(target_path):
|
|
147
157
|
logger.warning(
|
|
148
|
-
"Multiple files with same name ({}). Only the first will be used".format(
|
|
158
|
+
"Multiple files with same name ({}). Only the first will be used".format(
|
|
159
|
+
target_path
|
|
160
|
+
)
|
|
149
161
|
)
|
|
150
162
|
break
|
|
151
163
|
|
|
@@ -156,12 +168,20 @@ def format_input_data(context, subject, session, path):
|
|
|
156
168
|
|
|
157
169
|
metadata = fh.get_file_info()
|
|
158
170
|
if metadata:
|
|
159
|
-
metadata_target_name = "{}_{}{}".format(
|
|
160
|
-
|
|
171
|
+
metadata_target_name = "{}_{}{}".format(
|
|
172
|
+
sub_name, modality_name, ".json"
|
|
173
|
+
)
|
|
174
|
+
metadata_target_path = os.path.join(
|
|
175
|
+
cat_dir, metadata_target_name
|
|
176
|
+
)
|
|
161
177
|
with open(metadata_target_path, "w") as fp:
|
|
162
178
|
json.dump(metadata, fp)
|
|
163
179
|
else:
|
|
164
|
-
logger.warning(
|
|
180
|
+
logger.warning(
|
|
181
|
+
"File {} extension not supported ({})".format(
|
|
182
|
+
fh.name, supported_extensions
|
|
183
|
+
)
|
|
184
|
+
)
|
|
165
185
|
|
|
166
186
|
|
|
167
187
|
def format_settings(settings):
|
|
@@ -193,7 +213,10 @@ def run(context):
|
|
|
193
213
|
|
|
194
214
|
# Download data from the platform and store following the BIDS specification
|
|
195
215
|
format_input_data(
|
|
196
|
-
context,
|
|
216
|
+
context,
|
|
217
|
+
subject=analysis_data["patient_secret_name"],
|
|
218
|
+
session=analysis_data["ssid"],
|
|
219
|
+
path=input_path,
|
|
197
220
|
)
|
|
198
221
|
|
|
199
222
|
# Select type of analysis (TODO: add support for group analysis)
|
|
@@ -204,14 +227,18 @@ def run(context):
|
|
|
204
227
|
|
|
205
228
|
# Run the original BIDS-APP entrypoint
|
|
206
229
|
app_path = os.environ["BIDS_APP_ENTRYPOINT"]
|
|
207
|
-
context.set_progress(
|
|
230
|
+
context.set_progress(
|
|
231
|
+
message="Running {}".format(os.path.basename(app_path))
|
|
232
|
+
)
|
|
208
233
|
try:
|
|
209
234
|
args = [app_path, input_path, output_path, analysis_type] + options
|
|
210
235
|
logger.info("Calling: {}".format(" ".join(args)))
|
|
211
236
|
ret = check_output(args, stderr=STDOUT)
|
|
212
237
|
logger.info(ret)
|
|
213
238
|
except CalledProcessError as e:
|
|
214
|
-
raise RuntimeError(
|
|
239
|
+
raise RuntimeError(
|
|
240
|
+
"Program exited with error: {}\nOutput:\n{}".format(e, e.output)
|
|
241
|
+
)
|
|
215
242
|
except Exception:
|
|
216
243
|
raise
|
|
217
244
|
|
|
@@ -73,11 +73,22 @@ class ExecClient(object):
|
|
|
73
73
|
One of AnalysisState.RUNNING, AnalysisState.COMPLETED, AnalysisState.EXCEPTION or AnalysisState.NO_FILES
|
|
74
74
|
kwargs : dict
|
|
75
75
|
"""
|
|
76
|
-
assert isinstance(
|
|
77
|
-
|
|
76
|
+
assert isinstance(
|
|
77
|
+
state, AnalysisState
|
|
78
|
+
), "'state' is {}, not an 'AnalysisState'".format(state)
|
|
79
|
+
data_to_send = {
|
|
80
|
+
"analysis_id": self.__analysis_id,
|
|
81
|
+
"state": state.value,
|
|
82
|
+
}
|
|
78
83
|
data_to_send.update(kwargs)
|
|
79
|
-
logging.getLogger(__name__).info(
|
|
80
|
-
|
|
84
|
+
logging.getLogger(__name__).info(
|
|
85
|
+
"State = {state!r} for analysis {analysis_id}".format(
|
|
86
|
+
**data_to_send
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
self.__comm.send_request(
|
|
90
|
+
"analysis_manager/set_analysis_state", data_to_send
|
|
91
|
+
)
|
|
81
92
|
|
|
82
93
|
def upload_log(self):
|
|
83
94
|
|
|
@@ -92,7 +103,9 @@ class ExecClient(object):
|
|
|
92
103
|
# Send file in one single request
|
|
93
104
|
# FIXME Implement chuncked upload
|
|
94
105
|
self.__comm.send_files(
|
|
95
|
-
"analysis_manager/upload_log",
|
|
106
|
+
"analysis_manager/upload_log",
|
|
107
|
+
files={"file": ("exec.log", log_contents)},
|
|
108
|
+
req_data=data_to_send,
|
|
96
109
|
)
|
|
97
110
|
|
|
98
111
|
|
{qmenta_sdk_lib-2.0.1.dev3463 → qmenta_sdk_lib-2.0.1.dev3465}/python/qmenta/sdk/communication.py
RENAMED
|
@@ -11,7 +11,16 @@ except ImportError:
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class CommunicationObject(object):
|
|
14
|
-
def __init__(
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
url,
|
|
17
|
+
project_id,
|
|
18
|
+
token,
|
|
19
|
+
timeout=900.0,
|
|
20
|
+
chunk_size=256,
|
|
21
|
+
verify=True,
|
|
22
|
+
critical=False,
|
|
23
|
+
):
|
|
15
24
|
"""
|
|
16
25
|
Communications with the platform
|
|
17
26
|
|
|
@@ -112,7 +121,9 @@ class CommunicationObject(object):
|
|
|
112
121
|
|
|
113
122
|
if access_point:
|
|
114
123
|
# Add authentication for the platform
|
|
115
|
-
req_headers["Cookie"] = "AUTH_COOKIE={}; MINT_AP={}".format(
|
|
124
|
+
req_headers["Cookie"] = "AUTH_COOKIE={}; MINT_AP={}".format(
|
|
125
|
+
self.__token, self.__project_id
|
|
126
|
+
)
|
|
116
127
|
req_headers["Mint-Api-Call"] = "1"
|
|
117
128
|
url = urlparse.urljoin(self.__req_url, access_point)
|
|
118
129
|
|
|
@@ -132,10 +143,16 @@ class CommunicationObject(object):
|
|
|
132
143
|
|
|
133
144
|
# log & raise error if we get a HTTP error code
|
|
134
145
|
if not response.ok:
|
|
135
|
-
logger.debug(
|
|
146
|
+
logger.debug(
|
|
147
|
+
"{!r} HTTP response: {!r}".format(url, response.text)
|
|
148
|
+
)
|
|
136
149
|
response.raise_for_status()
|
|
137
150
|
|
|
138
|
-
except (
|
|
151
|
+
except (
|
|
152
|
+
requests.HTTPError,
|
|
153
|
+
requests.Timeout,
|
|
154
|
+
requests.ConnectionError,
|
|
155
|
+
):
|
|
139
156
|
retry_counter += 1
|
|
140
157
|
if self.__critical or total_retry == retry_counter:
|
|
141
158
|
raise
|
|
@@ -198,7 +215,9 @@ class CommunicationObject(object):
|
|
|
198
215
|
timeout = timeout or self.timeout
|
|
199
216
|
|
|
200
217
|
# Add authentication for the platform
|
|
201
|
-
req_headers["Cookie"] = "AUTH_COOKIE={}; MINT_AP={}".format(
|
|
218
|
+
req_headers["Cookie"] = "AUTH_COOKIE={}; MINT_AP={}".format(
|
|
219
|
+
self.__token, self.__project_id
|
|
220
|
+
)
|
|
202
221
|
req_headers["Mint-Api-Call"] = "1"
|
|
203
222
|
|
|
204
223
|
retry_counter = 0
|
|
@@ -222,7 +241,11 @@ class CommunicationObject(object):
|
|
|
222
241
|
logger.info("{!r} HTTP response: {!r}".format(url, result))
|
|
223
242
|
return result
|
|
224
243
|
|
|
225
|
-
except (
|
|
244
|
+
except (
|
|
245
|
+
requests.HTTPError,
|
|
246
|
+
requests.Timeout,
|
|
247
|
+
requests.ConnectionError,
|
|
248
|
+
):
|
|
226
249
|
retry_counter += 1
|
|
227
250
|
if self.__critical or total_retry == retry_counter:
|
|
228
251
|
raise
|