fractal-server 1.4.10__py3-none-any.whl → 2.0.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 (138) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/app/models/__init__.py +6 -8
  3. fractal_server/app/models/linkuserproject.py +9 -0
  4. fractal_server/app/models/security.py +6 -0
  5. fractal_server/app/models/v1/__init__.py +12 -0
  6. fractal_server/app/models/{dataset.py → v1/dataset.py} +5 -5
  7. fractal_server/app/models/{job.py → v1/job.py} +5 -5
  8. fractal_server/app/models/{project.py → v1/project.py} +5 -5
  9. fractal_server/app/models/{state.py → v1/state.py} +2 -2
  10. fractal_server/app/models/{task.py → v1/task.py} +7 -2
  11. fractal_server/app/models/{workflow.py → v1/workflow.py} +5 -5
  12. fractal_server/app/models/v2/__init__.py +22 -0
  13. fractal_server/app/models/v2/collection_state.py +21 -0
  14. fractal_server/app/models/v2/dataset.py +54 -0
  15. fractal_server/app/models/v2/job.py +51 -0
  16. fractal_server/app/models/v2/project.py +30 -0
  17. fractal_server/app/models/v2/task.py +93 -0
  18. fractal_server/app/models/v2/workflow.py +35 -0
  19. fractal_server/app/models/v2/workflowtask.py +49 -0
  20. fractal_server/app/routes/admin/__init__.py +0 -0
  21. fractal_server/app/routes/{admin.py → admin/v1.py} +42 -42
  22. fractal_server/app/routes/admin/v2.py +309 -0
  23. fractal_server/app/routes/api/v1/__init__.py +7 -7
  24. fractal_server/app/routes/api/v1/_aux_functions.py +8 -8
  25. fractal_server/app/routes/api/v1/dataset.py +41 -41
  26. fractal_server/app/routes/api/v1/job.py +14 -14
  27. fractal_server/app/routes/api/v1/project.py +27 -25
  28. fractal_server/app/routes/api/v1/task.py +26 -16
  29. fractal_server/app/routes/api/v1/task_collection.py +28 -16
  30. fractal_server/app/routes/api/v1/workflow.py +28 -28
  31. fractal_server/app/routes/api/v1/workflowtask.py +11 -11
  32. fractal_server/app/routes/api/v2/__init__.py +34 -0
  33. fractal_server/app/routes/api/v2/_aux_functions.py +502 -0
  34. fractal_server/app/routes/api/v2/dataset.py +293 -0
  35. fractal_server/app/routes/api/v2/images.py +279 -0
  36. fractal_server/app/routes/api/v2/job.py +200 -0
  37. fractal_server/app/routes/api/v2/project.py +186 -0
  38. fractal_server/app/routes/api/v2/status.py +150 -0
  39. fractal_server/app/routes/api/v2/submit.py +210 -0
  40. fractal_server/app/routes/api/v2/task.py +222 -0
  41. fractal_server/app/routes/api/v2/task_collection.py +239 -0
  42. fractal_server/app/routes/api/v2/task_legacy.py +59 -0
  43. fractal_server/app/routes/api/v2/workflow.py +380 -0
  44. fractal_server/app/routes/api/v2/workflowtask.py +265 -0
  45. fractal_server/app/routes/aux/_job.py +2 -2
  46. fractal_server/app/runner/__init__.py +0 -364
  47. fractal_server/app/runner/async_wrap.py +27 -0
  48. fractal_server/app/runner/components.py +5 -0
  49. fractal_server/app/runner/exceptions.py +129 -0
  50. fractal_server/app/runner/executors/__init__.py +0 -0
  51. fractal_server/app/runner/executors/slurm/__init__.py +3 -0
  52. fractal_server/app/runner/{_slurm → executors/slurm}/_batching.py +1 -1
  53. fractal_server/app/runner/{_slurm → executors/slurm}/_check_jobs_status.py +1 -1
  54. fractal_server/app/runner/{_slurm → executors/slurm}/_executor_wait_thread.py +1 -1
  55. fractal_server/app/runner/{_slurm → executors/slurm}/_slurm_config.py +3 -152
  56. fractal_server/app/runner/{_slurm → executors/slurm}/_subprocess_run_as_user.py +1 -1
  57. fractal_server/app/runner/{_slurm → executors/slurm}/executor.py +32 -21
  58. fractal_server/app/runner/filenames.py +6 -0
  59. fractal_server/app/runner/set_start_and_last_task_index.py +39 -0
  60. fractal_server/app/runner/task_files.py +103 -0
  61. fractal_server/app/runner/v1/__init__.py +366 -0
  62. fractal_server/app/runner/{_common.py → v1/_common.py} +14 -121
  63. fractal_server/app/runner/{_local → v1/_local}/__init__.py +5 -4
  64. fractal_server/app/runner/{_local → v1/_local}/_local_config.py +6 -7
  65. fractal_server/app/runner/{_local → v1/_local}/_submit_setup.py +1 -5
  66. fractal_server/app/runner/v1/_slurm/__init__.py +312 -0
  67. fractal_server/app/runner/{_slurm → v1/_slurm}/_submit_setup.py +5 -11
  68. fractal_server/app/runner/v1/_slurm/get_slurm_config.py +163 -0
  69. fractal_server/app/runner/v1/common.py +117 -0
  70. fractal_server/app/runner/{handle_failed_job.py → v1/handle_failed_job.py} +8 -8
  71. fractal_server/app/runner/v2/__init__.py +336 -0
  72. fractal_server/app/runner/v2/_local/__init__.py +162 -0
  73. fractal_server/app/runner/v2/_local/_local_config.py +118 -0
  74. fractal_server/app/runner/v2/_local/_submit_setup.py +52 -0
  75. fractal_server/app/runner/v2/_local/executor.py +100 -0
  76. fractal_server/app/runner/{_slurm → v2/_slurm}/__init__.py +38 -47
  77. fractal_server/app/runner/v2/_slurm/_submit_setup.py +82 -0
  78. fractal_server/app/runner/v2/_slurm/get_slurm_config.py +182 -0
  79. fractal_server/app/runner/v2/deduplicate_list.py +23 -0
  80. fractal_server/app/runner/v2/handle_failed_job.py +165 -0
  81. fractal_server/app/runner/v2/merge_outputs.py +38 -0
  82. fractal_server/app/runner/v2/runner.py +343 -0
  83. fractal_server/app/runner/v2/runner_functions.py +374 -0
  84. fractal_server/app/runner/v2/runner_functions_low_level.py +130 -0
  85. fractal_server/app/runner/v2/task_interface.py +62 -0
  86. fractal_server/app/runner/v2/v1_compat.py +31 -0
  87. fractal_server/app/schemas/__init__.py +1 -42
  88. fractal_server/app/schemas/_validators.py +28 -5
  89. fractal_server/app/schemas/v1/__init__.py +36 -0
  90. fractal_server/app/schemas/{applyworkflow.py → v1/applyworkflow.py} +18 -18
  91. fractal_server/app/schemas/{dataset.py → v1/dataset.py} +30 -30
  92. fractal_server/app/schemas/{dumps.py → v1/dumps.py} +8 -8
  93. fractal_server/app/schemas/{manifest.py → v1/manifest.py} +5 -5
  94. fractal_server/app/schemas/{project.py → v1/project.py} +9 -9
  95. fractal_server/app/schemas/{task.py → v1/task.py} +12 -12
  96. fractal_server/app/schemas/{task_collection.py → v1/task_collection.py} +7 -7
  97. fractal_server/app/schemas/{workflow.py → v1/workflow.py} +38 -38
  98. fractal_server/app/schemas/v2/__init__.py +37 -0
  99. fractal_server/app/schemas/v2/dataset.py +126 -0
  100. fractal_server/app/schemas/v2/dumps.py +87 -0
  101. fractal_server/app/schemas/v2/job.py +114 -0
  102. fractal_server/app/schemas/v2/manifest.py +159 -0
  103. fractal_server/app/schemas/v2/project.py +34 -0
  104. fractal_server/app/schemas/v2/status.py +16 -0
  105. fractal_server/app/schemas/v2/task.py +151 -0
  106. fractal_server/app/schemas/v2/task_collection.py +109 -0
  107. fractal_server/app/schemas/v2/workflow.py +79 -0
  108. fractal_server/app/schemas/v2/workflowtask.py +208 -0
  109. fractal_server/config.py +5 -4
  110. fractal_server/images/__init__.py +4 -0
  111. fractal_server/images/models.py +136 -0
  112. fractal_server/images/tools.py +84 -0
  113. fractal_server/main.py +11 -3
  114. fractal_server/migrations/env.py +0 -2
  115. fractal_server/migrations/versions/5bf02391cfef_v2.py +245 -0
  116. fractal_server/tasks/__init__.py +0 -5
  117. fractal_server/tasks/endpoint_operations.py +13 -19
  118. fractal_server/tasks/utils.py +35 -0
  119. fractal_server/tasks/{_TaskCollectPip.py → v1/_TaskCollectPip.py} +3 -3
  120. fractal_server/tasks/v1/__init__.py +0 -0
  121. fractal_server/tasks/{background_operations.py → v1/background_operations.py} +20 -52
  122. fractal_server/tasks/v1/get_collection_data.py +14 -0
  123. fractal_server/tasks/v2/_TaskCollectPip.py +103 -0
  124. fractal_server/tasks/v2/__init__.py +0 -0
  125. fractal_server/tasks/v2/background_operations.py +381 -0
  126. fractal_server/tasks/v2/get_collection_data.py +14 -0
  127. fractal_server/urls.py +13 -0
  128. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0.dist-info}/METADATA +10 -10
  129. fractal_server-2.0.0.dist-info/RECORD +169 -0
  130. fractal_server/app/runner/_slurm/.gitignore +0 -2
  131. fractal_server/app/runner/common.py +0 -311
  132. fractal_server/app/schemas/json_schemas/manifest.json +0 -81
  133. fractal_server-1.4.10.dist-info/RECORD +0 -98
  134. /fractal_server/app/runner/{_slurm → executors/slurm}/remote.py +0 -0
  135. /fractal_server/app/runner/{_local → v1/_local}/executor.py +0 -0
  136. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0.dist-info}/LICENSE +0 -0
  137. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0.dist-info}/WHEEL +0 -0
  138. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,381 @@
