fractal-server 2.13.0__py3-none-any.whl → 2.14.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.
Files changed (127) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +3 -1
  3. fractal_server/app/models/linkusergroup.py +6 -2
  4. fractal_server/app/models/v2/__init__.py +11 -1
  5. fractal_server/app/models/v2/accounting.py +35 -0
  6. fractal_server/app/models/v2/dataset.py +1 -11
  7. fractal_server/app/models/v2/history.py +78 -0
  8. fractal_server/app/models/v2/job.py +10 -3
  9. fractal_server/app/models/v2/task_group.py +2 -2
  10. fractal_server/app/models/v2/workflow.py +1 -1
  11. fractal_server/app/models/v2/workflowtask.py +1 -1
  12. fractal_server/app/routes/admin/v2/__init__.py +4 -0
  13. fractal_server/app/routes/admin/v2/accounting.py +98 -0
  14. fractal_server/app/routes/admin/v2/impersonate.py +35 -0
  15. fractal_server/app/routes/admin/v2/job.py +5 -13
  16. fractal_server/app/routes/admin/v2/task.py +1 -1
  17. fractal_server/app/routes/admin/v2/task_group.py +4 -29
  18. fractal_server/app/routes/api/__init__.py +1 -1
  19. fractal_server/app/routes/api/v2/__init__.py +8 -2
  20. fractal_server/app/routes/api/v2/_aux_functions.py +66 -0
  21. fractal_server/app/routes/api/v2/_aux_functions_history.py +166 -0
  22. fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +3 -3
  23. fractal_server/app/routes/api/v2/dataset.py +0 -17
  24. fractal_server/app/routes/api/v2/history.py +544 -0
  25. fractal_server/app/routes/api/v2/images.py +31 -43
  26. fractal_server/app/routes/api/v2/job.py +30 -0
  27. fractal_server/app/routes/api/v2/project.py +1 -53
  28. fractal_server/app/routes/api/v2/{status.py → status_legacy.py} +6 -6
  29. fractal_server/app/routes/api/v2/submit.py +17 -14
  30. fractal_server/app/routes/api/v2/task.py +3 -10
  31. fractal_server/app/routes/api/v2/task_collection_custom.py +4 -9
  32. fractal_server/app/routes/api/v2/task_group.py +2 -22
  33. fractal_server/app/routes/api/v2/verify_image_types.py +61 -0
  34. fractal_server/app/routes/api/v2/workflow.py +28 -69
  35. fractal_server/app/routes/api/v2/workflowtask.py +53 -50
  36. fractal_server/app/routes/auth/group.py +0 -16
  37. fractal_server/app/routes/auth/oauth.py +5 -3
  38. fractal_server/app/routes/aux/__init__.py +0 -20
  39. fractal_server/app/routes/pagination.py +47 -0
  40. fractal_server/app/runner/components.py +0 -3
  41. fractal_server/app/runner/compress_folder.py +57 -29
  42. fractal_server/app/runner/exceptions.py +4 -0
  43. fractal_server/app/runner/executors/base_runner.py +157 -0
  44. fractal_server/app/runner/{v2/_local/_local_config.py → executors/local/get_local_config.py} +7 -9
  45. fractal_server/app/runner/executors/local/runner.py +248 -0
  46. fractal_server/app/runner/executors/{slurm → slurm_common}/_batching.py +1 -1
  47. fractal_server/app/runner/executors/{slurm → slurm_common}/_slurm_config.py +9 -7
  48. fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +868 -0
  49. fractal_server/app/runner/{v2/_slurm_common → executors/slurm_common}/get_slurm_config.py +48 -17
  50. fractal_server/app/runner/executors/{slurm → slurm_common}/remote.py +36 -47
  51. fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +134 -0
  52. fractal_server/app/runner/executors/slurm_ssh/runner.py +268 -0
  53. fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
  54. fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_subprocess_run_as_user.py +2 -83
  55. fractal_server/app/runner/executors/slurm_sudo/runner.py +193 -0
  56. fractal_server/app/runner/extract_archive.py +1 -3
  57. fractal_server/app/runner/task_files.py +134 -87
  58. fractal_server/app/runner/v2/__init__.py +0 -395
  59. fractal_server/app/runner/v2/_local.py +88 -0
  60. fractal_server/app/runner/v2/{_slurm_ssh/__init__.py → _slurm_ssh.py} +22 -19
  61. fractal_server/app/runner/v2/{_slurm_sudo/__init__.py → _slurm_sudo.py} +19 -15
  62. fractal_server/app/runner/v2/db_tools.py +119 -0
  63. fractal_server/app/runner/v2/runner.py +219 -98
  64. fractal_server/app/runner/v2/runner_functions.py +491 -189
  65. fractal_server/app/runner/v2/runner_functions_low_level.py +40 -43
  66. fractal_server/app/runner/v2/submit_workflow.py +358 -0
  67. fractal_server/app/runner/v2/task_interface.py +31 -0
  68. fractal_server/app/schemas/_validators.py +13 -24
  69. fractal_server/app/schemas/user.py +10 -7
  70. fractal_server/app/schemas/user_settings.py +9 -21
  71. fractal_server/app/schemas/v2/__init__.py +10 -1
  72. fractal_server/app/schemas/v2/accounting.py +18 -0
  73. fractal_server/app/schemas/v2/dataset.py +12 -94
  74. fractal_server/app/schemas/v2/dumps.py +26 -9
  75. fractal_server/app/schemas/v2/history.py +80 -0
  76. fractal_server/app/schemas/v2/job.py +15 -8
  77. fractal_server/app/schemas/v2/manifest.py +14 -7
  78. fractal_server/app/schemas/v2/project.py +9 -7
  79. fractal_server/app/schemas/v2/status_legacy.py +35 -0
  80. fractal_server/app/schemas/v2/task.py +72 -77
  81. fractal_server/app/schemas/v2/task_collection.py +14 -32
  82. fractal_server/app/schemas/v2/task_group.py +10 -9
  83. fractal_server/app/schemas/v2/workflow.py +10 -11
  84. fractal_server/app/schemas/v2/workflowtask.py +2 -21
  85. fractal_server/app/security/__init__.py +3 -3
  86. fractal_server/app/security/signup_email.py +2 -2
  87. fractal_server/config.py +91 -90
  88. fractal_server/images/tools.py +23 -0
  89. fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +50 -0
  90. fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +250 -0
  91. fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +57 -0
  92. fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +41 -0
  93. fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +36 -0
  94. fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +39 -0
  95. fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +120 -0
  96. fractal_server/ssh/_fabric.py +28 -14
  97. fractal_server/tasks/v2/local/collect.py +2 -2
  98. fractal_server/tasks/v2/ssh/collect.py +2 -2
  99. fractal_server/tasks/v2/templates/2_pip_install.sh +1 -1
  100. fractal_server/tasks/v2/templates/4_pip_show.sh +1 -1
  101. fractal_server/tasks/v2/utils_background.py +1 -20
  102. fractal_server/tasks/v2/utils_database.py +30 -17
  103. fractal_server/tasks/v2/utils_templates.py +6 -0
  104. {fractal_server-2.13.0.dist-info → fractal_server-2.14.0.dist-info}/METADATA +4 -4
  105. {fractal_server-2.13.0.dist-info → fractal_server-2.14.0.dist-info}/RECORD +114 -99
  106. {fractal_server-2.13.0.dist-info → fractal_server-2.14.0.dist-info}/WHEEL +1 -1
  107. fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -126
  108. fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -116
  109. fractal_server/app/runner/executors/slurm/ssh/executor.py +0 -1386
  110. fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -71
  111. fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -130
  112. fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -1281
  113. fractal_server/app/runner/v2/_local/__init__.py +0 -129
  114. fractal_server/app/runner/v2/_local/_submit_setup.py +0 -52
  115. fractal_server/app/runner/v2/_local/executor.py +0 -100
  116. fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -83
  117. fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -83
  118. fractal_server/app/runner/v2/handle_failed_job.py +0 -59
  119. fractal_server/app/schemas/v2/status.py +0 -16
  120. /fractal_server/app/{runner/executors/slurm → history}/__init__.py +0 -0
  121. /fractal_server/app/runner/executors/{slurm/ssh → local}/__init__.py +0 -0
  122. /fractal_server/app/runner/executors/{slurm/sudo → slurm_common}/__init__.py +0 -0
  123. /fractal_server/app/runner/executors/{_job_states.py → slurm_common/_job_states.py} +0 -0
  124. /fractal_server/app/runner/executors/{slurm → slurm_common}/utils_executors.py +0 -0
  125. /fractal_server/app/runner/{v2/_slurm_common → executors/slurm_ssh}/__init__.py +0 -0
  126. {fractal_server-2.13.0.dist-info → fractal_server-2.14.0.dist-info}/LICENSE +0 -0
  127. {fractal_server-2.13.0.dist-info → fractal_server-2.14.0.dist-info}/entry_points.txt +0 -0
