fractal-server 2.13.1__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.
- fractal_server/__init__.py +1 -1
- fractal_server/__main__.py +3 -1
- fractal_server/app/models/linkusergroup.py +6 -2
- fractal_server/app/models/v2/__init__.py +7 -1
- fractal_server/app/models/v2/dataset.py +1 -11
- fractal_server/app/models/v2/history.py +78 -0
- fractal_server/app/models/v2/job.py +10 -3
- fractal_server/app/models/v2/task_group.py +2 -2
- fractal_server/app/models/v2/workflow.py +1 -1
- fractal_server/app/models/v2/workflowtask.py +1 -1
- fractal_server/app/routes/admin/v2/accounting.py +18 -28
- fractal_server/app/routes/admin/v2/task.py +1 -1
- fractal_server/app/routes/admin/v2/task_group.py +0 -17
- fractal_server/app/routes/api/__init__.py +1 -1
- fractal_server/app/routes/api/v2/__init__.py +8 -2
- fractal_server/app/routes/api/v2/_aux_functions.py +66 -0
- fractal_server/app/routes/api/v2/_aux_functions_history.py +166 -0
- fractal_server/app/routes/api/v2/dataset.py +0 -17
- fractal_server/app/routes/api/v2/history.py +544 -0
- fractal_server/app/routes/api/v2/images.py +31 -43
- fractal_server/app/routes/api/v2/job.py +30 -0
- fractal_server/app/routes/api/v2/project.py +1 -53
- fractal_server/app/routes/api/v2/{status.py → status_legacy.py} +6 -6
- fractal_server/app/routes/api/v2/submit.py +16 -14
- fractal_server/app/routes/api/v2/task.py +3 -10
- fractal_server/app/routes/api/v2/task_collection_custom.py +4 -9
- fractal_server/app/routes/api/v2/task_group.py +0 -17
- fractal_server/app/routes/api/v2/verify_image_types.py +61 -0
- fractal_server/app/routes/api/v2/workflow.py +28 -69
- fractal_server/app/routes/api/v2/workflowtask.py +53 -50
- fractal_server/app/routes/auth/group.py +0 -16
- fractal_server/app/routes/auth/oauth.py +5 -3
- fractal_server/app/routes/pagination.py +47 -0
- fractal_server/app/runner/components.py +0 -3
- fractal_server/app/runner/compress_folder.py +57 -29
- fractal_server/app/runner/exceptions.py +4 -0
- fractal_server/app/runner/executors/base_runner.py +157 -0
- fractal_server/app/runner/{v2/_local/_local_config.py → executors/local/get_local_config.py} +7 -9
- fractal_server/app/runner/executors/local/runner.py +248 -0
- fractal_server/app/runner/executors/{slurm → slurm_common}/_batching.py +1 -1
- fractal_server/app/runner/executors/{slurm → slurm_common}/_slurm_config.py +9 -7
- fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +868 -0
- fractal_server/app/runner/{v2/_slurm_common → executors/slurm_common}/get_slurm_config.py +48 -17
- fractal_server/app/runner/executors/{slurm → slurm_common}/remote.py +36 -47
- fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +134 -0
- fractal_server/app/runner/executors/slurm_ssh/runner.py +268 -0
- fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
- fractal_server/app/runner/executors/{slurm/sudo → slurm_sudo}/_subprocess_run_as_user.py +2 -83
- fractal_server/app/runner/executors/slurm_sudo/runner.py +193 -0
- fractal_server/app/runner/extract_archive.py +1 -3
- fractal_server/app/runner/task_files.py +134 -87
- fractal_server/app/runner/v2/__init__.py +0 -399
- fractal_server/app/runner/v2/_local.py +88 -0
- fractal_server/app/runner/v2/{_slurm_ssh/__init__.py → _slurm_ssh.py} +20 -19
- fractal_server/app/runner/v2/{_slurm_sudo/__init__.py → _slurm_sudo.py} +17 -15
- fractal_server/app/runner/v2/db_tools.py +119 -0
- fractal_server/app/runner/v2/runner.py +206 -95
- fractal_server/app/runner/v2/runner_functions.py +488 -187
- fractal_server/app/runner/v2/runner_functions_low_level.py +40 -43
- fractal_server/app/runner/v2/submit_workflow.py +358 -0
- fractal_server/app/runner/v2/task_interface.py +31 -0
- fractal_server/app/schemas/_validators.py +13 -24
- fractal_server/app/schemas/user.py +10 -7
- fractal_server/app/schemas/user_settings.py +9 -21
- fractal_server/app/schemas/v2/__init__.py +9 -1
- fractal_server/app/schemas/v2/dataset.py +12 -94
- fractal_server/app/schemas/v2/dumps.py +26 -9
- fractal_server/app/schemas/v2/history.py +80 -0
- fractal_server/app/schemas/v2/job.py +15 -8
- fractal_server/app/schemas/v2/manifest.py +14 -7
- fractal_server/app/schemas/v2/project.py +9 -7
- fractal_server/app/schemas/v2/status_legacy.py +35 -0
- fractal_server/app/schemas/v2/task.py +72 -77
- fractal_server/app/schemas/v2/task_collection.py +14 -32
- fractal_server/app/schemas/v2/task_group.py +10 -9
- fractal_server/app/schemas/v2/workflow.py +10 -11
- fractal_server/app/schemas/v2/workflowtask.py +2 -21
- fractal_server/app/security/__init__.py +3 -3
- fractal_server/app/security/signup_email.py +2 -2
- fractal_server/config.py +41 -46
- fractal_server/images/tools.py +23 -0
- fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +50 -0
- fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +250 -0
- fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +41 -0
- fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +36 -0
- fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +39 -0
- fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +120 -0
- fractal_server/ssh/_fabric.py +28 -14
- fractal_server/tasks/v2/local/collect.py +2 -2
- fractal_server/tasks/v2/ssh/collect.py +2 -2
- fractal_server/tasks/v2/templates/2_pip_install.sh +1 -1
- fractal_server/tasks/v2/templates/4_pip_show.sh +1 -1
- fractal_server/tasks/v2/utils_background.py +0 -19
- fractal_server/tasks/v2/utils_database.py +30 -17
- fractal_server/tasks/v2/utils_templates.py +6 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0.dist-info}/METADATA +4 -4
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0.dist-info}/RECORD +106 -96
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0.dist-info}/WHEEL +1 -1
- fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -126
- fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -116
- fractal_server/app/runner/executors/slurm/ssh/executor.py +0 -1386
- fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -71
- fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -130
- fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -1281
- fractal_server/app/runner/v2/_local/__init__.py +0 -132
- fractal_server/app/runner/v2/_local/_submit_setup.py +0 -52
- fractal_server/app/runner/v2/_local/executor.py +0 -100
- fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -83
- fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -83
- fractal_server/app/runner/v2/handle_failed_job.py +0 -59
- fractal_server/app/schemas/v2/status.py +0 -16
- /fractal_server/app/{runner/executors/slurm → history}/__init__.py +0 -0
- /fractal_server/app/runner/executors/{slurm/ssh → local}/__init__.py +0 -0
- /fractal_server/app/runner/executors/{slurm/sudo → slurm_common}/__init__.py +0 -0
- /fractal_server/app/runner/executors/{_job_states.py → slurm_common/_job_states.py} +0 -0
- /fractal_server/app/runner/executors/{slurm → slurm_common}/utils_executors.py +0 -0
- /fractal_server/app/runner/{v2/_slurm_common → executors/slurm_ssh}/__init__.py +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0.dist-info}/LICENSE +0 -0
- {fractal_server-2.13.1.dist-info → fractal_server-2.14.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
"""new history items
|
2
|
+
|
3
|
+
Revision ID: fbce16ff4e47
|
4
|
+
Revises: af1ef1c83c9b
|
5
|
+
Create Date: 2025-03-14 15:25:01.083619
|
6
|
+
|
7
|
+
"""
|
8
|
+
import sqlalchemy as sa
|
9
|
+
import sqlmodel
|
10
|
+
from alembic import op
|
11
|
+
from sqlalchemy.dialects import postgresql
|
12
|
+
|
13
|
+
# revision identifiers, used by Alembic.
|
14
|
+
revision = "fbce16ff4e47"
|
15
|
+
down_revision = "af1ef1c83c9b"
|
16
|
+
branch_labels = None
|
17
|
+
depends_on = None
|
18
|
+
|
19
|
+
|
20
|
+
def upgrade() -> None:
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
22
|
+
op.create_table(
|
23
|
+
"historyrun",
|
24
|
+
sa.Column("id", sa.Integer(), nullable=False),
|
25
|
+
sa.Column("dataset_id", sa.Integer(), nullable=False),
|
26
|
+
sa.Column("workflowtask_id", sa.Integer(), nullable=True),
|
27
|
+
sa.Column(
|
28
|
+
"workflowtask_dump",
|
29
|
+
postgresql.JSONB(astext_type=sa.Text()),
|
30
|
+
nullable=False,
|
31
|
+
),
|
32
|
+
sa.Column(
|
33
|
+
"task_group_dump",
|
34
|
+
postgresql.JSONB(astext_type=sa.Text()),
|
35
|
+
nullable=False,
|
36
|
+
),
|
37
|
+
sa.Column(
|
38
|
+
"timestamp_started", sa.DateTime(timezone=True), nullable=False
|
39
|
+
),
|
40
|
+
sa.Column(
|
41
|
+
"status", sqlmodel.sql.sqltypes.AutoString(), nullable=False
|
42
|
+
),
|
43
|
+
sa.Column("num_available_images", sa.Integer(), nullable=False),
|
44
|
+
sa.ForeignKeyConstraint(
|
45
|
+
["dataset_id"],
|
46
|
+
["datasetv2.id"],
|
47
|
+
name=op.f("fk_historyrun_dataset_id_datasetv2"),
|
48
|
+
ondelete="CASCADE",
|
49
|
+
),
|
50
|
+
sa.ForeignKeyConstraint(
|
51
|
+
["workflowtask_id"],
|
52
|
+
["workflowtaskv2.id"],
|
53
|
+
name=op.f("fk_historyrun_workflowtask_id_workflowtaskv2"),
|
54
|
+
ondelete="SET NULL",
|
55
|
+
),
|
56
|
+
sa.PrimaryKeyConstraint("id", name=op.f("pk_historyrun")),
|
57
|
+
)
|
58
|
+
op.create_table(
|
59
|
+
"historyunit",
|
60
|
+
sa.Column("id", sa.Integer(), nullable=False),
|
61
|
+
sa.Column("history_run_id", sa.Integer(), nullable=False),
|
62
|
+
sa.Column(
|
63
|
+
"logfile", sqlmodel.sql.sqltypes.AutoString(), nullable=True
|
64
|
+
),
|
65
|
+
sa.Column(
|
66
|
+
"status", sqlmodel.sql.sqltypes.AutoString(), nullable=False
|
67
|
+
),
|
68
|
+
sa.Column("zarr_urls", postgresql.ARRAY(sa.String()), nullable=True),
|
69
|
+
sa.ForeignKeyConstraint(
|
70
|
+
["history_run_id"],
|
71
|
+
["historyrun.id"],
|
72
|
+
name=op.f("fk_historyunit_history_run_id_historyrun"),
|
73
|
+
ondelete="CASCADE",
|
74
|
+
),
|
75
|
+
sa.PrimaryKeyConstraint("id", name=op.f("pk_historyunit")),
|
76
|
+
)
|
77
|
+
op.create_table(
|
78
|
+
"historyimagecache",
|
79
|
+
sa.Column(
|
80
|
+
"zarr_url", sqlmodel.sql.sqltypes.AutoString(), nullable=False
|
81
|
+
),
|
82
|
+
sa.Column("dataset_id", sa.Integer(), nullable=False),
|
83
|
+
sa.Column("workflowtask_id", sa.Integer(), nullable=False),
|
84
|
+
sa.Column("latest_history_unit_id", sa.Integer(), nullable=False),
|
85
|
+
sa.ForeignKeyConstraint(
|
86
|
+
["dataset_id"],
|
87
|
+
["datasetv2.id"],
|
88
|
+
name=op.f("fk_historyimagecache_dataset_id_datasetv2"),
|
89
|
+
ondelete="CASCADE",
|
90
|
+
),
|
91
|
+
sa.ForeignKeyConstraint(
|
92
|
+
["latest_history_unit_id"],
|
93
|
+
["historyunit.id"],
|
94
|
+
name=op.f(
|
95
|
+
"fk_historyimagecache_latest_history_unit_id_historyunit"
|
96
|
+
),
|
97
|
+
ondelete="CASCADE",
|
98
|
+
),
|
99
|
+
sa.ForeignKeyConstraint(
|
100
|
+
["workflowtask_id"],
|
101
|
+
["workflowtaskv2.id"],
|
102
|
+
name=op.f("fk_historyimagecache_workflowtask_id_workflowtaskv2"),
|
103
|
+
ondelete="CASCADE",
|
104
|
+
),
|
105
|
+
sa.PrimaryKeyConstraint(
|
106
|
+
"zarr_url",
|
107
|
+
"dataset_id",
|
108
|
+
"workflowtask_id",
|
109
|
+
name=op.f("pk_historyimagecache"),
|
110
|
+
),
|
111
|
+
)
|
112
|
+
# ### end Alembic commands ###
|
113
|
+
|
114
|
+
|
115
|
+
def downgrade() -> None:
|
116
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
117
|
+
op.drop_table("historyimagecache")
|
118
|
+
op.drop_table("historyunit")
|
119
|
+
op.drop_table("historyrun")
|
120
|
+
# ### end Alembic commands ###
|
fractal_server/ssh/_fabric.py
CHANGED
@@ -23,6 +23,18 @@ class FractalSSHTimeoutError(RuntimeError):
|
|
23
23
|
pass
|
24
24
|
|
25
25
|
|
26
|
+
class FractalSSHConnectionError(RuntimeError):
|
27
|
+
pass
|
28
|
+
|
29
|
+
|
30
|
+
class FractalSSHCommandError(RuntimeError):
|
31
|
+
pass
|
32
|
+
|
33
|
+
|
34
|
+
class FractalSSHUnknownError(RuntimeError):
|
35
|
+
pass
|
36
|
+
|
37
|
+
|
26
38
|
logger = set_logger(__name__)
|
27
39
|
|
28
40
|
|
@@ -170,7 +182,6 @@ class FractalSSH(object):
|
|
170
182
|
label="read_remote_json_file",
|
171
183
|
timeout=self.default_lock_timeout,
|
172
184
|
):
|
173
|
-
|
174
185
|
try:
|
175
186
|
with self._sftp_unsafe().open(filepath, "r") as f:
|
176
187
|
data = json.load(f)
|
@@ -263,7 +274,7 @@ class FractalSSH(object):
|
|
263
274
|
cmd: str,
|
264
275
|
allow_char: Optional[str] = None,
|
265
276
|
max_attempts: Optional[int] = None,
|
266
|
-
base_interval: Optional[
|
277
|
+
base_interval: Optional[float] = None,
|
267
278
|
lock_timeout: Optional[int] = None,
|
268
279
|
) -> str:
|
269
280
|
"""
|
@@ -311,7 +322,7 @@ class FractalSSH(object):
|
|
311
322
|
t_1 = time.perf_counter()
|
312
323
|
self.logger.info(
|
313
324
|
f"{prefix} END running '{cmd}' over SSH, "
|
314
|
-
f"elapsed
|
325
|
+
f"elapsed={t_1 - t_0:.3f}"
|
315
326
|
)
|
316
327
|
self.logger.debug("STDOUT:")
|
317
328
|
self.logger.debug(res.stdout)
|
@@ -329,12 +340,16 @@ class FractalSSH(object):
|
|
329
340
|
sleeptime = actual_base_interval**ind_attempt
|
330
341
|
self.logger.warning(
|
331
342
|
f"{prefix} Now sleep {sleeptime:.3f} "
|
332
|
-
"seconds and
|
343
|
+
"seconds and retry."
|
333
344
|
)
|
334
345
|
time.sleep(sleeptime)
|
335
346
|
else:
|
336
347
|
self.logger.error(f"{prefix} Reached last attempt")
|
337
|
-
|
348
|
+
raise FractalSSHConnectionError(
|
349
|
+
f"Reached last attempt "
|
350
|
+
f"({max_attempts=}) for running "
|
351
|
+
f"'{cmd}' over SSH"
|
352
|
+
)
|
338
353
|
except UnexpectedExit as e:
|
339
354
|
# Case 3: Command fails with an actual error
|
340
355
|
error_msg = (
|
@@ -342,18 +357,15 @@ class FractalSSH(object):
|
|
342
357
|
f"Original error:\n{str(e)}."
|
343
358
|
)
|
344
359
|
self.logger.error(error_msg)
|
345
|
-
raise
|
360
|
+
raise FractalSSHCommandError(error_msg)
|
361
|
+
except FractalSSHTimeoutError as e:
|
362
|
+
raise e
|
346
363
|
except Exception as e:
|
347
364
|
self.logger.error(
|
348
365
|
f"Running command `{cmd}` over SSH failed.\n"
|
349
366
|
f"Original Error:\n{str(e)}."
|
350
367
|
)
|
351
|
-
raise e
|
352
|
-
|
353
|
-
raise RuntimeError(
|
354
|
-
f"Reached last attempt ({max_attempts=}) for running "
|
355
|
-
f"'{cmd}' over SSH"
|
356
|
-
)
|
368
|
+
raise FractalSSHUnknownError(f"{type(e)}: {str(e)}")
|
357
369
|
|
358
370
|
def send_file(
|
359
371
|
self,
|
@@ -501,7 +513,8 @@ class FractalSSH(object):
|
|
501
513
|
content: Contents to be written to file.
|
502
514
|
lock_timeout: Timeout for lock acquisition (overrides default).
|
503
515
|
"""
|
504
|
-
|
516
|
+
t_start = time.perf_counter()
|
517
|
+
self.logger.info(f"[write_remote_file] START ({path}).")
|
505
518
|
actual_lock_timeout = self.default_lock_timeout
|
506
519
|
if lock_timeout is not None:
|
507
520
|
actual_lock_timeout = lock_timeout
|
@@ -518,7 +531,8 @@ class FractalSSH(object):
|
|
518
531
|
e=e, message=f"Error in `write_remote_file`, for {path=}."
|
519
532
|
)
|
520
533
|
|
521
|
-
|
534
|
+
elapsed = time.perf_counter() - t_start
|
535
|
+
self.logger.info(f"[write_remote_file] END, {elapsed=} s ({path}).")
|
522
536
|
|
523
537
|
def remote_exists(self, path: str) -> bool:
|
524
538
|
"""
|
@@ -6,7 +6,7 @@ from pathlib import Path
|
|
6
6
|
from tempfile import TemporaryDirectory
|
7
7
|
from typing import Optional
|
8
8
|
|
9
|
-
from ..utils_database import
|
9
|
+
from ..utils_database import create_db_tasks_and_update_task_group_sync
|
10
10
|
from ._utils import _customize_and_run_template
|
11
11
|
from fractal_server.app.db import get_sync_db
|
12
12
|
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
@@ -233,7 +233,7 @@ def collect_local(
|
|
233
233
|
activity = add_commit_refresh(obj=activity, db=db)
|
234
234
|
|
235
235
|
logger.info("create_db_tasks_and_update_task_group - " "start")
|
236
|
-
|
236
|
+
create_db_tasks_and_update_task_group_sync(
|
237
237
|
task_list=task_list,
|
238
238
|
task_group_id=task_group.id,
|
239
239
|
db=db,
|
@@ -6,7 +6,7 @@ from typing import Optional
|
|
6
6
|
|
7
7
|
from ..utils_background import _prepare_tasks_metadata
|
8
8
|
from ..utils_background import fail_and_cleanup
|
9
|
-
from ..utils_database import
|
9
|
+
from ..utils_database import create_db_tasks_and_update_task_group_sync
|
10
10
|
from fractal_server.app.db import get_sync_db
|
11
11
|
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
12
12
|
from fractal_server.app.models.v2 import TaskGroupV2
|
@@ -265,7 +265,7 @@ def collect_ssh(
|
|
265
265
|
logger.info("_prepare_tasks_metadata - end")
|
266
266
|
|
267
267
|
logger.info("create_db_tasks_and_update_task_group - " "start")
|
268
|
-
|
268
|
+
create_db_tasks_and_update_task_group_sync(
|
269
269
|
task_list=task_list,
|
270
270
|
task_group_id=task_group.id,
|
271
271
|
db=db,
|
@@ -25,7 +25,7 @@ echo
|
|
25
25
|
|
26
26
|
# Install package
|
27
27
|
write_log "START install ${INSTALL_STRING}"
|
28
|
-
"$VENVPYTHON" -m pip install
|
28
|
+
"$VENVPYTHON" -m pip install ${FRACTAL_PIP_CACHE_DIR_ARG} "$INSTALL_STRING"
|
29
29
|
write_log "END install ${INSTALL_STRING}"
|
30
30
|
echo
|
31
31
|
|
@@ -20,7 +20,7 @@ echo
|
|
20
20
|
# FIXME: only run pip-show once!
|
21
21
|
|
22
22
|
# Extract information about paths
|
23
|
-
# WARNING: this block will fail for paths which
|
23
|
+
# WARNING: this block will fail for paths which include whitespace characters
|
24
24
|
write_log "START pip show"
|
25
25
|
$VENVPYTHON -m pip show ${PACKAGE_NAME}
|
26
26
|
write_log "END pip show"
|
@@ -3,7 +3,6 @@ from typing import Optional
|
|
3
3
|
from typing import TypeVar
|
4
4
|
|
5
5
|
from sqlalchemy.orm import Session as DBSyncSession
|
6
|
-
from sqlmodel import select
|
7
6
|
|
8
7
|
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
9
8
|
from fractal_server.app.models.v2 import TaskGroupV2
|
@@ -44,24 +43,6 @@ def fail_and_cleanup(
|
|
44
43
|
task_group_activity.log = get_current_log(log_file_path)
|
45
44
|
task_group_activity = add_commit_refresh(obj=task_group_activity, db=db)
|
46
45
|
if task_group_activity.action == TaskGroupActivityActionV2.COLLECT:
|
47
|
-
logger.info(f"Now delete TaskGroupV2 with {task_group.id=}")
|
48
|
-
|
49
|
-
logger.info("Start of TaskGroupActivityV2 cascade operations.")
|
50
|
-
stm = select(TaskGroupActivityV2).where(
|
51
|
-
TaskGroupActivityV2.taskgroupv2_id == task_group.id
|
52
|
-
)
|
53
|
-
res = db.execute(stm)
|
54
|
-
task_group_activity_list = res.scalars().all()
|
55
|
-
for task_group_activity in task_group_activity_list:
|
56
|
-
logger.info(
|
57
|
-
f"Setting TaskGroupActivityV2[{task_group_activity.id}]"
|
58
|
-
".taskgroupv2_id to None."
|
59
|
-
)
|
60
|
-
task_group_activity.taskgroupv2_id = None
|
61
|
-
db.add(task_group_activity)
|
62
|
-
logger.info("End of TaskGroupActivityV2 cascade operations.")
|
63
|
-
logger.info(f"TaskGroupV2 with {task_group.id=} deleted")
|
64
|
-
|
65
46
|
db.delete(task_group)
|
66
47
|
db.commit()
|
67
48
|
reset_logger_handlers(logger)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
1
2
|
from sqlalchemy.orm import Session as DBSyncSession
|
2
3
|
|
3
4
|
from fractal_server.app.models.v2 import TaskGroupV2
|
@@ -5,16 +6,7 @@ from fractal_server.app.models.v2 import TaskV2
|
|
5
6
|
from fractal_server.app.schemas.v2 import TaskCreateV2
|
6
7
|
|
7
8
|
|
8
|
-
def
|
9
|
-
if task.command_non_parallel is None:
|
10
|
-
return "parallel"
|
11
|
-
elif task.command_parallel is None:
|
12
|
-
return "non_parallel"
|
13
|
-
else:
|
14
|
-
return "compound"
|
15
|
-
|
16
|
-
|
17
|
-
def create_db_tasks_and_update_task_group(
|
9
|
+
def create_db_tasks_and_update_task_group_sync(
|
18
10
|
*,
|
19
11
|
task_group_id: int,
|
20
12
|
task_list: list[TaskCreateV2],
|
@@ -31,13 +23,7 @@ def create_db_tasks_and_update_task_group(
|
|
31
23
|
Returns:
|
32
24
|
Updated `TaskGroupV2` object.
|
33
25
|
"""
|
34
|
-
actual_task_list = [
|
35
|
-
TaskV2(
|
36
|
-
**task.model_dump(),
|
37
|
-
type=_get_task_type(task),
|
38
|
-
)
|
39
|
-
for task in task_list
|
40
|
-
]
|
26
|
+
actual_task_list = [TaskV2(**task.model_dump()) for task in task_list]
|
41
27
|
task_group = db.get(TaskGroupV2, task_group_id)
|
42
28
|
task_group.task_list = actual_task_list
|
43
29
|
db.add(task_group)
|
@@ -45,3 +31,30 @@ def create_db_tasks_and_update_task_group(
|
|
45
31
|
db.refresh(task_group)
|
46
32
|
|
47
33
|
return task_group
|
34
|
+
|
35
|
+
|
36
|
+
async def create_db_tasks_and_update_task_group_async(
|
37
|
+
*,
|
38
|
+
task_group_id: int,
|
39
|
+
task_list: list[TaskCreateV2],
|
40
|
+
db: AsyncSession,
|
41
|
+
) -> TaskGroupV2:
|
42
|
+
"""
|
43
|
+
Create a `TaskGroupV2` with N `TaskV2`s, and insert them into the database.
|
44
|
+
|
45
|
+
Arguments:
|
46
|
+
task_group_id: ID of an existing `TaskGroupV2` object.
|
47
|
+
task_list: List of `TaskCreateV2` objects to be inserted into the db.
|
48
|
+
db: Synchronous database session
|
49
|
+
|
50
|
+
Returns:
|
51
|
+
Updated `TaskGroupV2` object.
|
52
|
+
"""
|
53
|
+
actual_task_list = [TaskV2(**task.model_dump()) for task in task_list]
|
54
|
+
task_group = await db.get(TaskGroupV2, task_group_id)
|
55
|
+
task_group.task_list = actual_task_list
|
56
|
+
db.add(task_group)
|
57
|
+
await db.commit()
|
58
|
+
await db.refresh(task_group)
|
59
|
+
|
60
|
+
return task_group
|
@@ -2,12 +2,15 @@ from pathlib import Path
|
|
2
2
|
|
3
3
|
from fractal_server.app.models.v2 import TaskGroupV2
|
4
4
|
from fractal_server.config import get_settings
|
5
|
+
from fractal_server.logger import set_logger
|
5
6
|
from fractal_server.syringe import Inject
|
6
7
|
|
7
8
|
TEMPLATES_DIR = Path(__file__).parent / "templates"
|
8
9
|
|
9
10
|
SCRIPTS_SUBFOLDER = "scripts"
|
10
11
|
|
12
|
+
logger = set_logger(__name__)
|
13
|
+
|
11
14
|
|
12
15
|
def customize_template(
|
13
16
|
*,
|
@@ -87,4 +90,7 @@ def get_collection_replacements(
|
|
87
90
|
task_group.pinned_package_versions_string,
|
88
91
|
),
|
89
92
|
]
|
93
|
+
logger.info(
|
94
|
+
f"Cache-dir argument for `pip install`: {settings.PIP_CACHE_DIR_ARG}"
|
95
|
+
)
|
90
96
|
return replacements
|
@@ -1,8 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: fractal-server
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.14.0
|
4
4
|
Summary: Backend component of the Fractal analytics platform
|
5
|
-
Home-page: https://github.com/fractal-analytics-platform/fractal-server
|
6
5
|
License: BSD-3-Clause
|
7
6
|
Author: Tommaso Comparin
|
8
7
|
Author-email: tommaso.comparin@exact-lab.it
|
@@ -21,14 +20,15 @@ Requires-Dist: fastapi-users[oauth] (>=14,<15)
|
|
21
20
|
Requires-Dist: gunicorn (>=23.0,<24.0)
|
22
21
|
Requires-Dist: packaging (>=24.0.0,<25.0.0)
|
23
22
|
Requires-Dist: psycopg[binary] (>=3.1.0,<4.0.0)
|
24
|
-
Requires-Dist: pydantic (>=2.
|
23
|
+
Requires-Dist: pydantic (>=2.11.0,<2.12.0)
|
25
24
|
Requires-Dist: pydantic-settings (>=2.7.0)
|
26
25
|
Requires-Dist: python-dotenv (>=1.0.0,<1.1.0)
|
27
26
|
Requires-Dist: sqlalchemy[asyncio] (>=2.0.23,<2.1)
|
28
|
-
Requires-Dist: sqlmodel (==0.0.
|
27
|
+
Requires-Dist: sqlmodel (==0.0.24)
|
29
28
|
Requires-Dist: uvicorn (>=0.29.0,<0.35.0)
|
30
29
|
Requires-Dist: uvicorn-worker (==0.3.0)
|
31
30
|
Project-URL: Documentation, https://fractal-analytics-platform.github.io/fractal-server
|
31
|
+
Project-URL: Homepage, https://github.com/fractal-analytics-platform/fractal-server
|
32
32
|
Project-URL: Repository, https://github.com/fractal-analytics-platform/fractal-server
|
33
33
|
Project-URL: changelog, https://github.com/fractal-analytics-platform/fractal-server/blob/main/CHANGELOG.md
|
34
34
|
Description-Content-Type: text/markdown
|