1
+ """
2
+ The main function exported from this module is `background_collect_pip`, which
3
+ is used as a background task for the task-collection endpoint.
4
+ """
5
+ import json
6
+ from pathlib import Path
7
+ from shutil import rmtree as shell_rmtree
8
+
9
+ from ..utils import _init_venv
10
+ from ..utils import _normalize_package_name
11
+ from ..utils import get_collection_log
12
+ from ..utils import get_collection_path
13
+ from ..utils import get_log_path
14
+ from ..utils import slugify_task_name
15
+ from ._TaskCollectPip import _TaskCollectPip
16
+ from fractal_server.app.db import DBSyncSession
17
+ from fractal_server.app.db import get_sync_db
18
+ from fractal_server.app.models.v2 import CollectionStateV2
19
+ from fractal_server.app.models.v2 import TaskV2
20
+ from fractal_server.app.schemas.v2 import TaskCollectStatusV2
21
+ from fractal_server.app.schemas.v2 import TaskCreateV2
22
+ from fractal_server.app.schemas.v2 import TaskReadV2
23
+ from fractal_server.logger import close_logger
24
+ from fractal_server.logger import get_logger
25
+ from fractal_server.logger import set_logger
26
+ from fractal_server.utils import execute_command
27
+
28
+
29
+ async def _pip_install(
30
+ venv_path: Path,
31
+ task_pkg: _TaskCollectPip,
32
+ logger_name: str,
33
+ ) -> Path:
34
+ """
35
+ Install package in venv
36
+
37
+ Args:
38
+ venv_path:
39
+ task_pkg:
40
+ logger_name:
41
+
42
+ Returns:
43
+ The location of the package.
44
+ """
45
+
46
+ logger = get_logger(logger_name)
47
+
48
+ pip = venv_path / "venv/bin/pip"
49
+
50
+ extras = f"[{task_pkg.package_extras}]" if task_pkg.package_extras else ""
51
+
52
+ if task_pkg.is_local_package:
53
+ pip_install_str = f"{task_pkg.package_path.as_posix()}{extras}"
54
+ else:
55
+ version_string = (
56
+ f"=={task_pkg.package_version}" if task_pkg.package_version else ""
57
+ )
58
+ pip_install_str = f"{task_pkg.package}{extras}{version_string}"
59
+
60
+ cmd_install = f"{pip} install {pip_install_str}"
61
+ cmd_inspect = f"{pip} show {task_pkg.package}"
62
+
63
+ await execute_command(
64
+ cwd=venv_path,
65
+ command=f"{pip} install --upgrade pip",
66
+ logger_name=logger_name,
67
+ )
68
+ await execute_command(
69
+ cwd=venv_path, command=cmd_install, logger_name=logger_name
70
+ )
71
+ if task_pkg.pinned_package_versions:
72
+ for (
73
+ pinned_pkg_name,
74
+ pinned_pkg_version,
75
+ ) in task_pkg.pinned_package_versions.items():
76
+
77
+ logger.debug(
78
+ "Specific version required: "
79
+ f"{pinned_pkg_name}=={pinned_pkg_version}"
80
+ )
81
+ logger.debug(
82
+ "Preliminary check: verify that "
83
+ f"{pinned_pkg_version} is already installed"
84
+ )
85
+ stdout_inspect = await execute_command(
86
+ cwd=venv_path,
87
+ command=f"{pip} show {pinned_pkg_name}",
88
+ logger_name=logger_name,
89
+ )
90
+ current_version = next(
91
+ line.split()[-1]
92
+ for line in stdout_inspect.split("\n")
93
+ if line.startswith("Version:")
94
+ )
95
+ if current_version != pinned_pkg_version:
96
+ logger.debug(
97
+ f"Currently installed version of {pinned_pkg_name} "
98
+ f"({current_version}) differs from pinned version "
99
+ f"({pinned_pkg_version}); "
100
+ f"install version {pinned_pkg_version}."
101
+ )
102
+ await execute_command(
103
+ cwd=venv_path,
104
+ command=(
105
+ f"{pip} install "
106
+ f"{pinned_pkg_name}=={pinned_pkg_version}"
107
+ ),
108
+ logger_name=logger_name,
109
+ )
110
+ else:
111
+ logger.debug(
112
+ f"Currently installed version of {pinned_pkg_name} "
113
+ f"({current_version}) already matches the pinned version."
114
+ )
115
+
116
+ # Extract package installation path from `pip show`
117
+ stdout_inspect = await execute_command(
118
+ cwd=venv_path, command=cmd_inspect, logger_name=logger_name
119
+ )
120
+
121
+ location = Path(
122
+ next(
123
+ line.split()[-1]
124
+ for line in stdout_inspect.split("\n")
125
+ if line.startswith("Location:")
126
+ )
127
+ )
128
+
129
+ # NOTE
130
+ # https://packaging.python.org/en/latest/specifications/recording-installed-packages/
131
+ # This directory is named as {name}-{version}.dist-info, with name and
132
+ # version fields corresponding to Core metadata specifications. Both
133
+ # fields must be normalized (see the name normalization specification and
134
+ # the version normalization specification), and replace dash (-)
135
+ # characters with underscore (_) characters, so the .dist-info directory
136
+ # always has exactly one dash (-) character in its stem, separating the
137
+ # name and version fields.
138
+ package_root = location / (task_pkg.package.replace("-", "_"))
139
+ logger.debug(f"[_pip install] {location=}")
140
+ logger.debug(f"[_pip install] {task_pkg.package=}")
141
+ logger.debug(f"[_pip install] {package_root=}")
142
+ if not package_root.exists():
143
+ raise RuntimeError(
144
+ "Could not determine package installation location."
145
+ )
146
+ return package_root
147
+
148
+
149
+ async def _create_venv_install_package(
150
+ *,
151
+ task_pkg: _TaskCollectPip,
152
+ path: Path,
153
+ logger_name: str,
154
+ ) -> tuple[Path, Path]:
155
+ """Create venv and install package
156
+
157
+ Args:
158
+ path: the directory in which to create the environment
159
+ task_pkg: object containing the different metadata required to install
160
+ the package
161
+
162
+ Returns:
163
+ python_bin: path to venv's python interpreter
164
+ package_root: the location of the package manifest
165
+ """
166
+
167
+ # Normalize package name
168
+ task_pkg.package_name = _normalize_package_name(task_pkg.package_name)
169
+ task_pkg.package = _normalize_package_name(task_pkg.package)
170
+
171
+ python_bin = await _init_venv(
172
+ path=path,
173
+ python_version=task_pkg.python_version,
174
+ logger_name=logger_name,
175
+ )
176
+ package_root = await _pip_install(
177
+ venv_path=path, task_pkg=task_pkg, logger_name=logger_name
178
+ )
179
+ return python_bin, package_root
180
+
181
+
182
+ async def create_package_environment_pip(
183
+ *,
184
+ task_pkg: _TaskCollectPip,
185
+ venv_path: Path,
186
+ logger_name: str,
187
+ ) -> list[TaskCreateV2]:
188
+ """
189
+ Create environment, install package, and prepare task list
190
+ """
191
+
192
+ logger = get_logger(logger_name)
193
+
194
+ # Normalize package name
195
+ task_pkg.package_name = _normalize_package_name(task_pkg.package_name)
196
+ task_pkg.package = _normalize_package_name(task_pkg.package)
197
+
198
+ # Only proceed if package, version and manifest attributes are set
199
+ task_pkg.check()
200
+
201
+ try:
202
+
203
+ logger.debug("Creating venv and installing package")
204
+ python_bin, package_root = await _create_venv_install_package(
205
+ path=venv_path,
206
+ task_pkg=task_pkg,
207
+ logger_name=logger_name,
208
+ )
209
+ logger.debug("Venv creation and package installation ended correctly.")
210
+
211
+ # Prepare task_list with appropriate metadata
212
+ logger.debug("Creating task list from manifest")
213
+ task_list = []
214
+ for t in task_pkg.package_manifest.task_list:
215
+ # Fill in attributes for TaskCreate
216
+ task_attributes = {}
217
+ task_attributes["version"] = task_pkg.package_version
218
+ task_name_slug = slugify_task_name(t.name)
219
+ task_attributes[
220
+ "source"
221
+ ] = f"{task_pkg.package_source}:{task_name_slug}"
222
+ # Executables
223
+ if t.executable_non_parallel is not None:
224
+ non_parallel_path = package_root / t.executable_non_parallel
225
+ if not non_parallel_path.exists():
226
+ raise FileNotFoundError(
227
+ f"Cannot find executable `{non_parallel_path}` "
228
+ f"for task `{t.name}`"
229
+ )
230
+ task_attributes[
231
+ "command_non_parallel"
232
+ ] = f"{python_bin.as_posix()} {non_parallel_path.as_posix()}"
233
+ if t.executable_parallel is not None:
234
+ parallel_path = package_root / t.executable_parallel
235
+ if not parallel_path.exists():
236
+ raise FileNotFoundError(
237
+ f"Cannot find executable `{parallel_path}` "
238
+ f"for task `{t.name}`"
239
+ )
240
+ task_attributes[
241
+ "command_parallel"
242
+ ] = f"{python_bin.as_posix()} {parallel_path.as_posix()}"
243
+
244
+ manifest = task_pkg.package_manifest
245
+ if manifest.has_args_schemas:
246
+ task_attributes[
247
+ "args_schema_version"
248
+ ] = manifest.args_schema_version
249
+
250
+ this_task = TaskCreateV2(
251
+ **t.dict(
252
+ exclude={"executable_non_parallel", "executable_parallel"}
253
+ ),
254
+ **task_attributes,
255
+ )
256
+ task_list.append(this_task)
257
+ logger.debug("Task list created correctly")
258
+ except Exception as e:
259
+ logger.error("Task manifest loading failed")
260
+ raise e
261
+ return task_list
262
+
263
+
264
+ def _get_task_type(task: TaskCreateV2) -> str:
265
+ if task.command_non_parallel is None:
266
+ return "parallel"
267
+ elif task.command_parallel is None:
268
+ return "non_parallel"
269
+ else:
270
+ return "compound"
271
+
272
+
273
+ async def _insert_tasks(
274
+ task_list: list[TaskCreateV2],
275
+ db: DBSyncSession,
276
+ ) -> list[TaskV2]:
277
+ """
278
+ Insert tasks into database
279
+ """
280
+
281
+ task_db_list = [
282
+ TaskV2(**t.dict(), type=_get_task_type(t)) for t in task_list
283
+ ]
284
+ db.add_all(task_db_list)
285
+ db.commit()
286
+ for t in task_db_list:
287
+ db.refresh(t)
288
+ db.close()
289
+ return task_db_list
290
+
291
+
292
+ async def background_collect_pip(
293
+ state_id: int,
294
+ venv_path: Path,
295
+ task_pkg: _TaskCollectPip,
296
+ ) -> None:
297
+ """
298
+ Install package and collect tasks
299
+
300
+ Install a python package and collect the tasks it provides according to
301
+ the manifest.
302
+
303
+ In case of error, copy the log into the state and delete the package
304
+ directory.
305
+ """
306
+ logger_name = task_pkg.package.replace("/", "_")
307
+ logger = set_logger(
308
+ logger_name=logger_name,
309
+ log_file_path=get_log_path(venv_path),
310
+ )
311
+ logger.debug("Start background task collection")
312
+ for key, value in task_pkg.dict(exclude={"package_manifest"}).items():
313
+ logger.debug(f"{key}: {value}")
314
+
315
+ with next(get_sync_db()) as db:
316
+ state: CollectionStateV2 = db.get(CollectionStateV2, state_id)
317
+ data = TaskCollectStatusV2(**state.data)
318
+ data.info = None
319
+
320
+ try:
321
+ # install
322
+ logger.debug("Task-collection status: installing")
323
+ data.status = "installing"
324
+
325
+ state.data = data.sanitised_dict()
326
+ db.merge(state)
327
+ db.commit()
328
+ task_list = await create_package_environment_pip(
329
+ venv_path=venv_path,
330
+ task_pkg=task_pkg,
331
+ logger_name=logger_name,
332
+ )
333
+
334
+ # collect
335
+ logger.debug("Task-collection status: collecting")
336
+ data.status = "collecting"
337
+ state.data = data.sanitised_dict()
338
+ db.merge(state)
339
+ db.commit()
340
+ tasks = await _insert_tasks(task_list=task_list, db=db)
341
+
342
+ # finalise
343
+ logger.debug("Task-collection status: finalising")
344
+ collection_path = get_collection_path(venv_path)
345
+ data.task_list = [
346
+ TaskReadV2(**task.model_dump()) for task in tasks
347
+ ]
348
+ with collection_path.open("w") as f:
349
+ json.dump(data.sanitised_dict(), f, indent=2)
350
+
351
+ # Update DB
352
+ data.status = "OK"
353
+ data.log = get_collection_log(venv_path)
354
+ state.data = data.sanitised_dict()
355
+ db.merge(state)
356
+ db.commit()
357
+
358
+ # Write last logs to file
359
+ logger.debug("Task-collection status: OK")
360
+ logger.info("Background task collection completed successfully")
361
+ close_logger(logger)
362
+ db.close()
363
+
364
+ except Exception as e:
365
+ # Write last logs to file
366
+ logger.debug("Task-collection status: fail")
367
+ logger.info(f"Background collection failed. Original error: {e}")
368
+ close_logger(logger)
369
+
370
+ # Update db
371
+ data.status = "fail"
372
+ data.info = f"Original error: {e}"
373
+ data.log = get_collection_log(venv_path)
374
+ state.data = data.sanitised_dict()
375
+ db.merge(state)
376
+ db.commit()
377
+ db.close()
378
+
379
+ # Delete corrupted package dir
380
+ logger.info(f"Now deleting temporary folder {venv_path}")
381
+ shell_rmtree(venv_path)
@@ -0,0 +1,14 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ from fractal_server.app.schemas.v2 import TaskCollectStatusV2
5
+ from fractal_server.tasks.utils import get_absolute_venv_path
6
+ from fractal_server.tasks.utils import get_collection_path
7
+
8
+
9
+ def get_collection_data(venv_path: Path) -> TaskCollectStatusV2:
10
+ package_path = get_absolute_venv_path(venv_path)
11
+ collection_path = get_collection_path(package_path)
12
+ with collection_path.open() as f:
13
+ data = json.load(f)
14
+ return TaskCollectStatusV2(**data)
fractal_server/urls.py ADDED
@@ -0,0 +1,13 @@
1
+ from os.path import normpath
2
+
3
+
4
+ def normalize_url(url: str) -> str:
5
+ if url.startswith("/"):
6
+ return normpath(url)
7
+ elif url.startswith("s3"):
8
+ # It would be better to have a NotImplementedError
9
+ # but Pydantic Validation + FastAPI require
10
+ # ValueError, TypeError or AssertionError
11
+ raise ValueError("S3 handling not implemented yet")
12
+ else:
13
+ raise ValueError("URLs must begin with '/' or 's3'.")
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fractal-server
3
- Version: 1.4.10
3
+ Version: 2.0.0
4
4
  Summary: Server component of the Fractal analytics platform