@@ -1,129 +0,0 @@
1
- # Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
2
- # University of Zurich
3
- #
4
- # Original authors:
5
- # Jacopo Nespolo <jacopo.nespolo@exact-lab.it>
6
- # Tommaso Comparin <tommaso.comparin@exact-lab.it>
7
- # Marco Franzon <marco.franzon@exact-lab.it>
8
- #
9
- # This file is part of Fractal and was originally developed by eXact lab S.r.l.
10
- # <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
11
- # Institute for Biomedical Research and Pelkmans Lab from the University of
12
- # Zurich.
13
- """
14
- Local Bakend
15
-
16
- This backend runs Fractal workflows using `FractalThreadPoolExecutor` (a custom
17
- version of Python
18
- [ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor))
19
- to run tasks in several threads.
20
- Incidentally, it also represents the reference implementation for a backend.
21
- """
22
- from pathlib import Path
23
- from typing import Optional
24
-
25
- from ....models.v2 import DatasetV2
26
- from ....models.v2 import WorkflowV2
27
- from ...set_start_and_last_task_index import set_start_and_last_task_index
28
- from ..runner import execute_tasks_v2
29
- from ._submit_setup import _local_submit_setup
30
- from .executor import FractalThreadPoolExecutor
31
- from fractal_server.images.models import AttributeFiltersType
32
-
33
-
34
- def process_workflow(
35
- *,
36
- workflow: WorkflowV2,
37
- dataset: DatasetV2,
38
- workflow_dir_local: Path,
39
- workflow_dir_remote: Optional[Path] = None,
40
- first_task_index: Optional[int] = None,
41
- last_task_index: Optional[int] = None,
42
- logger_name: str,
43
- job_attribute_filters: AttributeFiltersType,
44
- # Slurm-specific
45
- user_cache_dir: Optional[str] = None,
46
- slurm_user: Optional[str] = None,
47
- slurm_account: Optional[str] = None,
48
- worker_init: Optional[str] = None,
49
- ) -> None:
50
- """
51
- Run a workflow
52
-
53
- This function is responsible for running a workflow on some input data,
54
- saving the output and taking care of any exception raised during the run.
55
-
56
- NOTE: This is the `local` backend's public interface, which also works as
57
- a reference implementation for other backends.
58
-
59
- Args:
60
- workflow:
61
- The workflow to be run
62
- dataset:
63
- Initial dataset.
64
- workflow_dir_local:
65
- Working directory for this run.
66
- workflow_dir_remote:
67
- Working directory for this run, on the user side. This argument is
68
- present for compatibility with the standard backend interface, but
69
- for the `local` backend it cannot be different from
70
- `workflow_dir_local`.
71
- first_task_index:
72
- Positional index of the first task to execute; if `None`, start
73
- from `0`.
74
- last_task_index:
75
- Positional index of the last task to execute; if `None`, proceed
76
- until the last task.
77
- logger_name: Logger name
78
- slurm_user:
79
- Username to impersonate to run the workflow. This argument is
80
- present for compatibility with the standard backend interface, but
81
- is ignored in the `local` backend.
82
- slurm_account:
83
- SLURM account to use when running the workflow. This argument is
84
- present for compatibility with the standard backend interface, but
85
- is ignored in the `local` backend.
86
- user_cache_dir:
87
- Cache directory of the user who will run the workflow. This
88
- argument is present for compatibility with the standard backend
89
- interface, but is ignored in the `local` backend.
90
- worker_init:
91
- Any additional, usually backend specific, information to be passed
92
- to the backend executor. This argument is present for compatibility
93
- with the standard backend interface, but is ignored in the `local`
94
- backend.
95
-
96
- Raises:
97
- TaskExecutionError: wrapper for errors raised during tasks' execution
98
- (positive exit codes).
99
- JobExecutionError: wrapper for errors raised by the tasks' executors
100
- (negative exit codes).
101
- """
102
-
103
- if workflow_dir_remote and (workflow_dir_remote != workflow_dir_local):
104
- raise NotImplementedError(
105
- "Local backend does not support different directories "
106
- f"{workflow_dir_local=} and {workflow_dir_remote=}"
107
- )
108
-
109
- # Set values of first_task_index and last_task_index
110
- num_tasks = len(workflow.task_list)
111
- first_task_index, last_task_index = set_start_and_last_task_index(
112
- num_tasks,
113
- first_task_index=first_task_index,
114
- last_task_index=last_task_index,
115
- )
116
-
117
- with FractalThreadPoolExecutor() as executor:
118
- execute_tasks_v2(
119
- wf_task_list=workflow.task_list[
120
- first_task_index : (last_task_index + 1)
121
- ],
122
- dataset=dataset,
123
- executor=executor,
124
- workflow_dir_local=workflow_dir_local,
125
- workflow_dir_remote=workflow_dir_local,
126
- logger_name=logger_name,
127
- submit_setup_call=_local_submit_setup,
128
- job_attribute_filters=job_attribute_filters,
129
- )
@@ -1,52 +0,0 @@
1
- # Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
2
- # University of Zurich
3
- #
4
- # Original authors:
5
- # Tommaso Comparin <tommaso.comparin@exact-lab.it>
6
- #
7
- # This file is part of Fractal and was originally developed by eXact lab S.r.l.
8
- # <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
9
- # Institute for Biomedical Research and Pelkmans Lab from the University of
10
- # Zurich.
11
- """
12
- Submodule to define _local_submit_setup
13
- """
14
- from pathlib import Path
15
- from typing import Literal
16
- from typing import Optional
17
-
18
- from ....models.v2 import WorkflowTaskV2
19
- from ._local_config import get_local_backend_config
20
-
21
-
22
- def _local_submit_setup(
23
- *,
24
- wftask: WorkflowTaskV2,
25
- workflow_dir_local: Optional[Path] = None,
26
- workflow_dir_remote: Optional[Path] = None,
27
- which_type: Literal["non_parallel", "parallel"],
28
- ) -> dict[str, object]:
29
- """
30
- Collect WorfklowTask-specific configuration parameters from different
31
- sources, and inject them for execution.
32
-
33
- Arguments:
34
- wftask:
35
- WorkflowTask for which the configuration is to be assembled
36
- workflow_dir_local:
37
- Not used in this function.
38
- workflow_dir_remote:
39
- Not used in this function.
40
-
41
- Returns:
42
- submit_setup_dict:
43
- A dictionary that will be passed on to
44
- `FractalThreadPoolExecutor.submit` and
45
- `FractalThreadPoolExecutor.map`, so as to set extra options.
46
- """
47
-
48
- local_backend_config = get_local_backend_config(
49
- wftask=wftask, which_type=which_type
50
- )
51
-
52
- return dict(local_backend_config=local_backend_config)
@@ -1,100 +0,0 @@
1
- # Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
2
- # University of Zurich
3
- #
4
- # Original authors:
5
- # Tommaso Comparin <tommaso.comparin@exact-lab.it>
6
- #
7
- # This file is part of Fractal and was originally developed by eXact lab S.r.l.
8
- # <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
9
- # Institute for Biomedical Research and Pelkmans Lab from the University of
10
- # Zurich.
11
- """
12
- Custom version of Python
13
- [ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).
14
- """
15
- from concurrent.futures import ThreadPoolExecutor
16
- from typing import Callable
17
- from typing import Iterable
18
- from typing import Optional
19
- from typing import Sequence
20
-
21
- from ._local_config import get_default_local_backend_config
22
- from ._local_config import LocalBackendConfig
23
-
24
-
25
- class FractalThreadPoolExecutor(ThreadPoolExecutor):
26
- """
27
- Custom version of
28
- [ThreadPoolExecutor](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor))
29
- that overrides the `submit` and `map` methods
30
- """
31
-
32
- def submit(
33
- self,
34
- *args,
35
- local_backend_config: Optional[LocalBackendConfig] = None,
36
- **kwargs,
37
- ):
38
- """
39
- Compared to the `ThreadPoolExecutor` method, here we accept an addition
40
- keyword argument (`local_backend_config`), which is then simply
41
- ignored.
42
- """
43
- return super().submit(*args, **kwargs)
44
-
45
- def map(
46
- self,
47
- fn: Callable,
48
- *iterables: Sequence[Iterable],
49
- local_backend_config: Optional[LocalBackendConfig] = None,
50
- ):
51
- """
52
- Custom version of the `Executor.map` method
53
-
54
- The main change with the respect to the original `map` method is that
55
- the list of tasks to be executed is split into chunks, and then
56
- `super().map` is called (sequentially) on each chunk. The goal of this
57
- change is to limit parallelism, e.g. due to limited computational
58
- resources.
59
-
60
- Other changes from the `concurrent.futures` `map` method:
61
-
62
- 1. Removed `timeout` argument;
63
- 2. Removed `chunksize`;
64
- 3. All iterators (both inputs and output ones) are transformed into
65
- lists.
66
-
67
- Args:
68
- fn: A callable function.
69
- iterables: The argument iterables (one iterable per argument of
70
- `fn`).
71
- local_backend_config: The backend configuration, needed to extract
72
- `parallel_tasks_per_job`.
73
- """
74
-
75
- # Preliminary check
76
- iterable_lengths = [len(it) for it in iterables]
77
- if not len(set(iterable_lengths)) == 1:
78
- raise ValueError("Iterables have different lengths.")
79
-
80
- # Set total number of arguments
81
- n_elements = len(iterables[0])
82
-
83
- # Set parallel_tasks_per_job
84
- if local_backend_config is None:
85
- local_backend_config = get_default_local_backend_config()
86
- parallel_tasks_per_job = local_backend_config.parallel_tasks_per_job
87
- if parallel_tasks_per_job is None:
88
- parallel_tasks_per_job = n_elements
89
-
90
- # Execute tasks, in chunks of size parallel_tasks_per_job
91
- results = []
92
- for ind_chunk in range(0, n_elements, parallel_tasks_per_job):
93
- chunk_iterables = [
94
- it[ind_chunk : ind_chunk + parallel_tasks_per_job] # noqa
95
- for it in iterables
96
- ]
97
- map_iter = super().map(fn, *chunk_iterables)
98
- results.extend(list(map_iter))
99
-
100
- return iter(results)
@@ -1,83 +0,0 @@
1
- # Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
2
- # University of Zurich
3
- #
4
- # Original authors:
5
- # Jacopo Nespolo <jacopo.nespolo@exact-lab.it>
6
- # Tommaso Comparin <tommaso.comparin@exact-lab.it>
7
- #
8
- # This file is part of Fractal and was originally developed by eXact lab S.r.l.
9
- # <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
10
- # Institute for Biomedical Research and Pelkmans Lab from the University of
11
- # Zurich.
12
- """
13
- Submodule to define _slurm_submit_setup, which is also the reference
14
- implementation of `submit_setup_call`.
15
- """
16
- from pathlib import Path
17
- from typing import Literal
18
-
19
- from ...task_files import get_task_file_paths
20
- from fractal_server.app.models.v2 import WorkflowTaskV2
21
- from fractal_server.app.runner.v2._slurm_common.get_slurm_config import (
22
- get_slurm_config,
23
- )
24
-
25
-
26
- def _slurm_submit_setup(
27
- *,
28
- wftask: WorkflowTaskV2,
29
- workflow_dir_local: Path,
30
- workflow_dir_remote: Path,
31
- which_type: Literal["non_parallel", "parallel"],
32
- ) -> dict[str, object]:
33
- """
34
- Collect WorfklowTask-specific configuration parameters from different
35
- sources, and inject them for execution.
36
-
37
- Here goes all the logic for reading attributes from the appropriate sources
38
- and transforming them into an appropriate `SlurmConfig` object (encoding
39
- SLURM configuration) and `TaskFiles` object (with details e.g. about file
40
- paths or filename prefixes).
41
-
42
- For now, this is the reference implementation for the argument
43
- `submit_setup_call` of
44
- [fractal_server.app.runner.v2.runner][].
45
-
46
- Arguments:
47
- wftask:
48
- WorkflowTask for which the configuration is to be assembled
49
- workflow_dir_local:
50
- Server-owned directory to store all task-execution-related relevant
51
- files (inputs, outputs, errors, and all meta files related to the
52
- job execution). Note: users cannot write directly to this folder.
53
- workflow_dir_remote:
54
- User-side directory with the same scope as `workflow_dir_local`,
55
- and where a user can write.
56
-
57
- Returns:
58
- submit_setup_dict:
59
- A dictionary that will be passed on to
60
- `FractalSlurmExecutor.submit` and `FractalSlurmExecutor.map`, so
61
- as to set extra options.
62
- """
63
-
64
- # Get SlurmConfig object
65
- slurm_config = get_slurm_config(
66
- wftask=wftask,
67
- which_type=which_type,
68
- )
69
-
70
- # Get TaskFiles object
71
- task_files = get_task_file_paths(
72
- workflow_dir_local=workflow_dir_local,
73
- workflow_dir_remote=workflow_dir_remote,
74
- task_order=wftask.order,
75
- task_name=wftask.task.name,
76
- )
77
-
78
- # Prepare and return output dictionary
79
- submit_setup_dict = dict(
80
- slurm_config=slurm_config,
81
- task_files=task_files,
82
- )
83
- return submit_setup_dict
@@ -1,83 +0,0 @@
1
- # Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
2
- # University of Zurich
3
- #
4
- # Original authors:
5
- # Jacopo Nespolo <jacopo.nespolo@exact-lab.it>
6
- # Tommaso Comparin <tommaso.comparin@exact-lab.it>
7
- #
8
- # This file is part of Fractal and was originally developed by eXact lab S.r.l.
9
- # <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
10
- # Institute for Biomedical Research and Pelkmans Lab from the University of
11
- # Zurich.
12
- """
13
- Submodule to define _slurm_submit_setup, which is also the reference
14
- implementation of `submit_setup_call`.
15
- """
16
- from pathlib import Path
17
- from typing import Literal
18
-
19
- from ...task_files import get_task_file_paths
20
- from fractal_server.app.models.v2 import WorkflowTaskV2
21
- from fractal_server.app.runner.v2._slurm_common.get_slurm_config import (
22
- get_slurm_config,
23
- )
24
-
25
-
26
- def _slurm_submit_setup(
27
- *,
28
- wftask: WorkflowTaskV2,
29
- workflow_dir_local: Path,
30
- workflow_dir_remote: Path,
31
- which_type: Literal["non_parallel", "parallel"],
32
- ) -> dict[str, object]:
33
- """
34
- Collect WorfklowTask-specific configuration parameters from different
35
- sources, and inject them for execution.
36
-
37
- Here goes all the logic for reading attributes from the appropriate sources
38
- and transforming them into an appropriate `SlurmConfig` object (encoding
39
- SLURM configuration) and `TaskFiles` object (with details e.g. about file
40
- paths or filename prefixes).
41
-
42
- For now, this is the reference implementation for the argument
43
- `submit_setup_call` of
44
- [fractal_server.app.runner.v2.runner][].
45
-
46
- Arguments:
47
- wftask:
48
- WorkflowTask for which the configuration is to be assembled
49
- workflow_dir_local:
50
- Server-owned directory to store all task-execution-related relevant
51
- files (inputs, outputs, errors, and all meta files related to the
52
- job execution). Note: users cannot write directly to this folder.
53
- workflow_dir_remote:
54
- User-side directory with the same scope as `workflow_dir_local`,
55
- and where a user can write.
56
-
57
- Returns:
58
- submit_setup_dict:
59
- A dictionary that will be passed on to
60
- `FractalSlurmExecutor.submit` and `FractalSlurmExecutor.map`, so
61
- as to set extra options.
62
- """
63
-
64
- # Get SlurmConfig object
65
- slurm_config = get_slurm_config(
66
- wftask=wftask,
67
- which_type=which_type,
68
- )
69
-
70
- # Get TaskFiles object
71
- task_files = get_task_file_paths(
72
- workflow_dir_local=workflow_dir_local,
73
- workflow_dir_remote=workflow_dir_remote,
74
- task_order=wftask.order,
75
- task_name=wftask.task.name,
76
- )
77
-
78
- # Prepare and return output dictionary
79
- submit_setup_dict = dict(
80
- slurm_config=slurm_config,
81
- task_files=task_files,
82
- )
83
- return submit_setup_dict
@@ -1,59 +0,0 @@
1
- # Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
2
- # University of Zurich
3
- #
4
- # Original authors:
5
- # Tommaso Comparin <tommaso.comparin@exact-lab.it>
6
- # Marco Franzon <marco.franzon@exact-lab.it>
7
- #
8
- # This file is part of Fractal and was originally developed by eXact lab S.r.l.
9
- # <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
10
- # Institute for Biomedical Research and Pelkmans Lab from the University of
11
- # Zurich.
12
- """
13
- Helper functions to handle Dataset history.
14
- """
15
- import logging
16
-
17
- from sqlalchemy.orm.attributes import flag_modified
18
-
19
- from ...models.v2 import DatasetV2
20
- from ...schemas.v2 import WorkflowTaskStatusTypeV2
21
- from fractal_server.app.db import get_sync_db
22
-
23
-
24
- def mark_last_wftask_as_failed(
25
- dataset_id: int,
26
- logger_name: str,
27
- ) -> None:
28
- """
29
- Edit dataset history, by marking last item as failed.
30
-
31
- Args:
32
- dataset: The `DatasetV2` object
33
- logger_name: A logger name.
34
- """
35
-
36
- logger = logging.getLogger(logger_name)
37
- with next(get_sync_db()) as db:
38
- db_dataset = db.get(DatasetV2, dataset_id)
39
- if len(db_dataset.history) == 0:
40
- logger.warning(
41
- f"History for {dataset_id=} is empty. Likely reason: the job "
42
- "failed before its first task was marked as SUBMITTED. "
43
- "Continue."
44
- )
45
- return
46
- workflowtask_id = db_dataset.history[-1]["workflowtask"]["id"]
47
- last_item_status = db_dataset.history[-1]["status"]
48
- if last_item_status != WorkflowTaskStatusTypeV2.SUBMITTED:
49
- logger.warning(
50
- "Unexpected branch: "
51
- f"Last history item, for {workflowtask_id=}, "
52
- f"has status {last_item_status}. Skip."
53
- )
54
- return
55
- logger.info(f"Setting history item for {workflowtask_id=} to failed.")
56
- db_dataset.history[-1]["status"] = WorkflowTaskStatusTypeV2.FAILED
57
- flag_modified(db_dataset, "history")
58
- db.merge(db_dataset)
59
- db.commit()
@@ -1,16 +0,0 @@
1
- from pydantic import BaseModel
2
- from pydantic import Field
3
-
4
- from .workflowtask import WorkflowTaskStatusTypeV2
5
-
6
-
7
- class StatusReadV2(BaseModel):
8
- """
9
- Response type for the
10
- `/project/{project_id}/status/` endpoint
11
- """
12
-
13
- status: dict[
14
- str,
15
- WorkflowTaskStatusTypeV2,
16
- ] = Field(default_factory=dict)