fractal-server 2.0.6__py3-none-any.whl → 2.2.0__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.
- fractal_server/__init__.py +1 -1
- fractal_server/app/db/__init__.py +1 -1
- fractal_server/app/routes/admin/v1.py +2 -4
- fractal_server/app/routes/admin/v2.py +2 -4
- fractal_server/app/routes/api/v1/_aux_functions.py +24 -0
- fractal_server/app/routes/api/v1/job.py +3 -4
- fractal_server/app/routes/api/v1/project.py +28 -18
- fractal_server/app/routes/api/v2/_aux_functions.py +35 -12
- fractal_server/app/routes/api/v2/job.py +3 -4
- fractal_server/app/routes/api/v2/project.py +21 -0
- fractal_server/app/routes/api/v2/submit.py +36 -15
- fractal_server/app/routes/aux/_job.py +3 -1
- fractal_server/app/routes/aux/_runner.py +3 -3
- fractal_server/app/runner/executors/slurm/executor.py +169 -68
- fractal_server/app/runner/shutdown.py +88 -0
- fractal_server/app/runner/task_files.py +59 -27
- fractal_server/app/runner/v1/__init__.py +113 -64
- fractal_server/app/runner/v1/_common.py +53 -51
- fractal_server/app/runner/v1/_local/__init__.py +12 -11
- fractal_server/app/runner/v1/_local/_submit_setup.py +4 -4
- fractal_server/app/runner/v1/_slurm/__init__.py +16 -16
- fractal_server/app/runner/v1/_slurm/_submit_setup.py +11 -10
- fractal_server/app/runner/v1/_slurm/get_slurm_config.py +6 -6
- fractal_server/app/runner/v2/__init__.py +139 -60
- fractal_server/app/runner/v2/_local/__init__.py +12 -11
- fractal_server/app/runner/v2/_local/_local_config.py +1 -1
- fractal_server/app/runner/v2/_local/_submit_setup.py +4 -4
- fractal_server/app/runner/v2/_local_experimental/__init__.py +155 -0
- fractal_server/app/runner/v2/_local_experimental/_local_config.py +108 -0
- fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +42 -0
- fractal_server/app/runner/v2/_local_experimental/executor.py +156 -0
- fractal_server/app/runner/v2/_slurm/__init__.py +10 -10
- fractal_server/app/runner/v2/_slurm/_submit_setup.py +11 -10
- fractal_server/app/runner/v2/_slurm/get_slurm_config.py +6 -6
- fractal_server/app/runner/v2/runner.py +17 -15
- fractal_server/app/runner/v2/runner_functions.py +38 -38
- fractal_server/app/runner/v2/runner_functions_low_level.py +12 -6
- fractal_server/app/security/__init__.py +4 -5
- fractal_server/config.py +73 -19
- fractal_server/gunicorn_fractal.py +40 -0
- fractal_server/{logger/__init__.py → logger.py} +2 -2
- fractal_server/main.py +45 -26
- fractal_server/migrations/env.py +1 -1
- {fractal_server-2.0.6.dist-info → fractal_server-2.2.0.dist-info}/METADATA +4 -1
- {fractal_server-2.0.6.dist-info → fractal_server-2.2.0.dist-info}/RECORD +48 -43
- fractal_server/logger/gunicorn_logger.py +0 -19
- {fractal_server-2.0.6.dist-info → fractal_server-2.2.0.dist-info}/LICENSE +0 -0
- {fractal_server-2.0.6.dist-info → fractal_server-2.2.0.dist-info}/WHEEL +0 -0
- {fractal_server-2.0.6.dist-info → fractal_server-2.2.0.dist-info}/entry_points.txt +0 -0
@@ -36,8 +36,8 @@ from fractal_server.app.runner.task_files import get_task_file_paths
|
|
36
36
|
def no_op_submit_setup_call(
|
37
37
|
*,
|
38
38
|
wftask: WorkflowTask,
|
39
|
-
|
40
|
-
|
39
|
+
workflow_dir_local: Path,
|
40
|
+
workflow_dir_remote: Path,
|
41
41
|
) -> dict:
|
42
42
|
"""
|
43
43
|
Default (no-operation) interface of submit_setup_call.
|
@@ -113,8 +113,8 @@ def call_single_task(
|
|
113
113
|
*,
|
114
114
|
wftask: WorkflowTask,
|
115
115
|
task_pars: TaskParameters,
|
116
|
-
|
117
|
-
|
116
|
+
workflow_dir_local: Path,
|
117
|
+
workflow_dir_remote: Optional[Path] = None,
|
118
118
|
logger_name: Optional[str] = None,
|
119
119
|
) -> TaskParameters:
|
120
120
|
"""
|
@@ -133,8 +133,8 @@ def call_single_task(
|
|
133
133
|
|
134
134
|
If the executor then impersonates another user (as in the
|
135
135
|
`FractalSlurmExecutor`), this function is run by that user. For this
|
136
|
-
reason, it should not write any file to
|
137
|
-
permission errors.
|
136
|
+
reason, it should not write any file to `workflow_dir_local`, or it may
|
137
|
+
yield permission errors.
|
138
138
|
|
139
139
|
Args:
|
140
140
|
wftask:
|
@@ -143,12 +143,12 @@ def call_single_task(
|
|
143
143
|
task_pars:
|
144
144
|
The parameters required to run the task which are not specific to
|
145
145
|
the task, e.g., I/O paths.
|
146
|
-
|
146
|
+
workflow_dir_local:
|
147
147
|
The server-side working directory for workflow execution.
|
148
|
-
|
148
|
+
workflow_dir_remote:
|
149
149
|
The user-side working directory for workflow execution (only
|
150
150
|
relevant for multi-user executors). If `None`, it is set to be
|
151
|
-
equal to `
|
151
|
+
equal to `workflow_dir_remote`.
|
152
152
|
logger_name:
|
153
153
|
Name of the logger
|
154
154
|
|
@@ -164,18 +164,18 @@ def call_single_task(
|
|
164
164
|
information to the TaskExecutionError, such as task
|
165
165
|
order and name.
|
166
166
|
JobExecutionError: If the wrapped task raises a job-related error.
|
167
|
-
RuntimeError: If the `workflow_dir` is falsy.
|
168
167
|
"""
|
169
168
|
|
170
169
|
logger = get_logger(logger_name)
|
171
170
|
|
172
|
-
if not
|
173
|
-
|
171
|
+
if not workflow_dir_remote:
|
172
|
+
workflow_dir_remote = workflow_dir_local
|
174
173
|
|
175
174
|
task_files = get_task_file_paths(
|
176
|
-
|
177
|
-
|
175
|
+
workflow_dir_local=workflow_dir_local,
|
176
|
+
workflow_dir_remote=workflow_dir_remote,
|
178
177
|
task_order=wftask.order,
|
178
|
+
task_name=wftask.task.name,
|
179
179
|
)
|
180
180
|
|
181
181
|
# write args file (by assembling task_pars and wftask.args)
|
@@ -248,8 +248,8 @@ def call_single_parallel_task(
|
|
248
248
|
*,
|
249
249
|
wftask: WorkflowTask,
|
250
250
|
task_pars: TaskParameters,
|
251
|
-
|
252
|
-
|
251
|
+
workflow_dir_local: Path,
|
252
|
+
workflow_dir_remote: Optional[Path] = None,
|
253
253
|
) -> Any:
|
254
254
|
"""
|
255
255
|
Call a single instance of a parallel task
|
@@ -274,9 +274,9 @@ def call_single_parallel_task(
|
|
274
274
|
The task to execute.
|
275
275
|
task_pars:
|
276
276
|
The parameters to pass on to the task.
|
277
|
-
|
277
|
+
workflow_dir_local:
|
278
278
|
The server-side working directory for workflow execution.
|
279
|
-
|
279
|
+
workflow_dir_remote:
|
280
280
|
The user-side working directory for workflow execution (only
|
281
281
|
relevant for multi-user executors).
|
282
282
|
|
@@ -290,17 +290,18 @@ def call_single_parallel_task(
|
|
290
290
|
information to the TaskExecutionError, such as task
|
291
291
|
order and name.
|
292
292
|
JobExecutionError: If the wrapped task raises a job-related error.
|
293
|
-
RuntimeError: If the `
|
293
|
+
RuntimeError: If the `workflow_dir_local` is falsy.
|
294
294
|
"""
|
295
|
-
if not
|
295
|
+
if not workflow_dir_local:
|
296
296
|
raise RuntimeError
|
297
|
-
if not
|
298
|
-
|
297
|
+
if not workflow_dir_remote:
|
298
|
+
workflow_dir_remote = workflow_dir_local
|
299
299
|
|
300
300
|
task_files = get_task_file_paths(
|
301
|
-
|
302
|
-
|
301
|
+
workflow_dir_local=workflow_dir_local,
|
302
|
+
workflow_dir_remote=workflow_dir_remote,
|
303
303
|
task_order=wftask.order,
|
304
|
+
task_name=wftask.task.name,
|
304
305
|
component=component,
|
305
306
|
)
|
306
307
|
|
@@ -363,8 +364,8 @@ def call_parallel_task(
|
|
363
364
|
executor: Executor,
|
364
365
|
wftask: WorkflowTask,
|
365
366
|
task_pars_depend: TaskParameters,
|
366
|
-
|
367
|
-
|
367
|
+
workflow_dir_local: Path,
|
368
|
+
workflow_dir_remote: Optional[Path] = None,
|
368
369
|
submit_setup_call: Callable = no_op_submit_setup_call,
|
369
370
|
logger_name: Optional[str] = None,
|
370
371
|
) -> TaskParameters:
|
@@ -387,9 +388,9 @@ def call_parallel_task(
|
|
387
388
|
The parallel task to run.
|
388
389
|
task_pars_depend:
|
389
390
|
The task parameters to be passed on to the parallel task.
|
390
|
-
|
391
|
+
workflow_dir_local:
|
391
392
|
The server-side working directory for workflow execution.
|
392
|
-
|
393
|
+
workflow_dir_remote:
|
393
394
|
The user-side working directory for workflow execution (only
|
394
395
|
relevant for multi-user executors).
|
395
396
|
submit_setup_call:
|
@@ -405,8 +406,8 @@ def call_parallel_task(
|
|
405
406
|
"""
|
406
407
|
logger = get_logger(logger_name)
|
407
408
|
|
408
|
-
if not
|
409
|
-
|
409
|
+
if not workflow_dir_remote:
|
410
|
+
workflow_dir_remote = workflow_dir_local
|
410
411
|
|
411
412
|
try:
|
412
413
|
component_list = task_pars_depend.metadata[
|
@@ -424,8 +425,8 @@ def call_parallel_task(
|
|
424
425
|
try:
|
425
426
|
extra_setup = submit_setup_call(
|
426
427
|
wftask=wftask,
|
427
|
-
|
428
|
-
|
428
|
+
workflow_dir_local=workflow_dir_local,
|
429
|
+
workflow_dir_remote=workflow_dir_remote,
|
429
430
|
)
|
430
431
|
except Exception as e:
|
431
432
|
tb = "".join(traceback.format_tb(e.__traceback__))
|
@@ -443,8 +444,8 @@ def call_parallel_task(
|
|
443
444
|
call_single_parallel_task,
|
444
445
|
wftask=wftask,
|
445
446
|
task_pars=actual_task_pars_depend,
|
446
|
-
|
447
|
-
|
447
|
+
workflow_dir_local=workflow_dir_local,
|
448
|
+
workflow_dir_remote=workflow_dir_remote,
|
448
449
|
)
|
449
450
|
|
450
451
|
# Submit tasks for execution. Note that `for _ in map_iter:
|
@@ -511,16 +512,17 @@ def execute_tasks(
|
|
511
512
|
executor: Executor,
|
512
513
|
task_list: list[WorkflowTask],
|
513
514
|
task_pars: TaskParameters,
|
514
|
-
|
515
|
-
|
515
|
+
workflow_dir_local: Path,
|
516
|
+
workflow_dir_remote: Optional[Path] = None,
|
516
517
|
submit_setup_call: Callable = no_op_submit_setup_call,
|
517
518
|
logger_name: str,
|
518
519
|
) -> TaskParameters:
|
519
520
|
"""
|
520
521
|
Submit a list of WorkflowTasks for execution
|
521
522
|
|
522
|
-
**Note:** At the end of each task, write current metadata to
|
523
|
-
METADATA_FILENAME`, so that they can be read as part
|
523
|
+
**Note:** At the end of each task, write current metadata to
|
524
|
+
`workflow_dir_local / METADATA_FILENAME`, so that they can be read as part
|
525
|
+
of the [`get_job`
|
524
526
|
endpoint](../../api/v1/job/#fractal_server.app.routes.api.v1.job.get_job).
|
525
527
|
|
526
528
|
Arguments:
|
@@ -531,12 +533,12 @@ def execute_tasks(
|
|
531
533
|
The list of wftasks to be run
|
532
534
|
task_pars:
|
533
535
|
The task parameters to be passed on to the first task of the list.
|
534
|
-
|
536
|
+
workflow_dir_local:
|
535
537
|
The server-side working directory for workflow execution.
|
536
|
-
|
538
|
+
workflow_dir_remote:
|
537
539
|
The user-side working directory for workflow execution (only
|
538
540
|
relevant for multi-user executors). If `None`, it is set to be
|
539
|
-
equal to `
|
541
|
+
equal to `workflow_dir_local`.
|
540
542
|
submit_setup_call:
|
541
543
|
An optional function that computes configuration parameters for
|
542
544
|
the executor.
|
@@ -548,8 +550,8 @@ def execute_tasks(
|
|
548
550
|
A TaskParameters object which constitutes the output of the last
|
549
551
|
task in the list.
|
550
552
|
"""
|
551
|
-
if not
|
552
|
-
|
553
|
+
if not workflow_dir_remote:
|
554
|
+
workflow_dir_remote = workflow_dir_local
|
553
555
|
|
554
556
|
logger = get_logger(logger_name)
|
555
557
|
|
@@ -565,8 +567,8 @@ def execute_tasks(
|
|
565
567
|
executor=executor,
|
566
568
|
wftask=this_wftask,
|
567
569
|
task_pars_depend=current_task_pars,
|
568
|
-
|
569
|
-
|
570
|
+
workflow_dir_local=workflow_dir_local,
|
571
|
+
workflow_dir_remote=workflow_dir_remote,
|
570
572
|
submit_setup_call=submit_setup_call,
|
571
573
|
logger_name=logger_name,
|
572
574
|
)
|
@@ -575,8 +577,8 @@ def execute_tasks(
|
|
575
577
|
try:
|
576
578
|
extra_setup = submit_setup_call(
|
577
579
|
wftask=this_wftask,
|
578
|
-
|
579
|
-
|
580
|
+
workflow_dir_local=workflow_dir_local,
|
581
|
+
workflow_dir_remote=workflow_dir_remote,
|
580
582
|
)
|
581
583
|
except Exception as e:
|
582
584
|
tb = "".join(traceback.format_tb(e.__traceback__))
|
@@ -594,8 +596,8 @@ def execute_tasks(
|
|
594
596
|
call_single_task,
|
595
597
|
wftask=this_wftask,
|
596
598
|
task_pars=current_task_pars,
|
597
|
-
|
598
|
-
|
599
|
+
workflow_dir_local=workflow_dir_local,
|
600
|
+
workflow_dir_remote=workflow_dir_remote,
|
599
601
|
logger_name=logger_name,
|
600
602
|
**extra_setup,
|
601
603
|
)
|
@@ -607,11 +609,11 @@ def execute_tasks(
|
|
607
609
|
)
|
608
610
|
|
609
611
|
# Write most recent metadata to METADATA_FILENAME
|
610
|
-
with open(
|
612
|
+
with open(workflow_dir_local / METADATA_FILENAME, "w") as f:
|
611
613
|
json.dump(current_task_pars.metadata, f, indent=2)
|
612
614
|
|
613
615
|
# Write most recent metadata to HISTORY_FILENAME
|
614
|
-
with open(
|
616
|
+
with open(workflow_dir_local / HISTORY_FILENAME, "w") as f:
|
615
617
|
json.dump(current_task_pars.history, f, indent=2)
|
616
618
|
|
617
619
|
return current_task_pars
|
@@ -40,7 +40,7 @@ def _process_workflow(
|
|
40
40
|
input_metadata: dict[str, Any],
|
41
41
|
input_history: list[dict[str, Any]],
|
42
42
|
logger_name: str,
|
43
|
-
|
43
|
+
workflow_dir_local: Path,
|
44
44
|
first_task_index: int,
|
45
45
|
last_task_index: int,
|
46
46
|
) -> dict[str, Any]:
|
@@ -66,8 +66,8 @@ def _process_workflow(
|
|
66
66
|
metadata=input_metadata,
|
67
67
|
history=input_history,
|
68
68
|
),
|
69
|
-
|
70
|
-
|
69
|
+
workflow_dir_local=workflow_dir_local,
|
70
|
+
workflow_dir_remote=workflow_dir_local,
|
71
71
|
logger_name=logger_name,
|
72
72
|
submit_setup_call=_local_submit_setup,
|
73
73
|
)
|
@@ -85,8 +85,8 @@ async def process_workflow(
|
|
85
85
|
input_metadata: dict[str, Any],
|
86
86
|
input_history: list[dict[str, Any]],
|
87
87
|
logger_name: str,
|
88
|
-
|
89
|
-
|
88
|
+
workflow_dir_local: Path,
|
89
|
+
workflow_dir_remote: Optional[Path] = None,
|
90
90
|
slurm_user: Optional[str] = None,
|
91
91
|
slurm_account: Optional[str] = None,
|
92
92
|
user_cache_dir: Optional[str] = None,
|
@@ -115,12 +115,13 @@ async def process_workflow(
|
|
115
115
|
Initial metadata, passed to the first task
|
116
116
|
logger_name:
|
117
117
|
Name of the logger to log information on the run to
|
118
|
-
|
118
|
+
workflow_dir_local:
|
119
119
|
Working directory for this run.
|
120
|
-
|
120
|
+
workflow_dir_remote:
|
121
121
|
Working directory for this run, on the user side. This argument is
|
122
122
|
present for compatibility with the standard backend interface, but
|
123
|
-
for the `local` backend it cannot be different from
|
123
|
+
for the `local` backend it cannot be different from
|
124
|
+
`workflow_dir_local`.
|
124
125
|
slurm_user:
|
125
126
|
Username to impersonate to run the workflow. This argument is
|
126
127
|
present for compatibility with the standard backend interface, but
|
@@ -157,10 +158,10 @@ async def process_workflow(
|
|
157
158
|
of the workflow
|
158
159
|
"""
|
159
160
|
|
160
|
-
if
|
161
|
+
if workflow_dir_remote and (workflow_dir_remote != workflow_dir_local):
|
161
162
|
raise NotImplementedError(
|
162
163
|
"Local backend does not support different directories "
|
163
|
-
f"{
|
164
|
+
f"{workflow_dir_local=} and {workflow_dir_remote=}"
|
164
165
|
)
|
165
166
|
|
166
167
|
# Set values of first_task_index and last_task_index
|
@@ -178,7 +179,7 @@ async def process_workflow(
|
|
178
179
|
input_metadata=input_metadata,
|
179
180
|
input_history=input_history,
|
180
181
|
logger_name=logger_name,
|
181
|
-
|
182
|
+
workflow_dir_local=workflow_dir_local,
|
182
183
|
first_task_index=first_task_index,
|
183
184
|
last_task_index=last_task_index,
|
184
185
|
)
|
@@ -21,8 +21,8 @@ from ._local_config import get_local_backend_config
|
|
21
21
|
def _local_submit_setup(
|
22
22
|
*,
|
23
23
|
wftask: WorkflowTask,
|
24
|
-
|
25
|
-
|
24
|
+
workflow_dir_local: Optional[Path] = None,
|
25
|
+
workflow_dir_remote: Optional[Path] = None,
|
26
26
|
) -> dict[str, object]:
|
27
27
|
"""
|
28
28
|
Collect WorfklowTask-specific configuration parameters from different
|
@@ -31,9 +31,9 @@ def _local_submit_setup(
|
|
31
31
|
Arguments:
|
32
32
|
wftask:
|
33
33
|
WorkflowTask for which the configuration is to be assembled
|
34
|
-
|
34
|
+
workflow_dir_local:
|
35
35
|
Not used in this function.
|
36
|
-
|
36
|
+
workflow_dir_remote:
|
37
37
|
Not used in this function.
|
38
38
|
|
39
39
|
Returns:
|
@@ -50,8 +50,8 @@ def _process_workflow(
|
|
50
50
|
input_metadata: dict[str, Any],
|
51
51
|
input_history: list[dict[str, Any]],
|
52
52
|
logger_name: str,
|
53
|
-
|
54
|
-
|
53
|
+
workflow_dir_local: Path,
|
54
|
+
workflow_dir_remote: Path,
|
55
55
|
first_task_index: int,
|
56
56
|
last_task_index: int,
|
57
57
|
slurm_user: Optional[str] = None,
|
@@ -86,8 +86,8 @@ def _process_workflow(
|
|
86
86
|
keep_logs=True,
|
87
87
|
slurm_user=slurm_user,
|
88
88
|
user_cache_dir=user_cache_dir,
|
89
|
-
|
90
|
-
|
89
|
+
workflow_dir_local=workflow_dir_local,
|
90
|
+
workflow_dir_remote=workflow_dir_remote,
|
91
91
|
common_script_lines=worker_init,
|
92
92
|
slurm_account=slurm_account,
|
93
93
|
) as executor:
|
@@ -102,8 +102,8 @@ def _process_workflow(
|
|
102
102
|
metadata=input_metadata,
|
103
103
|
history=input_history,
|
104
104
|
),
|
105
|
-
|
106
|
-
|
105
|
+
workflow_dir_local=workflow_dir_local,
|
106
|
+
workflow_dir_remote=workflow_dir_remote,
|
107
107
|
submit_setup_call=_slurm_submit_setup,
|
108
108
|
logger_name=logger_name,
|
109
109
|
)
|
@@ -121,8 +121,8 @@ async def process_workflow(
|
|
121
121
|
input_metadata: dict[str, Any],
|
122
122
|
input_history: list[dict[str, Any]],
|
123
123
|
logger_name: str,
|
124
|
-
|
125
|
-
|
124
|
+
workflow_dir_local: Path,
|
125
|
+
workflow_dir_remote: Optional[Path] = None,
|
126
126
|
user_cache_dir: Optional[str] = None,
|
127
127
|
slurm_user: Optional[str] = None,
|
128
128
|
slurm_account: Optional[str] = None,
|
@@ -152,8 +152,8 @@ async def process_workflow(
|
|
152
152
|
input_metadata=input_metadata,
|
153
153
|
input_history=input_history,
|
154
154
|
logger_name=logger_name,
|
155
|
-
|
156
|
-
|
155
|
+
workflow_dir_local=workflow_dir_local,
|
156
|
+
workflow_dir_remote=workflow_dir_remote,
|
157
157
|
slurm_user=slurm_user,
|
158
158
|
slurm_account=slurm_account,
|
159
159
|
user_cache_dir=user_cache_dir,
|
@@ -166,8 +166,8 @@ async def process_workflow(
|
|
166
166
|
|
167
167
|
def get_slurm_config(
|
168
168
|
wftask: WorkflowTask,
|
169
|
-
|
170
|
-
|
169
|
+
workflow_dir_local: Path,
|
170
|
+
workflow_dir_remote: Path,
|
171
171
|
config_path: Optional[Path] = None,
|
172
172
|
) -> SlurmConfig:
|
173
173
|
"""
|
@@ -187,13 +187,13 @@ def get_slurm_config(
|
|
187
187
|
wftask:
|
188
188
|
WorkflowTask for which the SLURM configuration is is to be
|
189
189
|
prepared.
|
190
|
-
|
190
|
+
workflow_dir_local:
|
191
191
|
Server-owned directory to store all task-execution-related relevant
|
192
192
|
files (inputs, outputs, errors, and all meta files related to the
|
193
193
|
job execution). Note: users cannot write directly to this folder.
|
194
|
-
|
195
|
-
User-side directory with the same scope as `
|
196
|
-
where a user can write.
|
194
|
+
workflow_dir_remote:
|
195
|
+
User-side directory with the same scope as `workflow_dir_local`,
|
196
|
+
and where a user can write.
|
197
197
|
config_path:
|
198
198
|
Path of aFractal SLURM configuration file; if `None`, use
|
199
199
|
`FRACTAL_SLURM_CONFIG_FILE` variable from settings.
|
@@ -24,8 +24,8 @@ from fractal_server.app.models.v1 import WorkflowTask
|
|
24
24
|
def _slurm_submit_setup(
|
25
25
|
*,
|
26
26
|
wftask: WorkflowTask,
|
27
|
-
|
28
|
-
|
27
|
+
workflow_dir_local: Path,
|
28
|
+
workflow_dir_remote: Path,
|
29
29
|
) -> dict[str, object]:
|
30
30
|
"""
|
31
31
|
Collect WorfklowTask-specific configuration parameters from different
|
@@ -43,13 +43,13 @@ def _slurm_submit_setup(
|
|
43
43
|
Arguments:
|
44
44
|
wftask:
|
45
45
|
WorkflowTask for which the configuration is to be assembled
|
46
|
-
|
46
|
+
workflow_dir_local:
|
47
47
|
Server-owned directory to store all task-execution-related relevant
|
48
48
|
files (inputs, outputs, errors, and all meta files related to the
|
49
49
|
job execution). Note: users cannot write directly to this folder.
|
50
|
-
|
51
|
-
User-side directory with the same scope as `
|
52
|
-
where a user can write.
|
50
|
+
workflow_dir_remote:
|
51
|
+
User-side directory with the same scope as `workflow_dir_local`,
|
52
|
+
and where a user can write.
|
53
53
|
|
54
54
|
Returns:
|
55
55
|
submit_setup_dict:
|
@@ -61,15 +61,16 @@ def _slurm_submit_setup(
|
|
61
61
|
# Get SlurmConfig object
|
62
62
|
slurm_config = get_slurm_config(
|
63
63
|
wftask=wftask,
|
64
|
-
|
65
|
-
|
64
|
+
workflow_dir_local=workflow_dir_local,
|
65
|
+
workflow_dir_remote=workflow_dir_remote,
|
66
66
|
)
|
67
67
|
|
68
68
|
# Get TaskFiles object
|
69
69
|
task_files = get_task_file_paths(
|
70
|
-
|
71
|
-
|
70
|
+
workflow_dir_local=workflow_dir_local,
|
71
|
+
workflow_dir_remote=workflow_dir_remote,
|
72
72
|
task_order=wftask.order,
|
73
|
+
task_name=wftask.task.name,
|
73
74
|
)
|
74
75
|
|
75
76
|
# Prepare and return output dictionary
|
@@ -17,8 +17,8 @@ from fractal_server.app.runner.executors.slurm._slurm_config import (
|
|
17
17
|
|
18
18
|
def get_slurm_config(
|
19
19
|
wftask: WorkflowTask,
|
20
|
-
|
21
|
-
|
20
|
+
workflow_dir_local: Path,
|
21
|
+
workflow_dir_remote: Path,
|
22
22
|
config_path: Optional[Path] = None,
|
23
23
|
) -> SlurmConfig:
|
24
24
|
"""
|
@@ -38,13 +38,13 @@ def get_slurm_config(
|
|
38
38
|
wftask:
|
39
39
|
WorkflowTask for which the SLURM configuration is is to be
|
40
40
|
prepared.
|
41
|
-
|
41
|
+
workflow_dir_local:
|
42
42
|
Server-owned directory to store all task-execution-related relevant
|
43
43
|
files (inputs, outputs, errors, and all meta files related to the
|
44
44
|
job execution). Note: users cannot write directly to this folder.
|
45
|
-
|
46
|
-
User-side directory with the same scope as `
|
47
|
-
where a user can write.
|
45
|
+
workflow_dir_remote:
|
46
|
+
User-side directory with the same scope as `workflow_dir_local`,
|
47
|
+
and where a user can write.
|
48
48
|
config_path:
|
49
49
|
Path of aFractal SLURM configuration file; if `None`, use
|
50
50
|
`FRACTAL_SLURM_CONFIG_FILE` variable from settings.
|