5
5
  Home-page: https://github.com/fractal-analytics-platform/fractal-server
6
6
  License: BSD-3-Clause
7
- Author: Jacopo Nespolo
8
- Author-email: jacopo.nespolo@exact-lab.it
7
+ Author: Tommaso Comparin
8
+ Author-email: tommaso.comparin@exact-lab.it
9
9
  Requires-Python: >=3.9,<4.0
10
10
  Classifier: License :: OSI Approved :: BSD License
11
11
  Classifier: Programming Language :: Python :: 3
@@ -16,21 +16,21 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Provides-Extra: gunicorn
17
17
  Provides-Extra: postgres
18
18
  Requires-Dist: aiosqlite (>=0.19.0,<0.20.0)
19
- Requires-Dist: alembic (>=1.9.1,<2.0.0)
19
+ Requires-Dist: alembic (>=1.13.1,<2.0.0)
20
20
  Requires-Dist: asyncpg (>=0.29.0,<0.30.0) ; extra == "postgres"
21
21
  Requires-Dist: bcrypt (==4.0.1)
22
- Requires-Dist: cloudpickle (>=2.2.1,<2.3.0)
22
+ Requires-Dist: cloudpickle (>=3.0.0,<3.1.0)
23
23
  Requires-Dist: clusterfutures (>=0.5,<0.6)
