fractal-server 2.17.1a1__py3-none-any.whl → 2.18.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 +21 -19
- fractal_server/app/db/__init__.py +3 -3
- fractal_server/app/models/__init__.py +1 -0
- fractal_server/app/models/linkuserproject.py +43 -1
- fractal_server/app/models/security.py +28 -8
- fractal_server/app/models/v2/__init__.py +3 -1
- fractal_server/app/models/v2/accounting.py +9 -1
- fractal_server/app/models/v2/dataset.py +5 -1
- fractal_server/app/models/v2/history.py +15 -1
- fractal_server/app/models/v2/job.py +17 -2
- fractal_server/app/models/v2/profile.py +29 -0
- fractal_server/app/models/v2/project.py +4 -10
- fractal_server/app/models/v2/resource.py +17 -0
- fractal_server/app/models/v2/task_group.py +4 -3
- fractal_server/app/models/v2/workflow.py +2 -1
- fractal_server/app/routes/admin/v2/__init__.py +12 -13
- fractal_server/app/routes/admin/v2/accounting.py +3 -3
- fractal_server/app/routes/admin/v2/job.py +35 -24
- fractal_server/app/routes/admin/v2/profile.py +3 -2
- fractal_server/app/routes/admin/v2/resource.py +5 -5
- fractal_server/app/routes/admin/v2/sharing.py +103 -0
- fractal_server/app/routes/admin/v2/task.py +37 -26
- fractal_server/app/routes/admin/v2/task_group.py +94 -17
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +21 -22
- fractal_server/app/routes/api/__init__.py +1 -9
- fractal_server/app/routes/api/v2/__init__.py +49 -50
- fractal_server/app/routes/api/v2/_aux_functions.py +132 -124
- fractal_server/app/routes/api/v2/_aux_functions_history.py +51 -23
- fractal_server/app/routes/api/v2/_aux_functions_sharing.py +97 -0
- fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +6 -8
- fractal_server/app/routes/api/v2/_aux_functions_tasks.py +7 -9
- fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +1 -2
- fractal_server/app/routes/api/v2/dataset.py +95 -102
- fractal_server/app/routes/api/v2/history.py +59 -33
- fractal_server/app/routes/api/v2/images.py +24 -9
- fractal_server/app/routes/api/v2/job.py +52 -33
- fractal_server/app/routes/api/v2/pre_submission_checks.py +16 -8
- fractal_server/app/routes/api/v2/project.py +65 -37
- fractal_server/app/routes/api/v2/sharing.py +311 -0
- fractal_server/app/routes/api/v2/status_legacy.py +31 -41
- fractal_server/app/routes/api/v2/submit.py +82 -78
- fractal_server/app/routes/api/v2/task.py +19 -20
- fractal_server/app/routes/api/v2/task_collection.py +41 -43
- fractal_server/app/routes/api/v2/task_collection_custom.py +19 -20
- fractal_server/app/routes/api/v2/task_collection_pixi.py +10 -11
- fractal_server/app/routes/api/v2/task_group.py +25 -24
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +32 -32
- fractal_server/app/routes/api/v2/task_version_update.py +23 -19
- fractal_server/app/routes/api/v2/workflow.py +50 -55
- fractal_server/app/routes/api/v2/workflow_import.py +37 -37
- fractal_server/app/routes/api/v2/workflowtask.py +32 -26
- fractal_server/app/routes/auth/__init__.py +1 -3
- fractal_server/app/routes/auth/_aux_auth.py +101 -2
- fractal_server/app/routes/auth/current_user.py +2 -66
- fractal_server/app/routes/auth/group.py +8 -35
- fractal_server/app/routes/auth/login.py +1 -0
- fractal_server/app/routes/auth/oauth.py +4 -3
- fractal_server/app/routes/auth/register.py +4 -2
- fractal_server/app/routes/auth/router.py +2 -0
- fractal_server/app/routes/auth/users.py +19 -10
- fractal_server/app/routes/auth/viewer_paths.py +43 -0
- fractal_server/app/routes/aux/_job.py +1 -1
- fractal_server/app/routes/aux/_runner.py +2 -2
- fractal_server/app/routes/pagination.py +1 -1
- fractal_server/app/schemas/user.py +29 -12
- fractal_server/app/schemas/user_group.py +0 -15
- fractal_server/app/schemas/v2/__init__.py +55 -48
- fractal_server/app/schemas/v2/accounting.py +11 -0
- fractal_server/app/schemas/v2/dataset.py +57 -11
- fractal_server/app/schemas/v2/dumps.py +10 -9
- fractal_server/app/schemas/v2/job.py +11 -11
- fractal_server/app/schemas/v2/manifest.py +4 -3
- fractal_server/app/schemas/v2/profile.py +53 -2
- fractal_server/app/schemas/v2/project.py +3 -3
- fractal_server/app/schemas/v2/resource.py +121 -16
- fractal_server/app/schemas/v2/sharing.py +99 -0
- fractal_server/app/schemas/v2/status_legacy.py +3 -3
- fractal_server/app/schemas/v2/task.py +6 -7
- fractal_server/app/schemas/v2/task_collection.py +5 -5
- fractal_server/app/schemas/v2/task_group.py +16 -16
- fractal_server/app/schemas/v2/workflow.py +16 -16
- fractal_server/app/schemas/v2/workflowtask.py +16 -15
- fractal_server/app/security/__init__.py +5 -8
- fractal_server/app/security/signup_email.py +4 -5
- fractal_server/app/shutdown.py +6 -6
- fractal_server/config/__init__.py +0 -6
- fractal_server/config/_data.py +0 -68
- fractal_server/config/_database.py +19 -20
- fractal_server/config/_email.py +30 -38
- fractal_server/config/_main.py +38 -52
- fractal_server/config/_oauth.py +17 -21
- fractal_server/data_migrations/2_18_0.py +30 -0
- fractal_server/exceptions.py +4 -0
- fractal_server/images/models.py +4 -5
- fractal_server/images/status_tools.py +4 -2
- fractal_server/logger.py +1 -1
- fractal_server/main.py +75 -13
- fractal_server/migrations/versions/034a469ec2eb_task_groups.py +4 -8
- fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +1 -1
- fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +1 -0
- fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +1 -1
- fractal_server/migrations/versions/1a83a5260664_rename.py +1 -1
- fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +1 -0
- fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +1 -1
- fractal_server/migrations/versions/40d6d6511b20_add_index_to_history_models.py +47 -0
- fractal_server/migrations/versions/45fbb391d7af_make_resource_id_fk_non_nullable.py +1 -1
- fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +1 -0
- fractal_server/migrations/versions/49d0856e9569_drop_table.py +2 -3
- fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +1 -1
- fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +1 -1
- fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +2 -1
- fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +7 -19
- fractal_server/migrations/versions/5bf02391cfef_v2.py +4 -10
- fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +1 -0
- fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +1 -1
- fractal_server/migrations/versions/7673fe18c05d_remove_project_dir_server_default.py +1 -1
- fractal_server/migrations/versions/7910eed4cf97_user_project_dirs_and_usergroup_viewer_.py +60 -0
- fractal_server/migrations/versions/791ce783d3d8_add_indices.py +1 -1
- fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +1 -0
- fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +1 -0
- fractal_server/migrations/versions/88270f589c9b_add_prevent_new_submissions.py +39 -0
- fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +2 -4
- fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +1 -1
- fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +1 -0
- fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +1 -1
- fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +1 -1
- fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +1 -1
- fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +2 -4
- fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +1 -1
- fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +1 -1
- fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +1 -1
- fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +1 -1
- fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +1 -0
- fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +1 -0
- fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +1 -1
- fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +1 -0
- fractal_server/migrations/versions/bc0e8b3327a7_project_sharing.py +72 -0
- fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +1 -1
- fractal_server/migrations/versions/caba9fb1ea5e_drop_useroauth_user_settings_id.py +1 -1
- fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +4 -9
- fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +1 -0
- fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +1 -1
- fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +1 -0
- fractal_server/migrations/versions/e0e717ae2f26_delete_linkuserproject_ondelete_project.py +50 -0
- fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +1 -0
- fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +1 -1
- fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +1 -0
- fractal_server/migrations/versions/f0702066b007_one_submitted_job_per_dataset.py +40 -0
- fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +1 -1
- fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +1 -0
- fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +4 -9
- fractal_server/runner/config/_local.py +8 -5
- fractal_server/runner/config/_slurm.py +39 -33
- fractal_server/runner/config/slurm_mem_to_MB.py +0 -1
- fractal_server/runner/executors/base_runner.py +29 -4
- fractal_server/runner/executors/local/get_local_config.py +1 -0
- fractal_server/runner/executors/local/runner.py +14 -13
- fractal_server/runner/executors/slurm_common/_batching.py +9 -20
- fractal_server/runner/executors/slurm_common/base_slurm_runner.py +53 -27
- fractal_server/runner/executors/slurm_common/get_slurm_config.py +14 -7
- fractal_server/runner/executors/slurm_common/remote.py +3 -1
- fractal_server/runner/executors/slurm_common/slurm_config.py +2 -0
- fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +1 -3
- fractal_server/runner/executors/slurm_ssh/runner.py +16 -11
- fractal_server/runner/executors/slurm_ssh/tar_commands.py +1 -0
- fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -0
- fractal_server/runner/executors/slurm_sudo/runner.py +16 -11
- fractal_server/runner/task_files.py +9 -3
- fractal_server/runner/v2/_local.py +12 -6
- fractal_server/runner/v2/_slurm_ssh.py +14 -7
- fractal_server/runner/v2/_slurm_sudo.py +14 -7
- fractal_server/runner/v2/db_tools.py +0 -1
- fractal_server/runner/v2/deduplicate_list.py +2 -1
- fractal_server/runner/v2/runner.py +44 -28
- fractal_server/runner/v2/runner_functions.py +22 -28
- fractal_server/runner/v2/submit_workflow.py +29 -15
- fractal_server/ssh/_fabric.py +6 -13
- fractal_server/string_tools.py +0 -1
- fractal_server/syringe.py +1 -1
- fractal_server/tasks/config/_pixi.py +1 -1
- fractal_server/tasks/config/_python.py +16 -9
- fractal_server/tasks/utils.py +0 -1
- fractal_server/tasks/v2/local/_utils.py +3 -3
- fractal_server/tasks/v2/local/collect.py +15 -18
- fractal_server/tasks/v2/local/collect_pixi.py +14 -16
- fractal_server/tasks/v2/local/deactivate.py +14 -15
- fractal_server/tasks/v2/local/deactivate_pixi.py +7 -7
- fractal_server/tasks/v2/local/delete.py +6 -8
- fractal_server/tasks/v2/local/reactivate.py +12 -12
- fractal_server/tasks/v2/local/reactivate_pixi.py +12 -12
- fractal_server/tasks/v2/ssh/_utils.py +3 -3
- fractal_server/tasks/v2/ssh/collect.py +19 -24
- fractal_server/tasks/v2/ssh/collect_pixi.py +22 -24
- fractal_server/tasks/v2/ssh/deactivate.py +17 -15
- fractal_server/tasks/v2/ssh/deactivate_pixi.py +8 -7
- fractal_server/tasks/v2/ssh/delete.py +12 -10
- fractal_server/tasks/v2/ssh/reactivate.py +16 -16
- fractal_server/tasks/v2/ssh/reactivate_pixi.py +13 -14
- fractal_server/tasks/v2/templates/1_create_venv.sh +2 -0
- fractal_server/tasks/v2/templates/2_pip_install.sh +2 -0
- fractal_server/tasks/v2/templates/3_pip_freeze.sh +2 -0
- fractal_server/tasks/v2/templates/4_pip_show.sh +2 -0
- fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +3 -1
- fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +2 -0
- fractal_server/tasks/v2/templates/pixi_1_extract.sh +2 -0
- fractal_server/tasks/v2/templates/pixi_2_install.sh +2 -0
- fractal_server/tasks/v2/templates/pixi_3_post_install.sh +2 -0
- fractal_server/tasks/v2/utils_background.py +10 -10
- fractal_server/tasks/v2/utils_database.py +5 -5
- fractal_server/tasks/v2/utils_package_names.py +1 -2
- fractal_server/tasks/v2/utils_pixi.py +1 -3
- fractal_server/types/__init__.py +98 -1
- fractal_server/types/validators/__init__.py +3 -0
- fractal_server/types/validators/_common_validators.py +33 -3
- fractal_server/types/validators/_workflow_task_arguments_validators.py +1 -2
- fractal_server/utils.py +1 -0
- fractal_server/zip_tools.py +34 -0
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/METADATA +3 -2
- fractal_server-2.18.0.dist-info/RECORD +275 -0
- fractal_server/app/routes/admin/v2/project.py +0 -41
- fractal_server-2.17.1a1.dist-info/RECORD +0 -264
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/WHEEL +0 -0
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/entry_points.txt +0 -0
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,8 +7,8 @@ from typing import Self
|
|
|
7
7
|
from pydantic import AfterValidator
|
|
8
8
|
from pydantic import BaseModel
|
|
9
9
|
from pydantic import Discriminator
|
|
10
|
-
from pydantic import model_validator
|
|
11
10
|
from pydantic import Tag
|
|
11
|
+
from pydantic import model_validator
|
|
12
12
|
from pydantic import validate_call
|
|
13
13
|
from pydantic.types import AwareDatetime
|
|
14
14
|
|
|
@@ -21,23 +21,46 @@ from fractal_server.types import NonEmptyStr
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class ResourceType(StrEnum):
|
|
24
|
+
"""
|
|
25
|
+
Enum for the possible resource types.
|
|
26
|
+
"""
|
|
27
|
+
|
|
24
28
|
SLURM_SUDO = "slurm_sudo"
|
|
29
|
+
"""
|
|
30
|
+
Enum entry for resource type `slurm_sudo`.
|
|
31
|
+
"""
|
|
32
|
+
|
|
25
33
|
SLURM_SSH = "slurm_ssh"
|
|
34
|
+
"""
|
|
35
|
+
Enum entry for resource type `slurm_ssh`.
|
|
36
|
+
"""
|
|
37
|
+
|
|
26
38
|
LOCAL = "local"
|
|
39
|
+
"""
|
|
40
|
+
Enum entry for resource type `local`.
|
|
41
|
+
"""
|
|
27
42
|
|
|
28
43
|
|
|
29
44
|
def cast_serialize_pixi_settings(
|
|
30
|
-
|
|
45
|
+
value: dict[NonEmptyStr, Any],
|
|
31
46
|
) -> dict[NonEmptyStr, Any]:
|
|
32
47
|
"""
|
|
33
|
-
|
|
48
|
+
Cast/serialize round trip for `tasks_pixi_config` through the
|
|
49
|
+
`TasksPixiSettings` schema.
|
|
50
|
+
|
|
51
|
+
Arguments:
|
|
52
|
+
value: Current `tasks_pixi_config` value.
|
|
34
53
|
"""
|
|
35
|
-
if
|
|
36
|
-
|
|
37
|
-
return
|
|
54
|
+
if value != {}:
|
|
55
|
+
value = TasksPixiSettings(**value).model_dump()
|
|
56
|
+
return value
|
|
38
57
|
|
|
39
58
|
|
|
40
|
-
class
|
|
59
|
+
class ValidResourceBase(BaseModel):
|
|
60
|
+
"""
|
|
61
|
+
Base resource schema.
|
|
62
|
+
"""
|
|
63
|
+
|
|
41
64
|
type: ResourceType
|
|
42
65
|
name: NonEmptyStr
|
|
43
66
|
|
|
@@ -54,6 +77,8 @@ class _ValidResourceBase(BaseModel):
|
|
|
54
77
|
jobs_runner_config: dict[NonEmptyStr, Any]
|
|
55
78
|
jobs_poll_interval: int = 5
|
|
56
79
|
|
|
80
|
+
prevent_new_submissions: bool = False
|
|
81
|
+
|
|
57
82
|
@model_validator(mode="after")
|
|
58
83
|
def _pixi_slurm_config(self) -> Self:
|
|
59
84
|
if (
|
|
@@ -61,27 +86,98 @@ class _ValidResourceBase(BaseModel):
|
|
|
61
86
|
and self.type == ResourceType.SLURM_SSH
|
|
62
87
|
and self.tasks_pixi_config["SLURM_CONFIG"] is None
|
|
63
88
|
):
|
|
64
|
-
raise ValueError(
|
|
65
|
-
"`tasks_pixi_config` must include `SLURM_CONFIG`."
|
|
66
|
-
)
|
|
89
|
+
raise ValueError("`tasks_pixi_config` must include `SLURM_CONFIG`.")
|
|
67
90
|
return self
|
|
68
91
|
|
|
69
92
|
|
|
70
|
-
class ValidResourceLocal(
|
|
93
|
+
class ValidResourceLocal(ValidResourceBase):
|
|
94
|
+
"""
|
|
95
|
+
Valid local resource.
|
|
96
|
+
|
|
97
|
+
Attributes:
|
|
98
|
+
name: Resource name.
|
|
99
|
+
type: Resource type.
|
|
100
|
+
prevent_new_submissions:
|
|
101
|
+
When set to true: Prevent new job submissions and stop execution of
|
|
102
|
+
ongoing jobs as soon as the current task is complete.
|
|
103
|
+
tasks_python_config:
|
|
104
|
+
Configuration of Python interpreters used for task collection.
|
|
105
|
+
tasks_pixi_config:
|
|
106
|
+
Configuration of `pixi` interpreters used for task collection.
|
|
107
|
+
tasks_local_dir:
|
|
108
|
+
Local base folder for task environments.
|
|
109
|
+
jobs_local_dir:
|
|
110
|
+
Local base folder for job folders.
|
|
111
|
+
jobs_runner_config:
|
|
112
|
+
Runner configuration.
|
|
113
|
+
"""
|
|
114
|
+
|
|
71
115
|
type: Literal[ResourceType.LOCAL]
|
|
72
116
|
jobs_runner_config: JobRunnerConfigLocal
|
|
73
117
|
jobs_slurm_python_worker: None = None
|
|
74
118
|
host: None = None
|
|
75
119
|
|
|
76
120
|
|
|
77
|
-
class ValidResourceSlurmSudo(
|
|
121
|
+
class ValidResourceSlurmSudo(ValidResourceBase):
|
|
122
|
+
"""
|
|
123
|
+
Valid SLURM-sudo resource.
|
|
124
|
+
|
|
125
|
+
Attributes:
|
|
126
|
+
name: Resource name.
|
|
127
|
+
type: Resource type.
|
|
128
|
+
prevent_new_submissions:
|
|
129
|
+
When set to true: Prevent new job submissions and stop execution of
|
|
130
|
+
ongoing jobs as soon as the current task is complete.
|
|
131
|
+
tasks_python_config:
|
|
132
|
+
Configuration of Python interpreters used for task collection.
|
|
133
|
+
tasks_pixi_config:
|
|
134
|
+
Configuration of `pixi` interpreters used for task collection.
|
|
135
|
+
tasks_local_dir:
|
|
136
|
+
Local base folder for task environments.
|
|
137
|
+
jobs_local_dir:
|
|
138
|
+
Local base folder for job folders.
|
|
139
|
+
jobs_runner_config:
|
|
140
|
+
Runner configuration.
|
|
141
|
+
jobs_poll_interval:
|
|
142
|
+
`squeue` polling interval.
|
|
143
|
+
jobs_slurm_python_worker:
|
|
144
|
+
Python worker to be used in SLURM jobs.
|
|
145
|
+
"""
|
|
146
|
+
|
|
78
147
|
type: Literal[ResourceType.SLURM_SUDO]
|
|
79
148
|
jobs_slurm_python_worker: AbsolutePathStr
|
|
80
149
|
jobs_runner_config: JobRunnerConfigSLURM
|
|
81
150
|
host: None = None
|
|
82
151
|
|
|
83
152
|
|
|
84
|
-
class ValidResourceSlurmSSH(
|
|
153
|
+
class ValidResourceSlurmSSH(ValidResourceBase):
|
|
154
|
+
"""
|
|
155
|
+
Valid SLURM-SSH resource.
|
|
156
|
+
|
|
157
|
+
Attributes:
|
|
158
|
+
name: Resource name
|
|
159
|
+
type: Resource type.
|
|
160
|
+
prevent_new_submissions:
|
|
161
|
+
When set to true: Prevent new job submissions and stop execution of
|
|
162
|
+
ongoing jobs as soon as the current task is complete.
|
|
163
|
+
tasks_python_config:
|
|
164
|
+
Configuration of Python interpreters used for task collection.
|
|
165
|
+
tasks_pixi_config:
|
|
166
|
+
Configuration of `pixi` interpreters used for task collection.
|
|
167
|
+
tasks_local_dir:
|
|
168
|
+
Local base folder for task environments.
|
|
169
|
+
jobs_local_dir:
|
|
170
|
+
Local base folder for job folders.
|
|
171
|
+
jobs_runner_config:
|
|
172
|
+
Runner configuration.
|
|
173
|
+
jobs_poll_interval:
|
|
174
|
+
`squeue` polling interval.
|
|
175
|
+
jobs_slurm_python_worker:
|
|
176
|
+
Python worker to be used in SLURM jobs.
|
|
177
|
+
host:
|
|
178
|
+
Hostname or IP address of remote SLURM cluster.
|
|
179
|
+
"""
|
|
180
|
+
|
|
85
181
|
type: Literal[ResourceType.SLURM_SSH]
|
|
86
182
|
host: NonEmptyStr
|
|
87
183
|
jobs_slurm_python_worker: AbsolutePathStr
|
|
@@ -101,14 +197,20 @@ ResourceCreate = Annotated[
|
|
|
101
197
|
| Annotated[ValidResourceSlurmSSH, Tag(ResourceType.SLURM_SSH)],
|
|
102
198
|
Discriminator(get_discriminator_value),
|
|
103
199
|
]
|
|
200
|
+
"""
|
|
201
|
+
Schema for resources in API request bodies.
|
|
202
|
+
"""
|
|
104
203
|
|
|
105
204
|
|
|
106
205
|
class ResourceRead(BaseModel):
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
206
|
+
"""
|
|
207
|
+
Schema for resources in API response bodies.
|
|
208
|
+
"""
|
|
110
209
|
|
|
210
|
+
id: int
|
|
111
211
|
name: str
|
|
212
|
+
type: str
|
|
213
|
+
prevent_new_submissions: bool
|
|
112
214
|
timestamp_created: AwareDatetime
|
|
113
215
|
|
|
114
216
|
host: str | None
|
|
@@ -131,6 +233,9 @@ def cast_serialize_resource(_data: ResourceCreate) -> dict[str, Any]:
|
|
|
131
233
|
We use `@validate_call` because `ResourceCreate` is a `Union` type and it
|
|
132
234
|
cannot be instantiated directly.
|
|
133
235
|
|
|
236
|
+
Args:
|
|
237
|
+
_data:
|
|
238
|
+
|
|
134
239
|
Return:
|
|
135
240
|
Serialized version of a valid resource object.
|
|
136
241
|
"""
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from enum import StrEnum
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ProjectPermissions(StrEnum):
|
|
7
|
+
"""
|
|
8
|
+
Available permissions for accessing Project
|
|
9
|
+
Attributes:
|
|
10
|
+
READ:
|
|
11
|
+
WRITE:
|
|
12
|
+
EXECUTE:
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
READ = "r"
|
|
16
|
+
WRITE = "rw"
|
|
17
|
+
EXECUTE = "rwx"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ProjectGuestCreate(BaseModel):
|
|
21
|
+
"""
|
|
22
|
+
Request body for project-sharing invitation.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
permissions:
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
permissions: ProjectPermissions
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ProjectGuestRead(BaseModel):
|
|
32
|
+
"""
|
|
33
|
+
Information about a guest.
|
|
34
|
+
|
|
35
|
+
Attributes:
|
|
36
|
+
email: Guest email.
|
|
37
|
+
is_verified: Project/guest verification status.
|
|
38
|
+
permissions: Guest permissions for project.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
email: str
|
|
42
|
+
is_verified: bool
|
|
43
|
+
permissions: str
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ProjectGuestUpdate(BaseModel):
|
|
47
|
+
"""
|
|
48
|
+
Request body for updating permissions of an existing guest.
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
permissions: New permissions for guest.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
permissions: ProjectPermissions
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ProjectAccessRead(BaseModel):
|
|
58
|
+
"""
|
|
59
|
+
Project-access information for current user.
|
|
60
|
+
|
|
61
|
+
Attributes:
|
|
62
|
+
is_owner: Whether current user is owner.
|
|
63
|
+
permissions: Current user permissions.
|
|
64
|
+
owner_email: Email of project owner
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
is_owner: bool
|
|
68
|
+
permissions: str
|
|
69
|
+
owner_email: str
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ProjectInvitationRead(BaseModel):
|
|
73
|
+
"""
|
|
74
|
+
Info about a pending invitation.
|
|
75
|
+
|
|
76
|
+
Attributes:
|
|
77
|
+
project_id:
|
|
78
|
+
project_name:
|
|
79
|
+
owner_email:
|
|
80
|
+
guest_permissions:
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
project_id: int
|
|
84
|
+
project_name: str
|
|
85
|
+
owner_email: str
|
|
86
|
+
guest_permissions: str
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class LinkUserProjectRead(BaseModel):
|
|
90
|
+
# User info
|
|
91
|
+
user_id: int
|
|
92
|
+
user_email: str
|
|
93
|
+
# Project info
|
|
94
|
+
project_id: int
|
|
95
|
+
project_name: str
|
|
96
|
+
# Permissions
|
|
97
|
+
is_verified: bool
|
|
98
|
+
is_owner: bool
|
|
99
|
+
permissions: str
|
|
@@ -4,7 +4,7 @@ from pydantic import BaseModel
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
class
|
|
7
|
+
class WorkflowTaskStatusType(StrEnum):
|
|
8
8
|
"""
|
|
9
9
|
Define the available values for the status of a `WorkflowTask`.
|
|
10
10
|
|
|
@@ -23,7 +23,7 @@ class WorkflowTaskStatusTypeV2(StrEnum):
|
|
|
23
23
|
FAILED = "failed"
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
class
|
|
26
|
+
class LegacyStatusRead(BaseModel):
|
|
27
27
|
"""
|
|
28
28
|
Response type for the
|
|
29
29
|
`/project/{project_id}/status/` endpoint
|
|
@@ -31,5 +31,5 @@ class LegacyStatusReadV2(BaseModel):
|
|
|
31
31
|
|
|
32
32
|
status: dict[
|
|
33
33
|
str,
|
|
34
|
-
|
|
34
|
+
WorkflowTaskStatusType,
|
|
35
35
|
] = Field(default_factory=dict)
|
|
@@ -14,7 +14,6 @@ from fractal_server.types import ListUniqueNonEmptyString
|
|
|
14
14
|
from fractal_server.types import NonEmptyStr
|
|
15
15
|
from fractal_server.types import TypeFilters
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
logger = set_logger(__name__)
|
|
19
18
|
|
|
20
19
|
|
|
@@ -30,7 +29,7 @@ class TaskType(StrEnum):
|
|
|
30
29
|
PARALLEL = "parallel"
|
|
31
30
|
|
|
32
31
|
|
|
33
|
-
class
|
|
32
|
+
class TaskCreate(BaseModel):
|
|
34
33
|
model_config = ConfigDict(extra="forbid")
|
|
35
34
|
|
|
36
35
|
name: NonEmptyStr
|
|
@@ -91,7 +90,7 @@ class TaskCreateV2(BaseModel):
|
|
|
91
90
|
return self
|
|
92
91
|
|
|
93
92
|
|
|
94
|
-
class
|
|
93
|
+
class TaskRead(BaseModel):
|
|
95
94
|
id: int
|
|
96
95
|
name: str
|
|
97
96
|
type: TaskType
|
|
@@ -118,7 +117,7 @@ class TaskReadV2(BaseModel):
|
|
|
118
117
|
tags: list[str]
|
|
119
118
|
|
|
120
119
|
|
|
121
|
-
class
|
|
120
|
+
class TaskUpdate(BaseModel):
|
|
122
121
|
model_config = ConfigDict(extra="forbid")
|
|
123
122
|
|
|
124
123
|
command_parallel: NonEmptyStr = None
|
|
@@ -132,7 +131,7 @@ class TaskUpdateV2(BaseModel):
|
|
|
132
131
|
tags: ListUniqueNonEmptyString | None = None
|
|
133
132
|
|
|
134
133
|
|
|
135
|
-
class
|
|
134
|
+
class TaskImport(BaseModel):
|
|
136
135
|
model_config = ConfigDict(extra="forbid")
|
|
137
136
|
|
|
138
137
|
pkg_name: NonEmptyStr
|
|
@@ -140,11 +139,11 @@ class TaskImportV2(BaseModel):
|
|
|
140
139
|
name: NonEmptyStr
|
|
141
140
|
|
|
142
141
|
|
|
143
|
-
class
|
|
142
|
+
class TaskImportLegacy(BaseModel):
|
|
144
143
|
source: NonEmptyStr
|
|
145
144
|
|
|
146
145
|
|
|
147
|
-
class
|
|
146
|
+
class TaskExport(BaseModel):
|
|
148
147
|
pkg_name: NonEmptyStr
|
|
149
148
|
version: NonEmptyStr | None = None
|
|
150
149
|
name: NonEmptyStr
|
|
@@ -21,9 +21,9 @@ class FractalUploadedFile(BaseModel):
|
|
|
21
21
|
contents: bytes
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class
|
|
24
|
+
class TaskCollectPip(BaseModel):
|
|
25
25
|
"""
|
|
26
|
-
|
|
26
|
+
TaskCollectPip class
|
|
27
27
|
|
|
28
28
|
This class only encodes the attributes required to trigger a
|
|
29
29
|
task-collection operation. Other attributes (that are assigned *during*
|
|
@@ -86,12 +86,12 @@ class TaskCollectPipV2(BaseModel):
|
|
|
86
86
|
def validate_pinned_package_versions(cls, value):
|
|
87
87
|
if value is not None:
|
|
88
88
|
for pkg, version in value.items():
|
|
89
|
-
validate_cmd(pkg)
|
|
89
|
+
validate_cmd(pkg, allow_char="[]")
|
|
90
90
|
validate_cmd(version)
|
|
91
91
|
return value
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
class
|
|
94
|
+
class TaskCollectCustom(BaseModel):
|
|
95
95
|
"""
|
|
96
96
|
Attributes:
|
|
97
97
|
manifest: Manifest of a Fractal task package (this is typically the
|
|
@@ -99,7 +99,7 @@ class TaskCollectCustomV2(BaseModel):
|
|
|
99
99
|
python_interpreter: Absolute path to the Python interpreter to be used
|
|
100
100
|
for running tasks.
|
|
101
101
|
name: A name identifying this package, that will fill the
|
|
102
|
-
`
|
|
102
|
+
`TaskGroup.pkg_name` column.
|
|
103
103
|
package_root: The folder where the package is installed.
|
|
104
104
|
If not provided, it will be extracted via `pip show`
|
|
105
105
|
(requires `package_name` to be set).
|
|
@@ -7,40 +7,40 @@ from pydantic import Field
|
|
|
7
7
|
from pydantic import field_serializer
|
|
8
8
|
from pydantic.types import AwareDatetime
|
|
9
9
|
|
|
10
|
-
from fractal_server.app.schemas.v2.task import
|
|
10
|
+
from fractal_server.app.schemas.v2.task import TaskRead
|
|
11
11
|
from fractal_server.types import AbsolutePathStr
|
|
12
12
|
from fractal_server.types import DictStrStr
|
|
13
13
|
from fractal_server.types import NonEmptyStr
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
class
|
|
16
|
+
class TaskGroupOriginEnum(StrEnum):
|
|
17
17
|
PYPI = "pypi"
|
|
18
18
|
WHEELFILE = "wheel-file"
|
|
19
19
|
PIXI = "pixi"
|
|
20
20
|
OTHER = "other"
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class
|
|
23
|
+
class TaskGroupActivityStatus(StrEnum):
|
|
24
24
|
PENDING = "pending"
|
|
25
25
|
ONGOING = "ongoing"
|
|
26
26
|
FAILED = "failed"
|
|
27
27
|
OK = "OK"
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
class
|
|
30
|
+
class TaskGroupActivityAction(StrEnum):
|
|
31
31
|
COLLECT = "collect"
|
|
32
32
|
DEACTIVATE = "deactivate"
|
|
33
33
|
REACTIVATE = "reactivate"
|
|
34
34
|
DELETE = "delete"
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
class
|
|
37
|
+
class TaskGroupCreate(BaseModel):
|
|
38
38
|
model_config = ConfigDict(extra="forbid")
|
|
39
39
|
user_id: int
|
|
40
40
|
resource_id: int
|
|
41
41
|
user_group_id: int | None = None
|
|
42
42
|
active: bool = True
|
|
43
|
-
origin:
|
|
43
|
+
origin: TaskGroupOriginEnum
|
|
44
44
|
pkg_name: str
|
|
45
45
|
version: str | None = None
|
|
46
46
|
python_version: NonEmptyStr = None
|
|
@@ -54,9 +54,9 @@ class TaskGroupCreateV2(BaseModel):
|
|
|
54
54
|
pinned_package_versions_post: DictStrStr = Field(default_factory=dict)
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
class
|
|
57
|
+
class TaskGroupCreateStrict(TaskGroupCreate):
|
|
58
58
|
"""
|
|
59
|
-
A strict version of
|
|
59
|
+
A strict version of TaskGroupCreate, to be used for task collection.
|
|
60
60
|
"""
|
|
61
61
|
|
|
62
62
|
path: AbsolutePathStr
|
|
@@ -65,14 +65,14 @@ class TaskGroupCreateV2Strict(TaskGroupCreateV2):
|
|
|
65
65
|
python_version: NonEmptyStr
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
class
|
|
68
|
+
class TaskGroupRead(BaseModel):
|
|
69
69
|
id: int
|
|
70
|
-
task_list: list[
|
|
70
|
+
task_list: list[TaskRead]
|
|
71
71
|
|
|
72
72
|
user_id: int
|
|
73
73
|
user_group_id: int | None = None
|
|
74
74
|
|
|
75
|
-
origin:
|
|
75
|
+
origin: TaskGroupOriginEnum
|
|
76
76
|
pkg_name: str
|
|
77
77
|
version: str | None = None
|
|
78
78
|
python_version: str | None = None
|
|
@@ -96,16 +96,16 @@ class TaskGroupReadV2(BaseModel):
|
|
|
96
96
|
return v.isoformat()
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
class TaskGroupReadSuperuser(
|
|
99
|
+
class TaskGroupReadSuperuser(TaskGroupRead):
|
|
100
100
|
resource_id: int
|
|
101
101
|
|
|
102
102
|
|
|
103
|
-
class
|
|
103
|
+
class TaskGroupUpdate(BaseModel):
|
|
104
104
|
model_config = ConfigDict(extra="forbid")
|
|
105
105
|
user_group_id: int | None = None
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
class
|
|
108
|
+
class TaskGroupActivityRead(BaseModel):
|
|
109
109
|
id: int
|
|
110
110
|
user_id: int
|
|
111
111
|
taskgroupv2_id: int | None = None
|
|
@@ -113,8 +113,8 @@ class TaskGroupActivityV2Read(BaseModel):
|
|
|
113
113
|
timestamp_ended: AwareDatetime | None = None
|
|
114
114
|
pkg_name: str
|
|
115
115
|
version: str
|
|
116
|
-
status:
|
|
117
|
-
action:
|
|
116
|
+
status: TaskGroupActivityStatus
|
|
117
|
+
action: TaskGroupActivityAction
|
|
118
118
|
log: str | None = None
|
|
119
119
|
|
|
120
120
|
@field_serializer("timestamp_started")
|
|
@@ -5,29 +5,29 @@ from pydantic import ConfigDict
|
|
|
5
5
|
from pydantic import field_serializer
|
|
6
6
|
from pydantic.types import AwareDatetime
|
|
7
7
|
|
|
8
|
-
from fractal_server.app.schemas.v2.project import
|
|
9
|
-
from fractal_server.app.schemas.v2.workflowtask import
|
|
10
|
-
from fractal_server.app.schemas.v2.workflowtask import
|
|
11
|
-
from fractal_server.app.schemas.v2.workflowtask import
|
|
8
|
+
from fractal_server.app.schemas.v2.project import ProjectRead
|
|
9
|
+
from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskExport
|
|
10
|
+
from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskImport
|
|
11
|
+
from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskRead
|
|
12
12
|
from fractal_server.app.schemas.v2.workflowtask import (
|
|
13
|
-
|
|
13
|
+
WorkflowTaskReadWithWarning,
|
|
14
14
|
)
|
|
15
15
|
from fractal_server.types import ListUniqueNonNegativeInt
|
|
16
16
|
from fractal_server.types import NonEmptyStr
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class
|
|
19
|
+
class WorkflowCreate(BaseModel):
|
|
20
20
|
model_config = ConfigDict(extra="forbid")
|
|
21
21
|
|
|
22
22
|
name: NonEmptyStr
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class
|
|
25
|
+
class WorkflowRead(BaseModel):
|
|
26
26
|
id: int
|
|
27
27
|
name: str
|
|
28
28
|
project_id: int
|
|
29
|
-
task_list: list[
|
|
30
|
-
project:
|
|
29
|
+
task_list: list[WorkflowTaskRead]
|
|
30
|
+
project: ProjectRead
|
|
31
31
|
timestamp_created: AwareDatetime
|
|
32
32
|
|
|
33
33
|
@field_serializer("timestamp_created")
|
|
@@ -35,18 +35,18 @@ class WorkflowReadV2(BaseModel):
|
|
|
35
35
|
return v.isoformat()
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class
|
|
39
|
-
task_list: list[
|
|
38
|
+
class WorkflowReadWithWarnings(WorkflowRead):
|
|
39
|
+
task_list: list[WorkflowTaskReadWithWarning]
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class
|
|
42
|
+
class WorkflowUpdate(BaseModel):
|
|
43
43
|
model_config = ConfigDict(extra="forbid")
|
|
44
44
|
|
|
45
45
|
name: NonEmptyStr = None
|
|
46
46
|
reordered_workflowtask_ids: ListUniqueNonNegativeInt | None = None
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
class
|
|
49
|
+
class WorkflowImport(BaseModel):
|
|
50
50
|
"""
|
|
51
51
|
Class for `Workflow` import.
|
|
52
52
|
|
|
@@ -56,10 +56,10 @@ class WorkflowImportV2(BaseModel):
|
|
|
56
56
|
|
|
57
57
|
model_config = ConfigDict(extra="forbid")
|
|
58
58
|
name: NonEmptyStr
|
|
59
|
-
task_list: list[
|
|
59
|
+
task_list: list[WorkflowTaskImport]
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
class
|
|
62
|
+
class WorkflowExport(BaseModel):
|
|
63
63
|
"""
|
|
64
64
|
Class for `Workflow` export.
|
|
65
65
|
|
|
@@ -68,4 +68,4 @@ class WorkflowExportV2(BaseModel):
|
|
|
68
68
|
"""
|
|
69
69
|
|
|
70
70
|
name: str
|
|
71
|
-
task_list: list[
|
|
71
|
+
task_list: list[WorkflowTaskExport]
|