fractal-server 2.14.5__py3-none-any.whl → 2.14.7__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/app/db/__init__.py +2 -2
- fractal_server/app/models/security.py +8 -8
- fractal_server/app/models/user_settings.py +8 -10
- fractal_server/app/models/v2/accounting.py +2 -3
- fractal_server/app/models/v2/dataset.py +1 -2
- fractal_server/app/models/v2/history.py +3 -4
- fractal_server/app/models/v2/job.py +10 -11
- fractal_server/app/models/v2/project.py +1 -2
- fractal_server/app/models/v2/task.py +13 -14
- fractal_server/app/models/v2/task_group.py +15 -16
- fractal_server/app/models/v2/workflow.py +1 -2
- fractal_server/app/models/v2/workflowtask.py +6 -7
- fractal_server/app/routes/admin/v2/accounting.py +3 -4
- fractal_server/app/routes/admin/v2/job.py +13 -14
- fractal_server/app/routes/admin/v2/project.py +2 -4
- fractal_server/app/routes/admin/v2/task.py +11 -13
- fractal_server/app/routes/admin/v2/task_group.py +15 -17
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +5 -8
- fractal_server/app/routes/api/v2/__init__.py +2 -0
- fractal_server/app/routes/api/v2/_aux_functions.py +7 -9
- fractal_server/app/routes/api/v2/_aux_functions_history.py +1 -1
- fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +1 -3
- fractal_server/app/routes/api/v2/_aux_functions_tasks.py +5 -6
- fractal_server/app/routes/api/v2/dataset.py +6 -8
- fractal_server/app/routes/api/v2/history.py +5 -8
- fractal_server/app/routes/api/v2/images.py +2 -3
- fractal_server/app/routes/api/v2/job.py +5 -6
- fractal_server/app/routes/api/v2/pre_submission_checks.py +1 -3
- fractal_server/app/routes/api/v2/project.py +2 -4
- fractal_server/app/routes/api/v2/status_legacy.py +2 -4
- fractal_server/app/routes/api/v2/submit.py +3 -4
- fractal_server/app/routes/api/v2/task.py +6 -7
- fractal_server/app/routes/api/v2/task_collection.py +11 -13
- fractal_server/app/routes/api/v2/task_collection_custom.py +4 -4
- fractal_server/app/routes/api/v2/task_group.py +6 -8
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +6 -9
- fractal_server/app/routes/api/v2/task_version_update.py +270 -0
- fractal_server/app/routes/api/v2/workflow.py +5 -6
- fractal_server/app/routes/api/v2/workflow_import.py +3 -5
- fractal_server/app/routes/api/v2/workflowtask.py +2 -114
- fractal_server/app/routes/auth/current_user.py +2 -2
- fractal_server/app/routes/pagination.py +2 -3
- fractal_server/app/runner/exceptions.py +15 -16
- fractal_server/app/runner/executors/base_runner.py +3 -3
- fractal_server/app/runner/executors/call_command_wrapper.py +1 -1
- fractal_server/app/runner/executors/local/get_local_config.py +2 -3
- fractal_server/app/runner/executors/local/runner.py +1 -1
- fractal_server/app/runner/executors/slurm_common/_batching.py +2 -3
- fractal_server/app/runner/executors/slurm_common/_slurm_config.py +27 -29
- fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +32 -14
- fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +2 -3
- fractal_server/app/runner/executors/slurm_common/remote.py +2 -2
- fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/runner.py +5 -4
- fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -2
- fractal_server/app/runner/executors/slurm_sudo/runner.py +7 -8
- fractal_server/app/runner/set_start_and_last_task_index.py +2 -5
- fractal_server/app/runner/shutdown.py +5 -11
- fractal_server/app/runner/task_files.py +3 -5
- fractal_server/app/runner/v2/_local.py +3 -4
- fractal_server/app/runner/v2/_slurm_ssh.py +8 -7
- fractal_server/app/runner/v2/_slurm_sudo.py +8 -9
- fractal_server/app/runner/v2/runner.py +4 -5
- fractal_server/app/runner/v2/runner_functions.py +4 -5
- fractal_server/app/runner/v2/submit_workflow.py +12 -11
- fractal_server/app/runner/v2/task_interface.py +2 -3
- fractal_server/app/runner/versions.py +1 -2
- fractal_server/app/schemas/user.py +2 -4
- fractal_server/app/schemas/user_group.py +1 -2
- fractal_server/app/schemas/user_settings.py +19 -21
- fractal_server/app/schemas/v2/dataset.py +2 -3
- fractal_server/app/schemas/v2/dumps.py +13 -15
- fractal_server/app/schemas/v2/history.py +6 -7
- fractal_server/app/schemas/v2/job.py +17 -18
- fractal_server/app/schemas/v2/manifest.py +12 -13
- fractal_server/app/schemas/v2/status_legacy.py +2 -2
- fractal_server/app/schemas/v2/task.py +29 -30
- fractal_server/app/schemas/v2/task_collection.py +8 -9
- fractal_server/app/schemas/v2/task_group.py +22 -23
- fractal_server/app/schemas/v2/workflow.py +1 -2
- fractal_server/app/schemas/v2/workflowtask.py +27 -29
- fractal_server/app/security/__init__.py +10 -12
- fractal_server/config.py +32 -33
- fractal_server/images/models.py +2 -4
- fractal_server/images/tools.py +4 -7
- fractal_server/logger.py +3 -5
- fractal_server/ssh/_fabric.py +37 -12
- fractal_server/string_tools.py +2 -2
- fractal_server/syringe.py +1 -1
- fractal_server/tasks/v2/local/collect.py +2 -3
- fractal_server/tasks/v2/local/deactivate.py +1 -1
- fractal_server/tasks/v2/local/reactivate.py +1 -1
- fractal_server/tasks/v2/ssh/collect.py +256 -245
- fractal_server/tasks/v2/ssh/deactivate.py +210 -187
- fractal_server/tasks/v2/ssh/reactivate.py +154 -146
- fractal_server/tasks/v2/utils_background.py +2 -3
- fractal_server/types/__init__.py +1 -2
- fractal_server/types/validators/_filter_validators.py +1 -2
- fractal_server/utils.py +4 -5
- fractal_server/zip_tools.py +1 -1
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/METADATA +2 -3
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/RECORD +107 -107
- fractal_server/app/history/__init__.py +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/LICENSE +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/WHEEL +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,5 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from enum import
|
3
|
-
from typing import Optional
|
2
|
+
from enum import StrEnum
|
4
3
|
|
5
4
|
from pydantic import BaseModel
|
6
5
|
from pydantic import ConfigDict
|
@@ -14,20 +13,20 @@ from fractal_server.types import DictStrStr
|
|
14
13
|
from fractal_server.types import NonEmptyStr
|
15
14
|
|
16
15
|
|
17
|
-
class TaskGroupV2OriginEnum(
|
16
|
+
class TaskGroupV2OriginEnum(StrEnum):
|
18
17
|
PYPI = "pypi"
|
19
18
|
WHEELFILE = "wheel-file"
|
20
19
|
OTHER = "other"
|
21
20
|
|
22
21
|
|
23
|
-
class TaskGroupActivityStatusV2(
|
22
|
+
class TaskGroupActivityStatusV2(StrEnum):
|
24
23
|
PENDING = "pending"
|
25
24
|
ONGOING = "ongoing"
|
26
25
|
FAILED = "failed"
|
27
26
|
OK = "OK"
|
28
27
|
|
29
28
|
|
30
|
-
class TaskGroupActivityActionV2(
|
29
|
+
class TaskGroupActivityActionV2(StrEnum):
|
31
30
|
COLLECT = "collect"
|
32
31
|
DEACTIVATE = "deactivate"
|
33
32
|
REACTIVATE = "reactivate"
|
@@ -36,17 +35,17 @@ class TaskGroupActivityActionV2(str, Enum):
|
|
36
35
|
class TaskGroupCreateV2(BaseModel):
|
37
36
|
model_config = ConfigDict(extra="forbid")
|
38
37
|
user_id: int
|
39
|
-
user_group_id:
|
38
|
+
user_group_id: int | None = None
|
40
39
|
active: bool = True
|
41
40
|
origin: TaskGroupV2OriginEnum
|
42
41
|
pkg_name: str
|
43
|
-
version:
|
42
|
+
version: str | None = None
|
44
43
|
python_version: NonEmptyStr = None
|
45
44
|
path: AbsolutePathStr = None
|
46
45
|
venv_path: AbsolutePathStr = None
|
47
46
|
wheel_path: AbsolutePathStr = None
|
48
47
|
pip_extras: NonEmptyStr = None
|
49
|
-
pip_freeze:
|
48
|
+
pip_freeze: str | None = None
|
50
49
|
pinned_package_versions: DictStrStr = Field(default_factory=dict)
|
51
50
|
|
52
51
|
|
@@ -66,21 +65,21 @@ class TaskGroupReadV2(BaseModel):
|
|
66
65
|
task_list: list[TaskReadV2]
|
67
66
|
|
68
67
|
user_id: int
|
69
|
-
user_group_id:
|
68
|
+
user_group_id: int | None = None
|
70
69
|
|
71
70
|
origin: TaskGroupV2OriginEnum
|
72
71
|
pkg_name: str
|
73
|
-
version:
|
74
|
-
python_version:
|
75
|
-
path:
|
76
|
-
venv_path:
|
77
|
-
wheel_path:
|
78
|
-
pip_freeze:
|
79
|
-
pip_extras:
|
72
|
+
version: str | None = None
|
73
|
+
python_version: str | None = None
|
74
|
+
path: str | None = None
|
75
|
+
venv_path: str | None = None
|
76
|
+
wheel_path: str | None = None
|
77
|
+
pip_freeze: str | None = None
|
78
|
+
pip_extras: str | None = None
|
80
79
|
pinned_package_versions: dict[str, str] = Field(default_factory=dict)
|
81
80
|
|
82
|
-
venv_size_in_kB:
|
83
|
-
venv_file_number:
|
81
|
+
venv_size_in_kB: int | None = None
|
82
|
+
venv_file_number: int | None = None
|
84
83
|
|
85
84
|
active: bool
|
86
85
|
timestamp_created: AwareDatetime
|
@@ -93,27 +92,27 @@ class TaskGroupReadV2(BaseModel):
|
|
93
92
|
|
94
93
|
class TaskGroupUpdateV2(BaseModel):
|
95
94
|
model_config = ConfigDict(extra="forbid")
|
96
|
-
user_group_id:
|
95
|
+
user_group_id: int | None = None
|
97
96
|
|
98
97
|
|
99
98
|
class TaskGroupActivityV2Read(BaseModel):
|
100
99
|
id: int
|
101
100
|
user_id: int
|
102
|
-
taskgroupv2_id:
|
101
|
+
taskgroupv2_id: int | None = None
|
103
102
|
timestamp_started: AwareDatetime
|
104
|
-
timestamp_ended:
|
103
|
+
timestamp_ended: AwareDatetime | None = None
|
105
104
|
pkg_name: str
|
106
105
|
version: str
|
107
106
|
status: TaskGroupActivityStatusV2
|
108
107
|
action: TaskGroupActivityActionV2
|
109
|
-
log:
|
108
|
+
log: str | None = None
|
110
109
|
|
111
110
|
@field_serializer("timestamp_started")
|
112
111
|
def serialize_datetime_start(v: datetime) -> str:
|
113
112
|
return v.isoformat()
|
114
113
|
|
115
114
|
@field_serializer("timestamp_ended")
|
116
|
-
def serialize_datetime_end(v:
|
115
|
+
def serialize_datetime_end(v: datetime | None) -> str | None:
|
117
116
|
if v is None:
|
118
117
|
return None
|
119
118
|
else:
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import Optional
|
3
2
|
|
4
3
|
from pydantic import BaseModel
|
5
4
|
from pydantic import ConfigDict
|
@@ -47,7 +46,7 @@ class WorkflowUpdateV2(BaseModel):
|
|
47
46
|
model_config = ConfigDict(extra="forbid")
|
48
47
|
|
49
48
|
name: NonEmptyStr = None
|
50
|
-
reordered_workflowtask_ids:
|
49
|
+
reordered_workflowtask_ids: ListUniqueNonNegativeInt | None = None
|
51
50
|
|
52
51
|
|
53
52
|
class WorkflowImportV2(BaseModel):
|
@@ -1,6 +1,4 @@
|
|
1
1
|
from typing import Any
|
2
|
-
from typing import Optional
|
3
|
-
from typing import Union
|
4
2
|
|
5
3
|
from pydantic import BaseModel
|
6
4
|
from pydantic import ConfigDict
|
@@ -20,30 +18,30 @@ from fractal_server.types import WorkflowTaskArgument
|
|
20
18
|
class WorkflowTaskCreateV2(BaseModel):
|
21
19
|
model_config = ConfigDict(extra="forbid")
|
22
20
|
|
23
|
-
meta_non_parallel:
|
24
|
-
meta_parallel:
|
25
|
-
args_non_parallel:
|
26
|
-
args_parallel:
|
21
|
+
meta_non_parallel: DictStrAny | None = None
|
22
|
+
meta_parallel: DictStrAny | None = None
|
23
|
+
args_non_parallel: WorkflowTaskArgument | None = None
|
24
|
+
args_parallel: WorkflowTaskArgument | None = None
|
27
25
|
type_filters: TypeFilters = Field(default_factory=dict)
|
28
26
|
|
29
27
|
|
30
28
|
class WorkflowTaskReplaceV2(BaseModel):
|
31
29
|
"""Used by 'replace-task' endpoint"""
|
32
30
|
|
33
|
-
args_non_parallel:
|
34
|
-
args_parallel:
|
31
|
+
args_non_parallel: dict[str, Any] | None = None
|
32
|
+
args_parallel: dict[str, Any] | None = None
|
35
33
|
|
36
34
|
|
37
35
|
class WorkflowTaskReadV2(BaseModel):
|
38
36
|
id: int
|
39
37
|
|
40
38
|
workflow_id: int
|
41
|
-
order:
|
42
|
-
meta_non_parallel:
|
43
|
-
meta_parallel:
|
39
|
+
order: int | None = None
|
40
|
+
meta_non_parallel: dict[str, Any] | None = None
|
41
|
+
meta_parallel: dict[str, Any] | None = None
|
44
42
|
|
45
|
-
args_non_parallel:
|
46
|
-
args_parallel:
|
43
|
+
args_non_parallel: dict[str, Any] | None = None
|
44
|
+
args_parallel: dict[str, Any] | None = None
|
47
45
|
|
48
46
|
type_filters: dict[str, bool]
|
49
47
|
|
@@ -53,30 +51,30 @@ class WorkflowTaskReadV2(BaseModel):
|
|
53
51
|
|
54
52
|
|
55
53
|
class WorkflowTaskReadV2WithWarning(WorkflowTaskReadV2):
|
56
|
-
warning:
|
54
|
+
warning: str | None = None
|
57
55
|
|
58
56
|
|
59
57
|
class WorkflowTaskUpdateV2(BaseModel):
|
60
58
|
model_config = ConfigDict(extra="forbid")
|
61
59
|
|
62
|
-
meta_non_parallel:
|
63
|
-
meta_parallel:
|
64
|
-
args_non_parallel:
|
65
|
-
args_parallel:
|
60
|
+
meta_non_parallel: DictStrAny | None = None
|
61
|
+
meta_parallel: DictStrAny | None = None
|
62
|
+
args_non_parallel: WorkflowTaskArgument | None = None
|
63
|
+
args_parallel: WorkflowTaskArgument | None = None
|
66
64
|
type_filters: TypeFilters = None
|
67
65
|
|
68
66
|
|
69
67
|
class WorkflowTaskImportV2(BaseModel):
|
70
68
|
model_config = ConfigDict(extra="forbid")
|
71
69
|
|
72
|
-
meta_non_parallel:
|
73
|
-
meta_parallel:
|
74
|
-
args_non_parallel:
|
75
|
-
args_parallel:
|
76
|
-
type_filters:
|
77
|
-
input_filters:
|
70
|
+
meta_non_parallel: DictStrAny | None = None
|
71
|
+
meta_parallel: DictStrAny | None = None
|
72
|
+
args_non_parallel: DictStrAny | None = None
|
73
|
+
args_parallel: DictStrAny | None = None
|
74
|
+
type_filters: TypeFilters | None = None
|
75
|
+
input_filters: dict[str, Any] | None = None
|
78
76
|
|
79
|
-
task:
|
77
|
+
task: TaskImportV2 | TaskImportV2Legacy
|
80
78
|
|
81
79
|
@model_validator(mode="before")
|
82
80
|
@classmethod
|
@@ -108,10 +106,10 @@ class WorkflowTaskImportV2(BaseModel):
|
|
108
106
|
|
109
107
|
|
110
108
|
class WorkflowTaskExportV2(BaseModel):
|
111
|
-
meta_non_parallel:
|
112
|
-
meta_parallel:
|
113
|
-
args_non_parallel:
|
114
|
-
args_parallel:
|
109
|
+
meta_non_parallel: dict[str, Any] | None = None
|
110
|
+
meta_parallel: dict[str, Any] | None = None
|
111
|
+
args_non_parallel: dict[str, Any] | None = None
|
112
|
+
args_parallel: dict[str, Any] | None = None
|
115
113
|
type_filters: dict[str, bool] = Field(default_factory=dict)
|
116
114
|
|
117
115
|
task: TaskExportV2
|
@@ -27,11 +27,9 @@ registers the client and the relative routes.
|
|
27
27
|
All routes are registered under the `auth/` prefix.
|
28
28
|
"""
|
29
29
|
import contextlib
|
30
|
+
from collections.abc import AsyncGenerator
|
30
31
|
from typing import Any
|
31
|
-
from typing import AsyncGenerator
|
32
32
|
from typing import Generic
|
33
|
-
from typing import Optional
|
34
|
-
from typing import Type
|
35
33
|
|
36
34
|
from fastapi import Depends
|
37
35
|
from fastapi import Request
|
@@ -82,24 +80,24 @@ class SQLModelUserDatabaseAsync(Generic[UP, ID], BaseUserDatabase[UP, ID]):
|
|
82
80
|
"""
|
83
81
|
|
84
82
|
session: AsyncSession
|
85
|
-
user_model:
|
86
|
-
oauth_account_model:
|
83
|
+
user_model: type[UP]
|
84
|
+
oauth_account_model: type[OAuthAccount] | None = None
|
87
85
|
|
88
86
|
def __init__(
|
89
87
|
self,
|
90
88
|
session: AsyncSession,
|
91
|
-
user_model:
|
92
|
-
oauth_account_model:
|
89
|
+
user_model: type[UP],
|
90
|
+
oauth_account_model: type[OAuthAccount] | None = None,
|
93
91
|
):
|
94
92
|
self.session = session
|
95
93
|
self.user_model = user_model
|
96
94
|
self.oauth_account_model = oauth_account_model
|
97
95
|
|
98
|
-
async def get(self, id: ID) ->
|
96
|
+
async def get(self, id: ID) -> UP | None:
|
99
97
|
"""Get a single user by id."""
|
100
98
|
return await self.session.get(self.user_model, id)
|
101
99
|
|
102
|
-
async def get_by_email(self, email: str) ->
|
100
|
+
async def get_by_email(self, email: str) -> UP | None:
|
103
101
|
"""Get a single user by email."""
|
104
102
|
statement = select(self.user_model).where(
|
105
103
|
func.lower(self.user_model.email) == func.lower(email)
|
@@ -112,7 +110,7 @@ class SQLModelUserDatabaseAsync(Generic[UP, ID], BaseUserDatabase[UP, ID]):
|
|
112
110
|
|
113
111
|
async def get_by_oauth_account(
|
114
112
|
self, oauth: str, account_id: str
|
115
|
-
) ->
|
113
|
+
) -> UP | None: # noqa
|
116
114
|
"""Get a single user by OAuth account id."""
|
117
115
|
if self.oauth_account_model is None:
|
118
116
|
raise NotImplementedError()
|
@@ -212,7 +210,7 @@ class UserManager(IntegerIDMixin, BaseUserManager[UserOAuth, int]):
|
|
212
210
|
)
|
213
211
|
|
214
212
|
async def on_after_register(
|
215
|
-
self, user: UserOAuth, request:
|
213
|
+
self, user: UserOAuth, request: Request | None = None
|
216
214
|
):
|
217
215
|
logger.info(
|
218
216
|
f"New-user registration completed ({user.id=}, {user.email=})."
|
@@ -290,7 +288,7 @@ async def _create_first_user(
|
|
290
288
|
password: str,
|
291
289
|
is_superuser: bool = False,
|
292
290
|
is_verified: bool = False,
|
293
|
-
username:
|
291
|
+
username: str | None = None,
|
294
292
|
) -> None:
|
295
293
|
"""
|
296
294
|
Private method to create the first fractal-server user
|
fractal_server/config.py
CHANGED
@@ -18,7 +18,6 @@ from os import environ
|
|
18
18
|
from os import getenv
|
19
19
|
from pathlib import Path
|
20
20
|
from typing import Literal
|
21
|
-
from typing import Optional
|
22
21
|
from typing import TypeVar
|
23
22
|
|
24
23
|
from cryptography.fernet import Fernet
|
@@ -56,8 +55,8 @@ class MailSettings(BaseModel):
|
|
56
55
|
recipients: list[EmailStr] = Field(min_length=1)
|
57
56
|
smtp_server: str
|
58
57
|
port: int
|
59
|
-
encrypted_password:
|
60
|
-
encryption_key:
|
58
|
+
encrypted_password: SecretStr | None = None
|
59
|
+
encryption_key: SecretStr | None = None
|
61
60
|
instance_name: str
|
62
61
|
use_starttls: bool
|
63
62
|
use_login: bool
|
@@ -100,8 +99,8 @@ class OAuthClientConfig(BaseModel):
|
|
100
99
|
CLIENT_NAME: str
|
101
100
|
CLIENT_ID: str
|
102
101
|
CLIENT_SECRET: SecretStr
|
103
|
-
OIDC_CONFIGURATION_ENDPOINT:
|
104
|
-
REDIRECT_URL:
|
102
|
+
OIDC_CONFIGURATION_ENDPOINT: str | None = None
|
103
|
+
REDIRECT_URL: str | None = None
|
105
104
|
|
106
105
|
@model_validator(mode="before")
|
107
106
|
@classmethod
|
@@ -139,7 +138,7 @@ class Settings(BaseSettings):
|
|
139
138
|
JWT token lifetime, in seconds.
|
140
139
|
"""
|
141
140
|
|
142
|
-
JWT_SECRET_KEY:
|
141
|
+
JWT_SECRET_KEY: SecretStr | None = None
|
143
142
|
"""
|
144
143
|
JWT secret
|
145
144
|
|
@@ -202,23 +201,23 @@ class Settings(BaseSettings):
|
|
202
201
|
"""
|
203
202
|
If `True`, make database operations verbose.
|
204
203
|
"""
|
205
|
-
POSTGRES_USER:
|
204
|
+
POSTGRES_USER: str | None = None
|
206
205
|
"""
|
207
206
|
User to use when connecting to the PostgreSQL database.
|
208
207
|
"""
|
209
|
-
POSTGRES_PASSWORD:
|
208
|
+
POSTGRES_PASSWORD: SecretStr | None = None
|
210
209
|
"""
|
211
210
|
Password to use when connecting to the PostgreSQL database.
|
212
211
|
"""
|
213
|
-
POSTGRES_HOST:
|
212
|
+
POSTGRES_HOST: str | None = "localhost"
|
214
213
|
"""
|
215
214
|
URL to the PostgreSQL server or path to a UNIX domain socket.
|
216
215
|
"""
|
217
|
-
POSTGRES_PORT:
|
216
|
+
POSTGRES_PORT: str | None = "5432"
|
218
217
|
"""
|
219
218
|
Port number to use when connecting to the PostgreSQL server.
|
220
219
|
"""
|
221
|
-
POSTGRES_DB:
|
220
|
+
POSTGRES_DB: str | None = None
|
222
221
|
"""
|
223
222
|
Name of the PostgreSQL database to connect to.
|
224
223
|
"""
|
@@ -275,13 +274,13 @@ class Settings(BaseSettings):
|
|
275
274
|
default admin credentials.
|
276
275
|
"""
|
277
276
|
|
278
|
-
FRACTAL_TASKS_DIR:
|
277
|
+
FRACTAL_TASKS_DIR: Path | None = None
|
279
278
|
"""
|
280
279
|
Directory under which all the tasks will be saved (either an absolute path
|
281
280
|
or a path relative to current working directory).
|
282
281
|
"""
|
283
282
|
|
284
|
-
FRACTAL_RUNNER_WORKING_BASE_DIR:
|
283
|
+
FRACTAL_RUNNER_WORKING_BASE_DIR: Path | None = None
|
285
284
|
"""
|
286
285
|
Base directory for job files (either an absolute path or a path relative to
|
287
286
|
current working directory).
|
@@ -293,7 +292,7 @@ class Settings(BaseSettings):
|
|
293
292
|
mode="after",
|
294
293
|
)
|
295
294
|
@classmethod
|
296
|
-
def make_paths_absolute(cls, path:
|
295
|
+
def make_paths_absolute(cls, path: Path | None) -> Path | None:
|
297
296
|
if path is None or path.is_absolute():
|
298
297
|
return path
|
299
298
|
else:
|
@@ -319,7 +318,7 @@ class Settings(BaseSettings):
|
|
319
318
|
Only logs of with this level (or higher) will appear in the console logs.
|
320
319
|
"""
|
321
320
|
|
322
|
-
FRACTAL_LOCAL_CONFIG_FILE:
|
321
|
+
FRACTAL_LOCAL_CONFIG_FILE: Path | None = None
|
323
322
|
"""
|
324
323
|
Path of JSON file with configuration for the local backend.
|
325
324
|
"""
|
@@ -335,27 +334,27 @@ class Settings(BaseSettings):
|
|
335
334
|
Waiting time for the shutdown phase of executors
|
336
335
|
"""
|
337
336
|
|
338
|
-
FRACTAL_SLURM_CONFIG_FILE:
|
337
|
+
FRACTAL_SLURM_CONFIG_FILE: Path | None = None
|
339
338
|
"""
|
340
339
|
Path of JSON file with configuration for the SLURM backend.
|
341
340
|
"""
|
342
341
|
|
343
|
-
FRACTAL_SLURM_WORKER_PYTHON:
|
342
|
+
FRACTAL_SLURM_WORKER_PYTHON: AbsolutePathStr | None = None
|
344
343
|
"""
|
345
344
|
Absolute path to Python interpreter that will run the jobs on the SLURM
|
346
345
|
nodes. If not specified, the same interpreter that runs the server is used.
|
347
346
|
"""
|
348
347
|
|
349
|
-
FRACTAL_TASKS_PYTHON_DEFAULT_VERSION:
|
348
|
+
FRACTAL_TASKS_PYTHON_DEFAULT_VERSION: None | (
|
350
349
|
Literal["3.9", "3.10", "3.11", "3.12"]
|
351
|
-
|
350
|
+
) = None
|
352
351
|
"""
|
353
352
|
Default Python version to be used for task collection. Defaults to the
|
354
353
|
current version. Requires the corresponding variable (e.g
|
355
354
|
`FRACTAL_TASKS_PYTHON_3_10`) to be set.
|
356
355
|
"""
|
357
356
|
|
358
|
-
FRACTAL_TASKS_PYTHON_3_9:
|
357
|
+
FRACTAL_TASKS_PYTHON_3_9: str | None = None
|
359
358
|
"""
|
360
359
|
Absolute path to the Python 3.9 interpreter that serves as base for virtual
|
361
360
|
environments tasks. Note that this interpreter must have the `venv` module
|
@@ -364,17 +363,17 @@ class Settings(BaseSettings):
|
|
364
363
|
unset, `sys.executable` is used as a default.
|
365
364
|
"""
|
366
365
|
|
367
|
-
FRACTAL_TASKS_PYTHON_3_10:
|
366
|
+
FRACTAL_TASKS_PYTHON_3_10: str | None = None
|
368
367
|
"""
|
369
368
|
Same as `FRACTAL_TASKS_PYTHON_3_9`, for Python 3.10.
|
370
369
|
"""
|
371
370
|
|
372
|
-
FRACTAL_TASKS_PYTHON_3_11:
|
371
|
+
FRACTAL_TASKS_PYTHON_3_11: str | None = None
|
373
372
|
"""
|
374
373
|
Same as `FRACTAL_TASKS_PYTHON_3_9`, for Python 3.11.
|
375
374
|
"""
|
376
375
|
|
377
|
-
FRACTAL_TASKS_PYTHON_3_12:
|
376
|
+
FRACTAL_TASKS_PYTHON_3_12: str | None = None
|
378
377
|
"""
|
379
378
|
Same as `FRACTAL_TASKS_PYTHON_3_9`, for Python 3.12.
|
380
379
|
"""
|
@@ -460,7 +459,7 @@ class Settings(BaseSettings):
|
|
460
459
|
running a task that produces multiple SLURM jobs.
|
461
460
|
"""
|
462
461
|
|
463
|
-
FRACTAL_PIP_CACHE_DIR:
|
462
|
+
FRACTAL_PIP_CACHE_DIR: AbsolutePathStr | None = None
|
464
463
|
"""
|
465
464
|
Absolute path to the cache directory for `pip`; if unset,
|
466
465
|
`--no-cache-dir` is used.
|
@@ -507,7 +506,7 @@ class Settings(BaseSettings):
|
|
507
506
|
viewer paths. Useful when vizarr viewer is not used.
|
508
507
|
"""
|
509
508
|
|
510
|
-
FRACTAL_VIEWER_BASE_FOLDER:
|
509
|
+
FRACTAL_VIEWER_BASE_FOLDER: str | None = None
|
511
510
|
"""
|
512
511
|
Base path to Zarr files that will be served by fractal-vizarr-viewer;
|
513
512
|
This variable is required and used only when
|
@@ -518,31 +517,31 @@ class Settings(BaseSettings):
|
|
518
517
|
# SMTP SERVICE
|
519
518
|
###########################################################################
|
520
519
|
|
521
|
-
FRACTAL_EMAIL_SENDER:
|
520
|
+
FRACTAL_EMAIL_SENDER: EmailStr | None = None
|
522
521
|
"""
|
523
522
|
Address of the OAuth-signup email sender.
|
524
523
|
"""
|
525
|
-
FRACTAL_EMAIL_PASSWORD:
|
524
|
+
FRACTAL_EMAIL_PASSWORD: SecretStr | None = None
|
526
525
|
"""
|
527
526
|
Password for the OAuth-signup email sender.
|
528
527
|
"""
|
529
|
-
FRACTAL_EMAIL_PASSWORD_KEY:
|
528
|
+
FRACTAL_EMAIL_PASSWORD_KEY: SecretStr | None = None
|
530
529
|
"""
|
531
530
|
Key value for `cryptography.fernet` decrypt
|
532
531
|
"""
|
533
|
-
FRACTAL_EMAIL_SMTP_SERVER:
|
532
|
+
FRACTAL_EMAIL_SMTP_SERVER: str | None = None
|
534
533
|
"""
|
535
534
|
SMTP server for the OAuth-signup emails.
|
536
535
|
"""
|
537
|
-
FRACTAL_EMAIL_SMTP_PORT:
|
536
|
+
FRACTAL_EMAIL_SMTP_PORT: int | None = None
|
538
537
|
"""
|
539
538
|
SMTP server port for the OAuth-signup emails.
|
540
539
|
"""
|
541
|
-
FRACTAL_EMAIL_INSTANCE_NAME:
|
540
|
+
FRACTAL_EMAIL_INSTANCE_NAME: str | None = None
|
542
541
|
"""
|
543
542
|
Fractal instance name, to be included in the OAuth-signup emails.
|
544
543
|
"""
|
545
|
-
FRACTAL_EMAIL_RECIPIENTS:
|
544
|
+
FRACTAL_EMAIL_RECIPIENTS: str | None = None
|
546
545
|
"""
|
547
546
|
Comma-separated list of recipients of the OAuth-signup emails.
|
548
547
|
"""
|
@@ -558,7 +557,7 @@ class Settings(BaseSettings):
|
|
558
557
|
provided.
|
559
558
|
Accepted values: 'true', 'false'.
|
560
559
|
"""
|
561
|
-
email_settings:
|
560
|
+
email_settings: MailSettings | None = None
|
562
561
|
|
563
562
|
@model_validator(mode="after")
|
564
563
|
def validate_email_settings(self):
|
fractal_server/images/models.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import Optional
|
2
|
-
|
3
1
|
from pydantic import BaseModel
|
4
2
|
from pydantic import Field
|
5
3
|
|
@@ -23,7 +21,7 @@ class _SingleImageBase(BaseModel):
|
|
23
21
|
"""
|
24
22
|
|
25
23
|
zarr_url: ZarrUrlStr
|
26
|
-
origin:
|
24
|
+
origin: ZarrDirStr | None = None
|
27
25
|
|
28
26
|
attributes: DictStrAny = Field(default_factory=dict)
|
29
27
|
types: ImageTypes = Field(default_factory=dict)
|
@@ -48,4 +46,4 @@ class SingleImage(_SingleImageBase):
|
|
48
46
|
class SingleImageUpdate(BaseModel):
|
49
47
|
zarr_url: ZarrUrlStr
|
50
48
|
attributes: ImageAttributes = None
|
51
|
-
types:
|
49
|
+
types: ImageTypes | None = None
|
fractal_server/images/tools.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
from copy import copy
|
2
2
|
from typing import Any
|
3
3
|
from typing import Literal
|
4
|
-
from typing import Optional
|
5
4
|
from typing import Union
|
6
5
|
|
7
6
|
from fractal_server.types import AttributeFilters
|
@@ -13,7 +12,7 @@ def find_image_by_zarr_url(
|
|
13
12
|
*,
|
14
13
|
images: list[dict[str, Any]],
|
15
14
|
zarr_url: str,
|
16
|
-
) ->
|
15
|
+
) -> ImageSearch | None:
|
17
16
|
"""
|
18
17
|
Return a copy of the image with a given zarr_url, and its positional index.
|
19
18
|
|
@@ -65,8 +64,8 @@ def match_filter(
|
|
65
64
|
|
66
65
|
def filter_image_list(
|
67
66
|
images: list[dict[str, Any]],
|
68
|
-
type_filters:
|
69
|
-
attribute_filters:
|
67
|
+
type_filters: dict[str, bool] | None = None,
|
68
|
+
attribute_filters: AttributeFilters | None = None,
|
70
69
|
) -> list[dict[str, Any]]:
|
71
70
|
"""
|
72
71
|
Compute a sublist with images that match a filter set.
|
@@ -141,6 +140,4 @@ def aggregate_types(images: list[dict[str, Any]]) -> list[str]:
|
|
141
140
|
"""
|
142
141
|
Given a list of images, this function returns a list of all image types.
|
143
142
|
"""
|
144
|
-
return list(
|
145
|
-
set(type for image in images for type in image["types"].keys())
|
146
|
-
)
|
143
|
+
return list({type for image in images for type in image["types"].keys()})
|
fractal_server/logger.py
CHANGED
@@ -14,8 +14,6 @@ This module provides logging utilities
|
|
14
14
|
"""
|
15
15
|
import logging
|
16
16
|
from pathlib import Path
|
17
|
-
from typing import Optional
|
18
|
-
from typing import Union
|
19
17
|
|
20
18
|
from .config import get_settings
|
21
19
|
from .syringe import Inject
|
@@ -25,7 +23,7 @@ LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
25
23
|
LOG_FORMATTER = logging.Formatter(LOG_FORMAT)
|
26
24
|
|
27
25
|
|
28
|
-
def get_logger(logger_name:
|
26
|
+
def get_logger(logger_name: str | None = None) -> logging.Logger:
|
29
27
|
"""
|
30
28
|
Wrap the
|
31
29
|
[`logging.getLogger`](https://docs.python.org/3/library/logging.html#logging.getLogger)
|
@@ -57,8 +55,8 @@ def get_logger(logger_name: Optional[str] = None) -> logging.Logger:
|
|
57
55
|
def set_logger(
|
58
56
|
logger_name: str,
|
59
57
|
*,
|
60
|
-
log_file_path:
|
61
|
-
default_logging_level:
|
58
|
+
log_file_path: str | Path | None = None,
|
59
|
+
default_logging_level: int | None = None,
|
62
60
|
) -> logging.Logger:
|
63
61
|
"""
|
64
62
|
Set up a `fractal-server` logger
|