24
- Requires-Dist: fastapi (>=0.109.0,<0.110.0)
24
+ Requires-Dist: fastapi (>=0.110.0,<0.111.0)
25
25
  Requires-Dist: fastapi-users[oauth] (>=12.1.0,<13.0.0)
26
- Requires-Dist: gunicorn (>=21.2.0,<22.0.0) ; extra == "gunicorn"
26
+ Requires-Dist: gunicorn (>=21.2,<23.0) ; extra == "gunicorn"
27
27
  Requires-Dist: packaging (>=23.2,<24.0)
28
28
  Requires-Dist: psycopg2 (>=2.9.5,<3.0.0) ; extra == "postgres"
29
29
  Requires-Dist: pydantic (>=1.10.8,<2)
30
- Requires-Dist: python-dotenv (>=0.21.0,<0.22.0)
30
+ Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
31
31
  Requires-Dist: sqlalchemy[asyncio] (>=2.0.23,<2.1)
32
- Requires-Dist: sqlmodel (>=0.0.14,<0.0.15)
33
- Requires-Dist: uvicorn (>=0.27.0,<0.28.0)
32
+ Requires-Dist: sqlmodel (>=0.0.16,<0.0.17)
33
+ Requires-Dist: uvicorn (>=0.29.0,<0.30.0)
34
34
  Project-URL: Changelog, https://github.com/fractal-analytics-platform/fractal-server/blob/main/CHANGELOG.md
