fractal-server 2.17.2__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 +2 -1
- fractal_server/app/models/linkuserproject.py +40 -0
- fractal_server/app/models/security.py +7 -5
- fractal_server/app/models/v2/job.py +13 -2
- fractal_server/app/models/v2/resource.py +13 -0
- fractal_server/app/routes/admin/v2/__init__.py +11 -11
- fractal_server/app/routes/admin/v2/accounting.py +2 -2
- fractal_server/app/routes/admin/v2/job.py +34 -23
- fractal_server/app/routes/admin/v2/sharing.py +103 -0
- fractal_server/app/routes/admin/v2/task.py +9 -8
- fractal_server/app/routes/admin/v2/task_group.py +94 -16
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +20 -20
- fractal_server/app/routes/api/__init__.py +0 -9
- fractal_server/app/routes/api/v2/__init__.py +47 -47
- fractal_server/app/routes/api/v2/_aux_functions.py +65 -64
- fractal_server/app/routes/api/v2/_aux_functions_history.py +8 -3
- fractal_server/app/routes/api/v2/_aux_functions_sharing.py +97 -0
- fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +4 -4
- fractal_server/app/routes/api/v2/_aux_functions_tasks.py +2 -2
- fractal_server/app/routes/api/v2/dataset.py +89 -77
- fractal_server/app/routes/api/v2/history.py +28 -16
- fractal_server/app/routes/api/v2/images.py +22 -8
- fractal_server/app/routes/api/v2/job.py +40 -24
- fractal_server/app/routes/api/v2/pre_submission_checks.py +13 -6
- fractal_server/app/routes/api/v2/project.py +48 -25
- fractal_server/app/routes/api/v2/sharing.py +311 -0
- fractal_server/app/routes/api/v2/status_legacy.py +22 -33
- fractal_server/app/routes/api/v2/submit.py +76 -71
- fractal_server/app/routes/api/v2/task.py +15 -17
- fractal_server/app/routes/api/v2/task_collection.py +18 -18
- fractal_server/app/routes/api/v2/task_collection_custom.py +11 -13
- fractal_server/app/routes/api/v2/task_collection_pixi.py +9 -9
- fractal_server/app/routes/api/v2/task_group.py +18 -18
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +26 -26
- fractal_server/app/routes/api/v2/task_version_update.py +12 -9
- fractal_server/app/routes/api/v2/workflow.py +41 -29
- fractal_server/app/routes/api/v2/workflow_import.py +25 -23
- fractal_server/app/routes/api/v2/workflowtask.py +25 -17
- fractal_server/app/routes/auth/_aux_auth.py +100 -0
- fractal_server/app/routes/auth/current_user.py +0 -63
- fractal_server/app/routes/auth/group.py +1 -30
- fractal_server/app/routes/auth/router.py +2 -0
- fractal_server/app/routes/auth/users.py +9 -0
- fractal_server/app/routes/auth/viewer_paths.py +43 -0
- 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/dataset.py +35 -13
- fractal_server/app/schemas/v2/dumps.py +9 -9
- fractal_server/app/schemas/v2/job.py +11 -11
- fractal_server/app/schemas/v2/project.py +3 -3
- fractal_server/app/schemas/v2/resource.py +13 -4
- 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 -6
- fractal_server/app/schemas/v2/task_collection.py +4 -4
- 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 +14 -14
- fractal_server/app/security/__init__.py +1 -1
- fractal_server/app/shutdown.py +6 -6
- fractal_server/config/__init__.py +0 -6
- fractal_server/config/_data.py +0 -79
- fractal_server/config/_main.py +6 -1
- fractal_server/data_migrations/2_18_0.py +30 -0
- fractal_server/images/models.py +1 -2
- fractal_server/main.py +72 -11
- fractal_server/migrations/versions/7910eed4cf97_user_project_dirs_and_usergroup_viewer_.py +60 -0
- fractal_server/migrations/versions/88270f589c9b_add_prevent_new_submissions.py +39 -0
- fractal_server/migrations/versions/bc0e8b3327a7_project_sharing.py +72 -0
- fractal_server/migrations/versions/f0702066b007_one_submitted_job_per_dataset.py +40 -0
- fractal_server/runner/config/_slurm.py +2 -0
- fractal_server/runner/executors/slurm_common/_batching.py +4 -10
- fractal_server/runner/executors/slurm_common/slurm_config.py +1 -0
- fractal_server/runner/executors/slurm_ssh/runner.py +1 -1
- fractal_server/runner/executors/slurm_sudo/runner.py +1 -1
- fractal_server/runner/v2/_local.py +4 -3
- fractal_server/runner/v2/_slurm_ssh.py +4 -3
- fractal_server/runner/v2/_slurm_sudo.py +4 -3
- fractal_server/runner/v2/runner.py +36 -17
- fractal_server/runner/v2/runner_functions.py +11 -14
- fractal_server/runner/v2/submit_workflow.py +22 -9
- fractal_server/tasks/v2/local/_utils.py +2 -2
- fractal_server/tasks/v2/local/collect.py +5 -6
- fractal_server/tasks/v2/local/collect_pixi.py +5 -6
- fractal_server/tasks/v2/local/deactivate.py +7 -7
- fractal_server/tasks/v2/local/deactivate_pixi.py +3 -3
- fractal_server/tasks/v2/local/delete.py +5 -5
- fractal_server/tasks/v2/local/reactivate.py +5 -5
- fractal_server/tasks/v2/local/reactivate_pixi.py +5 -5
- fractal_server/tasks/v2/ssh/collect.py +5 -5
- fractal_server/tasks/v2/ssh/collect_pixi.py +5 -5
- fractal_server/tasks/v2/ssh/deactivate.py +7 -7
- fractal_server/tasks/v2/ssh/deactivate_pixi.py +2 -2
- fractal_server/tasks/v2/ssh/delete.py +5 -5
- fractal_server/tasks/v2/ssh/reactivate.py +5 -5
- fractal_server/tasks/v2/ssh/reactivate_pixi.py +5 -5
- fractal_server/tasks/v2/utils_background.py +7 -7
- fractal_server/tasks/v2/utils_database.py +5 -5
- fractal_server/types/__init__.py +22 -0
- fractal_server/types/validators/__init__.py +3 -0
- fractal_server/types/validators/_common_validators.py +32 -0
- {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/METADATA +3 -2
- {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/RECORD +108 -98
- {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/WHEEL +0 -0
- {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/entry_points.txt +0 -0
- {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -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)
|
|
@@ -29,7 +29,7 @@ class TaskType(StrEnum):
|
|
|
29
29
|
PARALLEL = "parallel"
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
class
|
|
32
|
+
class TaskCreate(BaseModel):
|
|
33
33
|
model_config = ConfigDict(extra="forbid")
|
|
34
34
|
|
|
35
35
|
name: NonEmptyStr
|
|
@@ -90,7 +90,7 @@ class TaskCreateV2(BaseModel):
|
|
|
90
90
|
return self
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
class
|
|
93
|
+
class TaskRead(BaseModel):
|
|
94
94
|
id: int
|
|
95
95
|
name: str
|
|
96
96
|
type: TaskType
|
|
@@ -117,7 +117,7 @@ class TaskReadV2(BaseModel):
|
|
|
117
117
|
tags: list[str]
|
|
118
118
|
|
|
119
119
|
|
|
120
|
-
class
|
|
120
|
+
class TaskUpdate(BaseModel):
|
|
121
121
|
model_config = ConfigDict(extra="forbid")
|
|
122
122
|
|
|
123
123
|
command_parallel: NonEmptyStr = None
|
|
@@ -131,7 +131,7 @@ class TaskUpdateV2(BaseModel):
|
|
|
131
131
|
tags: ListUniqueNonEmptyString | None = None
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
class
|
|
134
|
+
class TaskImport(BaseModel):
|
|
135
135
|
model_config = ConfigDict(extra="forbid")
|
|
136
136
|
|
|
137
137
|
pkg_name: NonEmptyStr
|
|
@@ -139,11 +139,11 @@ class TaskImportV2(BaseModel):
|
|
|
139
139
|
name: NonEmptyStr
|
|
140
140
|
|
|
141
141
|
|
|
142
|
-
class
|
|
142
|
+
class TaskImportLegacy(BaseModel):
|
|
143
143
|
source: NonEmptyStr
|
|
144
144
|
|
|
145
145
|
|
|
146
|
-
class
|
|
146
|
+
class TaskExport(BaseModel):
|
|
147
147
|
pkg_name: NonEmptyStr
|
|
148
148
|
version: NonEmptyStr | None = None
|
|
149
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*
|
|
@@ -91,7 +91,7 @@ class TaskCollectPipV2(BaseModel):
|
|
|
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]
|
|
@@ -9,14 +9,14 @@ from fractal_server.types import DictStrAny
|
|
|
9
9
|
from fractal_server.types import TypeFilters
|
|
10
10
|
from fractal_server.types import WorkflowTaskArgument
|
|
11
11
|
|
|
12
|
-
from .task import
|
|
13
|
-
from .task import
|
|
14
|
-
from .task import
|
|
15
|
-
from .task import
|
|
12
|
+
from .task import TaskExport
|
|
13
|
+
from .task import TaskImport
|
|
14
|
+
from .task import TaskImportLegacy
|
|
15
|
+
from .task import TaskRead
|
|
16
16
|
from .task import TaskType
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class
|
|
19
|
+
class WorkflowTaskCreate(BaseModel):
|
|
20
20
|
model_config = ConfigDict(extra="forbid")
|
|
21
21
|
|
|
22
22
|
meta_non_parallel: DictStrAny | None = None
|
|
@@ -26,14 +26,14 @@ class WorkflowTaskCreateV2(BaseModel):
|
|
|
26
26
|
type_filters: TypeFilters = Field(default_factory=dict)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class
|
|
29
|
+
class WorkflowTaskReplace(BaseModel):
|
|
30
30
|
"""Used by 'replace-task' endpoint"""
|
|
31
31
|
|
|
32
32
|
args_non_parallel: dict[str, Any] | None = None
|
|
33
33
|
args_parallel: dict[str, Any] | None = None
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
class
|
|
36
|
+
class WorkflowTaskRead(BaseModel):
|
|
37
37
|
id: int
|
|
38
38
|
|
|
39
39
|
workflow_id: int
|
|
@@ -48,14 +48,14 @@ class WorkflowTaskReadV2(BaseModel):
|
|
|
48
48
|
|
|
49
49
|
task_type: TaskType
|
|
50
50
|
task_id: int
|
|
51
|
-
task:
|
|
51
|
+
task: TaskRead
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
class
|
|
54
|
+
class WorkflowTaskReadWithWarning(WorkflowTaskRead):
|
|
55
55
|
warning: str | None = None
|
|
56
56
|
|
|
57
57
|
|
|
58
|
-
class
|
|
58
|
+
class WorkflowTaskUpdate(BaseModel):
|
|
59
59
|
model_config = ConfigDict(extra="forbid")
|
|
60
60
|
|
|
61
61
|
meta_non_parallel: DictStrAny | None = None
|
|
@@ -65,7 +65,7 @@ class WorkflowTaskUpdateV2(BaseModel):
|
|
|
65
65
|
type_filters: TypeFilters = None
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
class
|
|
68
|
+
class WorkflowTaskImport(BaseModel):
|
|
69
69
|
model_config = ConfigDict(extra="forbid")
|
|
70
70
|
|
|
71
71
|
meta_non_parallel: DictStrAny | None = None
|
|
@@ -75,7 +75,7 @@ class WorkflowTaskImportV2(BaseModel):
|
|
|
75
75
|
type_filters: TypeFilters | None = None
|
|
76
76
|
input_filters: dict[str, Any] | None = None
|
|
77
77
|
|
|
78
|
-
task:
|
|
78
|
+
task: TaskImport | TaskImportLegacy
|
|
79
79
|
|
|
80
80
|
@model_validator(mode="before")
|
|
81
81
|
@classmethod
|
|
@@ -106,11 +106,11 @@ class WorkflowTaskImportV2(BaseModel):
|
|
|
106
106
|
return values
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
class
|
|
109
|
+
class WorkflowTaskExport(BaseModel):
|
|
110
110
|
meta_non_parallel: dict[str, Any] | None = None
|
|
111
111
|
meta_parallel: dict[str, Any] | None = None
|
|
112
112
|
args_non_parallel: dict[str, Any] | None = None
|
|
113
113
|
args_parallel: dict[str, Any] | None = None
|
|
114
114
|
type_filters: dict[str, bool] = Field(default_factory=dict)
|
|
115
115
|
|
|
116
|
-
task:
|
|
116
|
+
task: TaskExport
|
fractal_server/app/shutdown.py
CHANGED
|
@@ -4,26 +4,26 @@ from sqlmodel import select
|
|
|
4
4
|
|
|
5
5
|
from fractal_server.app.db import get_async_db
|
|
6
6
|
from fractal_server.app.models.v2 import JobV2
|
|
7
|
-
from fractal_server.app.models.v2.job import
|
|
7
|
+
from fractal_server.app.models.v2.job import JobStatusType
|
|
8
8
|
from fractal_server.app.routes.aux._job import _write_shutdown_file
|
|
9
9
|
from fractal_server.config import get_settings
|
|
10
10
|
from fractal_server.logger import get_logger
|
|
11
11
|
from fractal_server.syringe import Inject
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
async def cleanup_after_shutdown(*,
|
|
14
|
+
async def cleanup_after_shutdown(*, jobs: list[int], logger_name: str):
|
|
15
15
|
settings = Inject(get_settings)
|
|
16
16
|
logger = get_logger(logger_name)
|
|
17
17
|
logger.info("Cleanup function after shutdown")
|
|
18
18
|
stm_objects = (
|
|
19
19
|
select(JobV2)
|
|
20
|
-
.where(JobV2.id.in_(
|
|
21
|
-
.where(JobV2.status ==
|
|
20
|
+
.where(JobV2.id.in_(jobs))
|
|
21
|
+
.where(JobV2.status == JobStatusType.SUBMITTED)
|
|
22
22
|
)
|
|
23
23
|
stm_ids = (
|
|
24
24
|
select(JobV2.id)
|
|
25
|
-
.where(JobV2.id.in_(
|
|
26
|
-
.where(JobV2.status ==
|
|
25
|
+
.where(JobV2.id.in_(jobs))
|
|
26
|
+
.where(JobV2.status == JobStatusType.SUBMITTED)
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
async for session in get_async_db():
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from ._data import DataAuthScheme # noqa F401
|
|
2
|
-
from ._data import DataSettings
|
|
3
1
|
from ._database import DatabaseSettings
|
|
4
2
|
from ._email import EmailSettings
|
|
5
3
|
from ._email import PublicEmailSettings # noqa F401
|
|
@@ -21,7 +19,3 @@ def get_email_settings(email_settings=EmailSettings()) -> EmailSettings:
|
|
|
21
19
|
|
|
22
20
|
def get_oauth_settings(oauth_settings=OAuthSettings()) -> OAuthSettings:
|
|
23
21
|
return oauth_settings
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def get_data_settings(data_settings=DataSettings()) -> DataSettings:
|
|
27
|
-
return data_settings
|
fractal_server/config/_data.py
CHANGED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
from enum import StrEnum
|
|
2
|
-
from typing import Self
|
|
3
|
-
|
|
4
|
-
from pydantic import model_validator
|
|
5
|
-
from pydantic_settings import BaseSettings
|
|
6
|
-
from pydantic_settings import SettingsConfigDict
|
|
7
|
-
|
|
8
|
-
from fractal_server.types import AbsolutePathStr
|
|
9
|
-
|
|
10
|
-
from ._settings_config import SETTINGS_CONFIG_DICT
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class DataAuthScheme(StrEnum):
|
|
14
|
-
VIEWER_PATHS = "viewer-paths"
|
|
15
|
-
USERS_FOLDERS = "users-folders"
|
|
16
|
-
NONE = "none"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class DataSettings(BaseSettings):
|
|
20
|
-
"""
|
|
21
|
-
Settings for the `fractal-data` integration.
|
|
22
|
-
|
|
23
|
-
See https://github.com/fractal-analytics-platform/fractal-data.
|
|
24
|
-
|
|
25
|
-
Attributes:
|
|
26
|
-
FRACTAL_DATA_AUTH_SCHEME:
|
|
27
|
-
Defines how the list of allowed viewer paths is built.
|
|
28
|
-
|
|
29
|
-
This variable affects the
|
|
30
|
-
`GET /auth/current-user/allowed-viewer-paths/` response, which is
|
|
31
|
-
then consumed by
|
|
32
|
-
[fractal-data](https://github.com/fractal-analytics-platform/fractal-data).
|
|
33
|
-
|
|
34
|
-
Options:
|
|
35
|
-
<ul>
|
|
36
|
-
<li> `"viewer-paths"`: The list of allowed viewer paths will
|
|
37
|
-
include the user's `project_dir` along with any path
|
|
38
|
-
defined in UserGroups `viewer_paths` attributes.
|
|
39
|
-
</li>
|
|
40
|
-
<li> `"users-folders"`: The list will consist of the user's
|
|
41
|
-
`project_dir` and a user-specific folder. The user folder
|
|
42
|
-
is constructed by concatenating the base folder
|
|
43
|
-
`FRACTAL_DATA_BASE_FOLDER` with the user's profile
|
|
44
|
-
`username`.
|
|
45
|
-
</li>
|
|
46
|
-
<li> `"none"`: An empty list will be returned, indicating no
|
|
47
|
-
access to viewer paths. Useful when vizarr viewer is not
|
|
48
|
-
used.
|
|
49
|
-
</li>
|
|
50
|
-
</ul>
|
|
51
|
-
FRACTAL_DATA_BASE_FOLDER:
|
|
52
|
-
Base path to Zarr files that will be served by
|
|
53
|
-
fractal-vizarr-viewer.
|
|
54
|
-
This variable is required and used only when
|
|
55
|
-
`FRACTAL_DATA_AUTHORIZATION_SCHEME` is set to `"users-folders"`.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
59
|
-
|
|
60
|
-
FRACTAL_DATA_AUTH_SCHEME: DataAuthScheme = "none"
|
|
61
|
-
|
|
62
|
-
FRACTAL_DATA_BASE_FOLDER: AbsolutePathStr | None = None
|
|
63
|
-
|
|
64
|
-
@model_validator(mode="after")
|
|
65
|
-
def check(self: Self) -> Self:
|
|
66
|
-
"""
|
|
67
|
-
`FRACTAL_DATA_BASE_FOLDER` is required when
|
|
68
|
-
`FRACTAL_DATA_AUTHORIZATION_SCHEME` is set to `"users-folders"`.
|
|
69
|
-
"""
|
|
70
|
-
if (
|
|
71
|
-
self.FRACTAL_DATA_AUTH_SCHEME == DataAuthScheme.USERS_FOLDERS
|
|
72
|
-
and self.FRACTAL_DATA_BASE_FOLDER is None
|
|
73
|
-
):
|
|
74
|
-
raise ValueError(
|
|
75
|
-
"FRACTAL_DATA_BASE_FOLDER is required when "
|
|
76
|
-
"FRACTAL_DATA_AUTH_SCHEME is set to "
|
|
77
|
-
"users-folders"
|
|
78
|
-
)
|
|
79
|
-
return self
|
fractal_server/config/_main.py
CHANGED
|
@@ -28,7 +28,7 @@ class Settings(BaseSettings):
|
|
|
28
28
|
Only logs of with this level (or higher) will appear in the console
|
|
29
29
|
logs.
|
|
30
30
|
FRACTAL_API_MAX_JOB_LIST_LENGTH:
|
|
31
|
-
Number of ids that can be stored in the `
|
|
31
|
+
Number of ids that can be stored in the `jobs` attribute of
|
|
32
32
|
`app.state`.
|
|
33
33
|
FRACTAL_GRACEFUL_SHUTDOWN_TIME:
|
|
34
34
|
Waiting time for the shutdown phase of executors, in seconds.
|
|
@@ -41,6 +41,10 @@ class Settings(BaseSettings):
|
|
|
41
41
|
user group (e.g. it cannot be deleted, and new users are
|
|
42
42
|
automatically added to it). If set to `None` (the default value),
|
|
43
43
|
then user groups are all equivalent, independently on their name.
|
|
44
|
+
FRACTAL_LONG_REQUEST_TIME:
|
|
45
|
+
Time limit beyond which the execution of an API request is
|
|
46
|
+
considered *slow* and an appropriate warning is logged by the
|
|
47
|
+
middleware.
|
|
44
48
|
"""
|
|
45
49
|
|
|
46
50
|
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
@@ -57,3 +61,4 @@ class Settings(BaseSettings):
|
|
|
57
61
|
FRACTAL_GRACEFUL_SHUTDOWN_TIME: float = 30.0
|
|
58
62
|
FRACTAL_HELP_URL: HttpUrl | None = None
|
|
59
63
|
FRACTAL_DEFAULT_GROUP_NAME: Literal["All"] | None = None
|
|
64
|
+
FRACTAL_LONG_REQUEST_TIME: float = 30.0
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
from os.path import normpath
|
|
4
|
+
|
|
5
|
+
from sqlalchemy.orm.attributes import flag_modified
|
|
6
|
+
from sqlmodel import select
|
|
7
|
+
|
|
8
|
+
from fractal_server.app.db import get_sync_db
|
|
9
|
+
from fractal_server.app.models import UserOAuth
|
|
10
|
+
|
|
11
|
+
logging.basicConfig(level=logging.INFO)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def fix_db():
|
|
15
|
+
logging.info("START - fix db")
|
|
16
|
+
|
|
17
|
+
with next(get_sync_db()) as db:
|
|
18
|
+
res = db.execute(select(UserOAuth).order_by(UserOAuth.email))
|
|
19
|
+
user_list = res.scalars().unique().all()
|
|
20
|
+
|
|
21
|
+
for user in user_list:
|
|
22
|
+
logging.info(f"Now handling user {user.email}.")
|
|
23
|
+
if user.project_dirs != []:
|
|
24
|
+
sys.exit(f"Non empty `project_dirs` for User[{user.id}]")
|
|
25
|
+
user.project_dirs.append(normpath(user.project_dir))
|
|
26
|
+
flag_modified(user, "project_dirs")
|
|
27
|
+
|
|
28
|
+
db.commit()
|
|
29
|
+
|
|
30
|
+
logging.info("END - fix db")
|
fractal_server/images/models.py
CHANGED
|
@@ -5,7 +5,6 @@ from fractal_server.types import DictStrAny
|
|
|
5
5
|
from fractal_server.types import ImageAttributes
|
|
6
6
|
from fractal_server.types import ImageAttributesWithNone
|
|
7
7
|
from fractal_server.types import ImageTypes
|
|
8
|
-
from fractal_server.types import ZarrDirStr
|
|
9
8
|
from fractal_server.types import ZarrUrlStr
|
|
10
9
|
|
|
11
10
|
|
|
@@ -21,7 +20,7 @@ class SingleImageBase(BaseModel):
|
|
|
21
20
|
"""
|
|
22
21
|
|
|
23
22
|
zarr_url: ZarrUrlStr
|
|
24
|
-
origin:
|
|
23
|
+
origin: ZarrUrlStr | None = None
|
|
25
24
|
|
|
26
25
|
attributes: DictStrAny = Field(default_factory=dict)
|
|
27
26
|
types: ImageTypes = Field(default_factory=dict)
|