35
35
  Project-URL: Documentation, https://fractal-analytics-platform.github.io/fractal-server
36
36
  Project-URL: Repository, https://github.com/fractal-analytics-platform/fractal-server
@@ -0,0 +1,169 @@
1
+ fractal_server/__init__.py,sha256=ZVQUK1WTLwP7diwqSLF80ZrIglm2xzeMYk5HrWsXtQc,22
2
+ fractal_server/__main__.py,sha256=CocbzZooX1UtGqPi55GcHGNxnrJXFg5tUU5b3wyFCyo,4958
3
+ fractal_server/alembic.ini,sha256=MWwi7GzjzawI9cCAK1LW7NxIBQDUqD12-ptJoq5JpP0,3153
4
+ fractal_server/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ fractal_server/app/db/__init__.py,sha256=WZEVfdJAX7ZyBM1ngfEGeqWWcjK_NygtCbawpmbwGpU,4042
6
+ fractal_server/app/models/__init__.py,sha256=FRRDJkx7LgPaUqSp8IV7qevu_VE2dt0-fQtQruHFaVo,267
7
+ fractal_server/app/models/linkuserproject.py,sha256=eQaourbGRshvlMVlKzLYJKHEjfsW1CbWws9yW4eHXhA,567
8
+ fractal_server/app/models/security.py,sha256=UG9wCVA5GRSyHrYEFhH8lIF1hXykxsr9LSi8_dFToMY,3378
9
+ fractal_server/app/models/v1/__init__.py,sha256=qUlUGnWFaIm3aBXfUuLdhcW9f_s1VzAEuypr31zvHGo,458
10
+ fractal_server/app/models/v1/dataset.py,sha256=99GDgt7njx8yYQApkImqp_7bHA5HH3ElvbR6Oyj9kVI,2017
11
+ fractal_server/app/models/v1/job.py,sha256=QLGXcWdVRHaUHQNDapYYlLpEfw4K7QyD8TmcwhrWw2o,3304
12
+ fractal_server/app/models/v1/project.py,sha256=sDmAFLOBK5o4dLrwsIN681JcT5J1rzoUNTV9QVqwnA8,859
13
+ fractal_server/app/models/v1/state.py,sha256=ew7xw3iPzBwUnPlzmsOEMiPbPEMsJn_TyZ5cK93jBRQ,1095
14
+ fractal_server/app/models/v1/task.py,sha256=3xZqNeFYUqslh8ddMSXF2nO4nIiOD8T5Ij37wY20kss,2782
15
+ fractal_server/app/models/v1/workflow.py,sha256=dnY5eMaOe3oZv8arn00RNX9qVkBtTLG-vYdWXcQuyo4,3950
16
+ fractal_server/app/models/v2/__init__.py,sha256=uLzdInqATSwi0bS_V4vKB-TqFrOFaXuxCAbU73c0f24,473
17
+ fractal_server/app/models/v2/collection_state.py,sha256=nxb042i8tt8rCpmgbFJoBCYWU-34m0HdUfO9YurTp8k,588
18
+ fractal_server/app/models/v2/dataset.py,sha256=-7sxHEw4IIAvF_uSan7tA3o8hvoakBkQ0SRvqS2iOQU,1455
19
+ fractal_server/app/models/v2/job.py,sha256=ypJmN-qspkKBGhBG7Mt-HypSQqcQ2EmB4Bzzb2-y550,1535
20
+ fractal_server/app/models/v2/project.py,sha256=CqDEKzdVxmFDMee6DnVOyX7WGmdn-dQSLSekzw_OLUc,817
21
+ fractal_server/app/models/v2/task.py,sha256=9ZPhug3VWyeqgT8wQ9_8ZXQ2crSiiicRipxrxTslOso,3257
22
+ fractal_server/app/models/v2/workflow.py,sha256=YBgFGCziUgU0aJ5EM3Svu9W2c46AewZO9VBlFCHiSps,1069
23
+ fractal_server/app/models/v2/workflowtask.py,sha256=3jEkObsSnlI05Pur_dSsXYdJxRqPL60Z7tK5-EJLOks,1532
24
+ fractal_server/app/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ fractal_server/app/routes/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ fractal_server/app/routes/admin/v1.py,sha256=uMupmRkicaoWazX8qSX5fgh00O3MbuSfim8QayP6NkE,13996
27
+ fractal_server/app/routes/admin/v2.py,sha256=T8-bGAL25on-ntZx_Msz9j5jq6NGhkjVl1jp3eRJUbw,9830
28
+ fractal_server/app/routes/api/__init__.py,sha256=EVyZrEq3I_1643QGTPCC5lgCp4xH_auYbrFfogTm4pc,315
29
+ fractal_server/app/routes/api/v1/__init__.py,sha256=Y2HQdG197J0a7DyQEE2jn53IfxD0EHGhzK1I2JZuEck,958
30
+ fractal_server/app/routes/api/v1/_aux_functions.py,sha256=KoSefKiBXximu0df4fJ3l9bKsGaLO8rb3z6xhD8PWj4,11973
31
+ fractal_server/app/routes/api/v1/dataset.py,sha256=HRE-8vPmVkeXf7WFYkI19mDtbY-iJZeJ7PmMiV0LMgY,16923
32
+ fractal_server/app/routes/api/v1/job.py,sha256=NwXyhvvzdPDor0ts8Im__9-I0P1H943s4NXIRgaz7PM,5436
33
+ fractal_server/app/routes/api/v1/project.py,sha256=4wlxcc-bR45bns6Yy0WyjA9Qv9eiMscATLZKjVhSd1k,15777
34
+ fractal_server/app/routes/api/v1/task.py,sha256=udbKnenzc-Q10elYCVB9JmOPWATraa9tZi0AaByvWo0,6129
35
+ fractal_server/app/routes/api/v1/task_collection.py,sha256=mFaYyCWtCPRqvs3j6zx_zaiDXn31Uzoa7UHZS-Lu_L0,8882
36
+ fractal_server/app/routes/api/v1/workflow.py,sha256=7r9IoIevg_rvYCrerMOsIsUabSOQatxdPCfLdkP0dRs,10942
37
+ fractal_server/app/routes/api/v1/workflowtask.py,sha256=qcHQlzlSFf_k8gtId-mA3tnyzgSR7i1m7pvR4R86blE,5582
38
+ fractal_server/app/routes/api/v2/__init__.py,sha256=UNgODxoEXfQpQDjvsnMvHaUWbZOrcHhEXNisLcU-0tE,1487
39
+ fractal_server/app/routes/api/v2/_aux_functions.py,sha256=IL1JKVqRcGfqiVbptDzpMKqi9QTYDYCCcsqIG0x0Nl8,14301
40
+ fractal_server/app/routes/api/v2/dataset.py,sha256=_HjKNP9XsMGoqyubGdF2ZyeW7vXC3VdK_0_TaUxgIF0,8248
41
+ fractal_server/app/routes/api/v2/images.py,sha256=4r_HblPWyuKSZSJZfn8mbDaLv1ncwZU0gWdKneZcNG4,7894
42
+ fractal_server/app/routes/api/v2/job.py,sha256=BtaxErBDbLwjY2zgGD1I6eRpsffoMonifcS1CMEXmLU,5325
43
+ fractal_server/app/routes/api/v2/project.py,sha256=qyvizYZ4aUFgF3tGdfp4z8AwWgfo19N_KbFEljfUaC8,5594
44
+ fractal_server/app/routes/api/v2/status.py,sha256=3bqQejJ3TnIMan5wK6jr9sv4ypsQr9WWU8xqlvTgDCE,5739
45
+ fractal_server/app/routes/api/v2/submit.py,sha256=lbPTZKemoRjypcpExi-Yz9fIiPdv9OIjFeUu9yuILA4,6889
46
+ fractal_server/app/routes/api/v2/task.py,sha256=gJ0LruSk-Q1iMw8ZOX8C0wrZ4S4DGlQTr_5SdJJud0Q,7130
47
+ fractal_server/app/routes/api/v2/task_collection.py,sha256=wHkPkQKnvXEzidywuJqLe8QB_xjlHUqzPgsitXydNkU,8961
48
+ fractal_server/app/routes/api/v2/task_legacy.py,sha256=P_VJv9v0yzFUBuS-DQHhMVSOe20ecGJJcFBqiiFciOM,1628
49
+ fractal_server/app/routes/api/v2/workflow.py,sha256=sw-1phO_rrmDAcWX9Zqb9M8SfrWF78-02AuLB1-D1PU,11845
50
+ fractal_server/app/routes/api/v2/workflowtask.py,sha256=l4eTD5IIun5cOdYzsxh3ajmnOISaSccYA_mVf15Cjtw,8802
51
+ fractal_server/app/routes/auth.py,sha256=Xv80iqdyfY3lyicYs2Y8B6zEDEnyUu_H6_6psYtv3R4,4885
52
+ fractal_server/app/routes/aux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ fractal_server/app/routes/aux/_job.py,sha256=7OP3B_FqYJUQ8hVn-7G8oYEEaZrM4hxLF9FoSyjudTo,1251
54
+ fractal_server/app/routes/aux/_runner.py,sha256=psW6fsoo_VrAHrD5UQPbqFYikCp0m16VRymC-U1yUTk,675
55
+ fractal_server/app/runner/.gitignore,sha256=ytzN_oyHWXrGU7iFAtoHSTUbM6Rn6kG0Zkddg0xZk6s,16
56
+ fractal_server/app/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ fractal_server/app/runner/async_wrap.py,sha256=_O6f8jftKYXG_DozkmlrDBhoiK9QhE9MablOyECq2_M,829
58
+ fractal_server/app/runner/components.py,sha256=ZF8ct_Ky5k8IAcrmpYOZ-bc6OBgdELEighYVqFDEbZg,119
59
+ fractal_server/app/runner/exceptions.py,sha256=_qZ_t8O4umAdJ1ikockiF5rDJuxnEskrGrLjZcnQl7A,4159
60
+ fractal_server/app/runner/executors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
+ fractal_server/app/runner/executors/slurm/__init__.py,sha256=Cjn1rYvljddi96tAwS-qqGkNfOcfPzjChdaEZEObCcM,65
62
+ fractal_server/app/runner/executors/slurm/_batching.py,sha256=1P6CgrAOCK9u_EvNFTumcQ-PcZMpocCaSAyNr0YB1js,8841
63
+ fractal_server/app/runner/executors/slurm/_check_jobs_status.py,sha256=8d29a7DQ2xoWxoFQCnFfTpHER-qBX8mEatl4Dw5HU_o,1908
64
+ fractal_server/app/runner/executors/slurm/_executor_wait_thread.py,sha256=J3tjAx33nBgW4eHAXDte7hDs7Oe9FLEZaElEt8inrbg,4421
65
+ fractal_server/app/runner/executors/slurm/_slurm_config.py,sha256=rF37XDImX1QoWx37MC5hSM9AuY_KfHU5gaWwN4vl4Zk,15552
66
+ fractal_server/app/runner/executors/slurm/_subprocess_run_as_user.py,sha256=8CCtxWCuB5UDst3C_WJxBU77xwPrpDyq7iMCZMnodXU,5123
67
+ fractal_server/app/runner/executors/slurm/executor.py,sha256=O9h6ZPAKM95BUJrZkHCdFJZrw2zR2XmxeB5fCoGp97w,44451
68
+ fractal_server/app/runner/executors/slurm/remote.py,sha256=wLziIsGdSMiO-jIXM8x77JRK82g_2hx0iBKTiMghuIo,5852
69
+ fractal_server/app/runner/filenames.py,sha256=9lwu3yB4C67yiijYw8XIKaLFn3mJUt6_TCyVFM_aZUQ,206
70
+ fractal_server/app/runner/set_start_and_last_task_index.py,sha256=-q4zVybAj8ek2XlbENKlfOAJ39hT_zoJoZkqzDqiAMY,1254
71
+ fractal_server/app/runner/task_files.py,sha256=b5aRDi35QemBQnHT_AU6L_IPJJU_k_f5sJn-JXzkzy0,3180
72
+ fractal_server/app/runner/v1/__init__.py,sha256=Uqf9smd4G9JCunXOsJ0U_DJyhYvl8TwItY3TbDLBLMc,13620
73
+ fractal_server/app/runner/v1/_common.py,sha256=2-NScI-7qCIw14Od90so1onw-psIt8x1kx6EXq489Vk,21246
74
+ fractal_server/app/runner/v1/_local/__init__.py,sha256=ZcWftuGRLmN8-S6QZXm6FhNehsxwmwZRhuRv-a7zA6s,6839
75
+ fractal_server/app/runner/v1/_local/_local_config.py,sha256=hM7SPxR07luXPcXdrWXRpEB2uOyjSSRUdqW3QBKJn9c,3147
76
+ fractal_server/app/runner/v1/_local/_submit_setup.py,sha256=kvNPT7ey2mEamORzPMMVThbFHtzZcSr-0A9tYw9uVDA,1493
77
+ fractal_server/app/runner/v1/_local/executor.py,sha256=QrJlD77G6q4WohoJQO7XXbvi2RlCUsNvMnPDEZIoAqA,3620
78
+ fractal_server/app/runner/v1/_slurm/__init__.py,sha256=KN98RO8E3EG4MLNFa--D3DilRHjUyHrVicC6pHtu5L0,10853
79
+ fractal_server/app/runner/v1/_slurm/_submit_setup.py,sha256=llTgSOCnCVMvm7Q0SoVpLZshorAOZZUDz927ij0LZEA,2738
80
+ fractal_server/app/runner/v1/_slurm/get_slurm_config.py,sha256=6TLWQon8hSicsD7c3yXK4P9xeId0s_H3HOOeMUVGVss,5977
81
+ fractal_server/app/runner/v1/common.py,sha256=_L-vjLnWato80VdlB_BFN4G8P4jSM07u-5cnl1T3S34,3294
82
+ fractal_server/app/runner/v1/handle_failed_job.py,sha256=bHzScC_aIlU3q-bQxGW6rfWV4xbZ2tho_sktjsAs1no,4684
83
+ fractal_server/app/runner/v2/__init__.py,sha256=RwIOSLCChMZWHix5QuUNRPtRwgf1UmFDk3YufRCTOoc,12482
84
+ fractal_server/app/runner/v2/_local/__init__.py,sha256=Q1s-DwXleUq6w1ZNv6tlh3tZv6cyBqxB_hMvZlqVYaM,5881
85
+ fractal_server/app/runner/v2/_local/_local_config.py,sha256=lR0Js-l63mQUzN9hK0HkfdLsrTf-W6GHvPvbPC64amY,3630
86
+ fractal_server/app/runner/v2/_local/_submit_setup.py,sha256=deagsLSy6A3ZHKaSDcQqrdvbQVM3i4kgyTcbVc0tC5U,1614
87
+ fractal_server/app/runner/v2/_local/executor.py,sha256=QrJlD77G6q4WohoJQO7XXbvi2RlCUsNvMnPDEZIoAqA,3620
88
+ fractal_server/app/runner/v2/_slurm/__init__.py,sha256=srxn5-KdQxqD8cWJmOJlSoctbXYlyCMM249xWGY9bhI,4409
89
+ fractal_server/app/runner/v2/_slurm/_submit_setup.py,sha256=tsZHQdVy3VxENMdsBzHltrVWzugBppq0cFrHtaVzoUA,2793
90
+ fractal_server/app/runner/v2/_slurm/get_slurm_config.py,sha256=I_lOS75iGYyJ74-gNwwcPadvZ9vI9HYe04WMln5GJ5Q,6726
91
+ fractal_server/app/runner/v2/deduplicate_list.py,sha256=-imwO7OB7ATADEnqVbTElUwoY0YIJCTf_SbWJNN9OZg,639
92
+ fractal_server/app/runner/v2/handle_failed_job.py,sha256=M1r3dnrbUMo_AI2qjaVuGhieMAyLh5gcvB10YOBpjvI,5415
93
+ fractal_server/app/runner/v2/merge_outputs.py,sha256=IHuHqbKmk97K35BFvTrKVBs60z3e_--OzXTnsvmA02c,1281
94
+ fractal_server/app/runner/v2/runner.py,sha256=pZDRYXibPs6lYz8hg-F7KbibR_cl0sjCa5s9yaFE_-s,14160
95
+ fractal_server/app/runner/v2/runner_functions.py,sha256=jwLfIL1gdmL-KqSKb-5CDG-g7rQYZdywn24bJ92R2qI,11067
96
+ fractal_server/app/runner/v2/runner_functions_low_level.py,sha256=nPxmoSTIAQRwEf8iwfCdwTq4Eo3eDAHcgGn3GejPgqk,3710
97
+ fractal_server/app/runner/v2/task_interface.py,sha256=myS-kT0DsJ8xIJZBVEzgD8g54VbiwL6i7Im3e1zcVHQ,1866
98
+ fractal_server/app/runner/v2/v1_compat.py,sha256=t0ficzAHUFaaeI56nqTb4YEKxfARF7L9Y6ijtJCwjP8,912
99
+ fractal_server/app/schemas/__init__.py,sha256=jiIf54owztXupv3PO6Ilh0qcrkh2RUzKq4bcEFqEfc4,40
100
+ fractal_server/app/schemas/_validators.py,sha256=1dTOYr1IZykrxuQSV2-zuEMZbKe_nGwrfS7iUrsh-sE,3461
101
+ fractal_server/app/schemas/state.py,sha256=t4XM04aqxeluh8MfvD7LfEc-8-dOmUVluZHhLsfxxkc,692
102
+ fractal_server/app/schemas/user.py,sha256=rE8WgBz-ceVUs0Sz2ZwcjUrSTZTnS0ys5SBtD2XD9r8,3113
103
+ fractal_server/app/schemas/v1/__init__.py,sha256=terWiFLKJ0QU-y3PG3hXNYdpxGTffZTlwrwJ8LfQ3FM,1809
104
+ fractal_server/app/schemas/v1/applyworkflow.py,sha256=uuIh7fHlHEL4yLqL-dePI6-nfCsqgBYATmht7w_KITw,4302
105
+ fractal_server/app/schemas/v1/dataset.py,sha256=n71lNUO3JLy2K3IM9BZM2Fk1EnKQOTU7pm2s2rJ1FGY,3444
106
+ fractal_server/app/schemas/v1/dumps.py,sha256=67VXnyLh_0Ufo7rPM2jZ9P9rk0CnYcVAkilx_cLX6sg,1274
107
+ fractal_server/app/schemas/v1/manifest.py,sha256=Yht7guhs0Pcl2U0RMOCbI_UHBZ9YO_YU0H8hxACx3TY,3829
108
+ fractal_server/app/schemas/v1/project.py,sha256=TO2TjI4m9FO-A9IB9lUCld7E4Ld0k4MacLcyA9j6Qi4,1218
109
+ fractal_server/app/schemas/v1/task.py,sha256=7BxOZ_qoRQ8n3YbQpDvB7VMcxB5fSYQmR5RLIWhuJ5U,3704
110
+ fractal_server/app/schemas/v1/task_collection.py,sha256=uvq9bcMaGD_qHsh7YtcpoSAkVAbw12eY4DocIO3MKOg,3057
111
+ fractal_server/app/schemas/v1/workflow.py,sha256=tuOs5E5Q_ozA8if7YPZ07cQjzqB_QMkBS4u92qo4Ro0,4618
112
+ fractal_server/app/schemas/v2/__init__.py,sha256=IssDWR6q_mgNkaAxfhSnEZZLZRZIqOsr9SM7RvN1IsY,1852
113
+ fractal_server/app/schemas/v2/dataset.py,sha256=dLT52tV4dSf2HrFNak4vdQEn8PT_04IUrGnd2z-AXIU,2599
114
+ fractal_server/app/schemas/v2/dumps.py,sha256=IpIT_2KxJd7qTgW2NllDknGeP7vBAJDfyz1I5p3TytU,2023
115
+ fractal_server/app/schemas/v2/job.py,sha256=zfF9K3v4jWUJ7M482ta2CkqUJ4tVT4XfVt60p9IRhP0,3250
116
+ fractal_server/app/schemas/v2/manifest.py,sha256=N37IWohcfO3_y2l8rVM0h_1nZq7m4Izxk9iL1vtwBJw,6243
117
+ fractal_server/app/schemas/v2/project.py,sha256=u7S4B-bote1oGjzAGiZ-DuQIyeRAGqJsI71Tc1EtYE0,736
118
+ fractal_server/app/schemas/v2/status.py,sha256=SQaUpQkjFq5c5k5J4rOjNhuQaDOEg8lksPhkKmPU5VU,332
119
+ fractal_server/app/schemas/v2/task.py,sha256=7IfxiZkaVqlARy7WYE_H8m7j_IEcuQaZORUrs6b5YuY,4672
120
+ fractal_server/app/schemas/v2/task_collection.py,sha256=sY29NQfJrbjiidmVkVjSIH-20wIsmh7G1QOdr05KoDQ,3171
121
+ fractal_server/app/schemas/v2/workflow.py,sha256=Zzx3e-qgkH8le0FUmAx9UrV5PWd7bj14PPXUh_zgZXM,1827
122
+ fractal_server/app/schemas/v2/workflowtask.py,sha256=atVuVN4aXsVEOmSd-vyg-8_8OnPmqx-gT75rXcn_AlQ,6552
123
+ fractal_server/app/security/__init__.py,sha256=wxosoHc3mJYPCdPMyWnRD8w_2OgnKYp2aDkdmwrZh5k,11203
124
+ fractal_server/config.py,sha256=CA8ASObADaME5chDiBXawAJZ3MvjTRpCKP0jvdYtSh8,15080
125
+ fractal_server/data_migrations/README.md,sha256=_3AEFvDg9YkybDqCLlFPdDmGJvr6Tw7HRI14aZ3LOIw,398
126
+ fractal_server/images/__init__.py,sha256=xO6jTLE4EZKO6cTDdJsBmK9cdeh9hFTaSbSuWgQg7y4,196
127
+ fractal_server/images/models.py,sha256=9ipU5h4N6ogBChoB-2vHoqtL0TXOHCv6kRR-fER3mkM,4167
128
+ fractal_server/images/tools.py,sha256=gxeniYy4Z-cp_ToK2LHPJUTVVUUrdpogYdcBUvBuLiY,2209
129
+ fractal_server/logger.py,sha256=95duXY8eSxf1HWg0CVn8SUGNzgJw9ZR0FlapDDF6WAY,3924
130
+ fractal_server/main.py,sha256=7CpwPfCsHxBAo5fWuXPCsYOFCpbBI0F7Z0jsgCQdou8,3001
131
+ fractal_server/migrations/README,sha256=4rQvyDfqodGhpJw74VYijRmgFP49ji5chyEemWGHsuw,59
132
+ fractal_server/migrations/env.py,sha256=bsl0HGZpjhommztgcs7wQ94sJzI1Orgnij97K8P_uyo,2630
133
+ fractal_server/migrations/script.py.mako,sha256=oMXw9LC3zRbinWWPPDgeZ4z9FJrV2zhRWiYdS5YgNbI,526
134
+ fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py,sha256=-wHe-fOffmYeAm0JXVl_lxZ7hhDkaEVqxgxpHkb_uL8,954
135
+ fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py,sha256=Mob8McGYAcmgvrseyyYOa54E6Gsgr-4SiGdC-r9O4_A,1157
136
+ fractal_server/migrations/versions/50a13d6138fd_initial_schema.py,sha256=zwXegXs9J40eyCWi3w0c_iIBVJjXNn4VdVnQaT3KxDg,8770
137
+ fractal_server/migrations/versions/5bf02391cfef_v2.py,sha256=axhNkr_H6R4rRbY7oGYazNbFvPXeSyBDWFVbKNmiqs8,8433
138
+ fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py,sha256=Q-DsMzG3IcUV2Ol1dhJWosDvKERamBE6QvA2zzS5zpQ,1632
139
+ fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py,sha256=mbWuCkTpRAdGbRhW7lhXs_e5S6O37UAcCN6JfoY5H8A,1353
140
+ fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py,sha256=NSCuhANChsg76vBkShBl-9tQ4VEHubOjtAv1etHhlvY,2684
141
+ fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py,sha256=6pgODDtyAxevZvAJBj9IJ41inhV1RpwbpZr_qfPPu1A,1115
142
+ fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py,sha256=eKTZm3EgUgapXBxO0RuHkEfTKic-TZG3ADaMpGLuc0k,1057
143
+ fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py,sha256=0im6TxDr53sKKcjiPgeH4ftVRGnRXZSh2lPbRQ1Ir9w,883
144
+ fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py,sha256=4l1AHGUsa0ONoJVZlr3fTXw_xbbQ8O7wlD92Az2aRfM,1849
145
+ fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py,sha256=ekDUML7ILpmdoqEclKbEUdyLi4uw9HSG_sTjG2hp_JE,867
146
+ fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py,sha256=6cHEZFuTXiQg9yu32Y3RH1XAl71av141WQ6UMbiITIg,949
147
+ fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py,sha256=lOggSvzGWqQvnxxFuSM6W50Ui49R918A-uBuiZJ0pNM,963
148
+ fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py,sha256=jilQW3QIqYQ4Q6hCnUiG7UtNMpA41ujqrB3tPFiPM1Q,1221
149
+ fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py,sha256=9BwqUS9Gf7UW_KjrzHbtViC880qhD452KAytkHWWZyk,746
150
+ fractal_server/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
151
+ fractal_server/syringe.py,sha256=3qSMW3YaMKKnLdgnooAINOPxnCOxP7y2jeAQYB21Gdo,2786
152
+ fractal_server/tasks/__init__.py,sha256=kadmVUoIghl8s190_Tt-8f-WBqMi8u8oU4Pvw39NHE8,23
153
+ fractal_server/tasks/endpoint_operations.py,sha256=D1WSJd8dIfIumKezon1NYX5a0QNPqqlbj9uRq-ur9CQ,5379
154
+ fractal_server/tasks/utils.py,sha256=R1_SKfXTwveT7CJJOrvkwi0vNpr9MBIiNh7qv8EK3Wc,3278
155
+ fractal_server/tasks/v1/_TaskCollectPip.py,sha256=16Gn8lVYHBuwNLBHdcdx0X8s9QXXsbfPwSzcCcM6fRg,3775
156
+ fractal_server/tasks/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
+ fractal_server/tasks/v1/background_operations.py,sha256=I-D4SaG56UMkoH7dNy5CzbEsAjySCPc7gQc-U14phKk,11731
158
+ fractal_server/tasks/v1/get_collection_data.py,sha256=bi9tuApLgoKZNMIG1kR4GoKI9S6Y040gFfNQapw4ikM,502
159
+ fractal_server/tasks/v2/_TaskCollectPip.py,sha256=QeCqXDgOnMjk3diVlC5bgGEywyQjYFm5637Rke49vJY,3775
160
+ fractal_server/tasks/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
+ fractal_server/tasks/v2/background_operations.py,sha256=fUukEA-zFjUDhxgI3oO_Bvy7FinaYFaydciASOIbL3w,12842
162
+ fractal_server/tasks/v2/get_collection_data.py,sha256=Qhf2T_aaqAfqu9_KpUSlXsS7EJoZQbEPEreHHa2jco8,502
163
+ fractal_server/urls.py,sha256=5o_qq7PzKKbwq12NHSQZDmDitn5RAOeQ4xufu-2v9Zk,448
164
+ fractal_server/utils.py,sha256=b7WwFdcFZ8unyT65mloFToYuEDXpQoHRcmRNqrhd_dQ,2115
165
+ fractal_server-2.0.0.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
166
+ fractal_server-2.0.0.dist-info/METADATA,sha256=C_FyIU-WDz6RrAgnOPpQvOs2yMcsRF98l9prONt6l9Q,4202
167
+ fractal_server-2.0.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
168
+ fractal_server-2.0.0.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
169
+ fractal_server-2.0.0.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- test*
2
- mypy-scan