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
|
@@ -5,17 +5,18 @@ from pydantic import ConfigDict
|
|
|
5
5
|
from pydantic import Field
|
|
6
6
|
from pydantic import model_validator
|
|
7
7
|
|
|
8
|
-
from .task import TaskExportV2
|
|
9
|
-
from .task import TaskImportV2
|
|
10
|
-
from .task import TaskImportV2Legacy
|
|
11
|
-
from .task import TaskReadV2
|
|
12
|
-
from .task import TaskType
|
|
13
8
|
from fractal_server.types import DictStrAny
|
|
14
9
|
from fractal_server.types import TypeFilters
|
|
15
10
|
from fractal_server.types import WorkflowTaskArgument
|
|
16
11
|
|
|
12
|
+
from .task import TaskExport
|
|
13
|
+
from .task import TaskImport
|
|
14
|
+
from .task import TaskImportLegacy
|
|
15
|
+
from .task import TaskRead
|
|
16
|
+
from .task import TaskType
|
|
17
|
+
|
|
17
18
|
|
|
18
|
-
class
|
|
19
|
+
class WorkflowTaskCreate(BaseModel):
|
|
19
20
|
model_config = ConfigDict(extra="forbid")
|
|
20
21
|
|
|
21
22
|
meta_non_parallel: DictStrAny | None = None
|
|
@@ -25,14 +26,14 @@ class WorkflowTaskCreateV2(BaseModel):
|
|
|
25
26
|
type_filters: TypeFilters = Field(default_factory=dict)
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
class
|
|
29
|
+
class WorkflowTaskReplace(BaseModel):
|
|
29
30
|
"""Used by 'replace-task' endpoint"""
|
|
30
31
|
|
|
31
32
|
args_non_parallel: dict[str, Any] | None = None
|
|
32
33
|
args_parallel: dict[str, Any] | None = None
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
class
|
|
36
|
+
class WorkflowTaskRead(BaseModel):
|
|
36
37
|
id: int
|
|
37
38
|
|
|
38
39
|
workflow_id: int
|
|
@@ -47,14 +48,14 @@ class WorkflowTaskReadV2(BaseModel):
|
|
|
47
48
|
|
|
48
49
|
task_type: TaskType
|
|
49
50
|
task_id: int
|
|
50
|
-
task:
|
|
51
|
+
task: TaskRead
|
|
51
52
|
|
|
52
53
|
|
|
53
|
-
class
|
|
54
|
+
class WorkflowTaskReadWithWarning(WorkflowTaskRead):
|
|
54
55
|
warning: str | None = None
|
|
55
56
|
|
|
56
57
|
|
|
57
|
-
class
|
|
58
|
+
class WorkflowTaskUpdate(BaseModel):
|
|
58
59
|
model_config = ConfigDict(extra="forbid")
|
|
59
60
|
|
|
60
61
|
meta_non_parallel: DictStrAny | None = None
|
|
@@ -64,7 +65,7 @@ class WorkflowTaskUpdateV2(BaseModel):
|
|
|
64
65
|
type_filters: TypeFilters = None
|
|
65
66
|
|
|
66
67
|
|
|
67
|
-
class
|
|
68
|
+
class WorkflowTaskImport(BaseModel):
|
|
68
69
|
model_config = ConfigDict(extra="forbid")
|
|
69
70
|
|
|
70
71
|
meta_non_parallel: DictStrAny | None = None
|
|
@@ -74,7 +75,7 @@ class WorkflowTaskImportV2(BaseModel):
|
|
|
74
75
|
type_filters: TypeFilters | None = None
|
|
75
76
|
input_filters: dict[str, Any] | None = None
|
|
76
77
|
|
|
77
|
-
task:
|
|
78
|
+
task: TaskImport | TaskImportLegacy
|
|
78
79
|
|
|
79
80
|
@model_validator(mode="before")
|
|
80
81
|
@classmethod
|
|
@@ -105,11 +106,11 @@ class WorkflowTaskImportV2(BaseModel):
|
|
|
105
106
|
return values
|
|
106
107
|
|
|
107
108
|
|
|
108
|
-
class
|
|
109
|
+
class WorkflowTaskExport(BaseModel):
|
|
109
110
|
meta_non_parallel: dict[str, Any] | None = None
|
|
110
111
|
meta_parallel: dict[str, Any] | None = None
|
|
111
112
|
args_non_parallel: dict[str, Any] | None = None
|
|
112
113
|
args_parallel: dict[str, Any] | None = None
|
|
113
114
|
type_filters: dict[str, bool] = Field(default_factory=dict)
|
|
114
115
|
|
|
115
|
-
task:
|
|
116
|
+
task: TaskExport
|
|
@@ -15,6 +15,7 @@ registers the client and the relative routes.
|
|
|
15
15
|
|
|
16
16
|
All routes are registered under the `auth/` prefix.
|
|
17
17
|
"""
|
|
18
|
+
|
|
18
19
|
import contextlib
|
|
19
20
|
from collections.abc import AsyncGenerator
|
|
20
21
|
from typing import Any
|
|
@@ -39,7 +40,7 @@ from sqlalchemy.orm import selectinload
|
|
|
39
40
|
from sqlmodel import func
|
|
40
41
|
from sqlmodel import select
|
|
41
42
|
|
|
42
|
-
from
|
|
43
|
+
from fractal_server.app.db import get_async_db
|
|
43
44
|
from fractal_server.app.db import get_sync_db
|
|
44
45
|
from fractal_server.app.models import LinkUserGroup
|
|
45
46
|
from fractal_server.app.models import OAuthAccount
|
|
@@ -275,9 +276,7 @@ class UserManager(IntegerIDMixin, BaseUserManager[UserOAuth, int]):
|
|
|
275
276
|
)
|
|
276
277
|
except exceptions.UserNotExists:
|
|
277
278
|
# (0) Log
|
|
278
|
-
logger.warning(
|
|
279
|
-
f"Self-registration attempt by {account_email}."
|
|
280
|
-
)
|
|
279
|
+
logger.warning(f"Self-registration attempt by {account_email}.")
|
|
281
280
|
|
|
282
281
|
# (1) Prepare user-facing error message
|
|
283
282
|
error_msg = (
|
|
@@ -426,7 +425,7 @@ async def _create_first_user(
|
|
|
426
425
|
kwargs = dict(
|
|
427
426
|
email=email,
|
|
428
427
|
password=password,
|
|
429
|
-
|
|
428
|
+
project_dirs=[project_dir],
|
|
430
429
|
profile_id=profile_id,
|
|
431
430
|
is_superuser=is_superuser,
|
|
432
431
|
is_verified=is_verified,
|
|
@@ -459,9 +458,7 @@ def _create_first_group():
|
|
|
459
458
|
)
|
|
460
459
|
return
|
|
461
460
|
|
|
462
|
-
function_logger.info(
|
|
463
|
-
f"START, name '{settings.FRACTAL_DEFAULT_GROUP_NAME}'"
|
|
464
|
-
)
|
|
461
|
+
function_logger.info(f"START, name '{settings.FRACTAL_DEFAULT_GROUP_NAME}'")
|
|
465
462
|
with next(get_sync_db()) as db:
|
|
466
463
|
group_all = db.execute(
|
|
467
464
|
select(UserGroup).where(
|
|
@@ -36,9 +36,9 @@ def send_fractal_email_or_log_failure(
|
|
|
36
36
|
for recipient in email_settings.recipients
|
|
37
37
|
]
|
|
38
38
|
)
|
|
39
|
-
mail_msg[
|
|
40
|
-
"
|
|
41
|
-
|
|
39
|
+
mail_msg["Subject"] = (
|
|
40
|
+
f"[Fractal, {email_settings.instance_name}] {subject}"
|
|
41
|
+
)
|
|
42
42
|
with smtplib.SMTP(
|
|
43
43
|
email_settings.smtp_server,
|
|
44
44
|
email_settings.port,
|
|
@@ -61,6 +61,5 @@ def send_fractal_email_or_log_failure(
|
|
|
61
61
|
|
|
62
62
|
except Exception as e:
|
|
63
63
|
logger.error(
|
|
64
|
-
"Could not send self-registration email, "
|
|
65
|
-
f"original error: {str(e)}."
|
|
64
|
+
f"Could not send self-registration email, original error: {str(e)}."
|
|
66
65
|
)
|
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,68 +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 ._settings_config import SETTINGS_CONFIG_DICT
|
|
9
|
-
from fractal_server.types import AbsolutePathStr
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class DataAuthScheme(StrEnum):
|
|
13
|
-
VIEWER_PATHS = "viewer-paths"
|
|
14
|
-
USERS_FOLDERS = "users-folders"
|
|
15
|
-
NONE = "none"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class DataSettings(BaseSettings):
|
|
19
|
-
"""
|
|
20
|
-
Settings for the `fractal-data` integration.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
24
|
-
|
|
25
|
-
FRACTAL_DATA_AUTH_SCHEME: DataAuthScheme = "none"
|
|
26
|
-
"""
|
|
27
|
-
Defines how the list of allowed viewer paths is built.
|
|
28
|
-
|
|
29
|
-
This variable affects the `GET /auth/current-user/allowed-viewer-paths/`
|
|
30
|
-
response, which is then consumed by
|
|
31
|
-
[fractal-data](https://github.com/fractal-analytics-platform/fractal-data).
|
|
32
|
-
|
|
33
|
-
Options:
|
|
34
|
-
|
|
35
|
-
- "viewer-paths": The list of allowed viewer paths will include the user's
|
|
36
|
-
`project_dir` along with any path defined in user groups' `viewer_paths`
|
|
37
|
-
attributes.
|
|
38
|
-
- "users-folders": The list will consist of the user's `project_dir` and a
|
|
39
|
-
user-specific folder. The user folder is constructed by concatenating
|
|
40
|
-
the base folder `FRACTAL_DATA_BASE_FOLDER` with the user's profile
|
|
41
|
-
`username`.
|
|
42
|
-
- "none": An empty list will be returned, indicating no access to
|
|
43
|
-
viewer paths. Useful when vizarr viewer is not used.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
FRACTAL_DATA_BASE_FOLDER: AbsolutePathStr | None = None
|
|
47
|
-
"""
|
|
48
|
-
Base path to Zarr files that will be served by fractal-vizarr-viewer;
|
|
49
|
-
This variable is required and used only when
|
|
50
|
-
FRACTAL_DATA_AUTHORIZATION_SCHEME is set to "users-folders".
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
@model_validator(mode="after")
|
|
54
|
-
def check(self: Self) -> Self:
|
|
55
|
-
"""
|
|
56
|
-
`FRACTAL_DATA_BASE_FOLDER` is required when
|
|
57
|
-
`FRACTAL_DATA_AUTHORIZATION_SCHEME` is set to `"users-folders"`.
|
|
58
|
-
"""
|
|
59
|
-
if (
|
|
60
|
-
self.FRACTAL_DATA_AUTH_SCHEME == DataAuthScheme.USERS_FOLDERS
|
|
61
|
-
and self.FRACTAL_DATA_BASE_FOLDER is None
|
|
62
|
-
):
|
|
63
|
-
raise ValueError(
|
|
64
|
-
"FRACTAL_DATA_BASE_FOLDER is required when "
|
|
65
|
-
"FRACTAL_DATA_AUTH_SCHEME is set to "
|
|
66
|
-
"users-folders"
|
|
67
|
-
)
|
|
68
|
-
return self
|
|
@@ -1,45 +1,44 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
1
3
|
from pydantic import SecretStr
|
|
2
4
|
from pydantic.types import NonNegativeInt
|
|
3
5
|
from pydantic_settings import BaseSettings
|
|
4
6
|
from pydantic_settings import SettingsConfigDict
|
|
5
7
|
from sqlalchemy.engine import URL
|
|
6
8
|
|
|
7
|
-
from ._settings_config import SETTINGS_CONFIG_DICT
|
|
8
9
|
from fractal_server.types import NonEmptyStr
|
|
9
10
|
|
|
11
|
+
from ._settings_config import SETTINGS_CONFIG_DICT
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
class DatabaseSettings(BaseSettings):
|
|
12
15
|
"""
|
|
13
16
|
Minimal set of configurations needed for operating on the database (e.g
|
|
14
17
|
for schema migrations).
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
DB_ECHO:
|
|
21
|
+
If `"true"`, make database operations verbose.
|
|
22
|
+
POSTGRES_USER:
|
|
23
|
+
User to use when connecting to the PostgreSQL database.
|
|
24
|
+
POSTGRES_PASSWORD:
|
|
25
|
+
Password to use when connecting to the PostgreSQL database.
|
|
26
|
+
POSTGRES_HOST:
|
|
27
|
+
URL to the PostgreSQL server or path to a UNIX domain socket.
|
|
28
|
+
POSTGRES_PORT:
|
|
29
|
+
Port number to use when connecting to the PostgreSQL server.
|
|
30
|
+
POSTGRES_DB:
|
|
31
|
+
Name of the PostgreSQL database to connect to.
|
|
15
32
|
"""
|
|
16
33
|
|
|
17
34
|
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
18
35
|
|
|
19
|
-
DB_ECHO:
|
|
20
|
-
"""
|
|
21
|
-
If `True`, make database operations verbose.
|
|
22
|
-
"""
|
|
36
|
+
DB_ECHO: Literal["true", "false"] = "false"
|
|
23
37
|
POSTGRES_USER: NonEmptyStr | None = None
|
|
24
|
-
"""
|
|
25
|
-
User to use when connecting to the PostgreSQL database.
|
|
26
|
-
"""
|
|
27
38
|
POSTGRES_PASSWORD: SecretStr | None = None
|
|
28
|
-
"""
|
|
29
|
-
Password to use when connecting to the PostgreSQL database.
|
|
30
|
-
"""
|
|
31
39
|
POSTGRES_HOST: NonEmptyStr = "localhost"
|
|
32
|
-
"""
|
|
33
|
-
URL to the PostgreSQL server or path to a UNIX domain socket.
|
|
34
|
-
"""
|
|
35
40
|
POSTGRES_PORT: NonNegativeInt = 5432
|
|
36
|
-
"""
|
|
37
|
-
Port number to use when connecting to the PostgreSQL server.
|
|
38
|
-
"""
|
|
39
41
|
POSTGRES_DB: NonEmptyStr
|
|
40
|
-
"""
|
|
41
|
-
Name of the PostgreSQL database to connect to.
|
|
42
|
-
"""
|
|
43
42
|
|
|
44
43
|
@property
|
|
45
44
|
def DATABASE_URL(self) -> URL:
|
fractal_server/config/_email.py
CHANGED
|
@@ -4,8 +4,8 @@ from typing import Self
|
|
|
4
4
|
from pydantic import BaseModel
|
|
5
5
|
from pydantic import EmailStr
|
|
6
6
|
from pydantic import Field
|
|
7
|
-
from pydantic import model_validator
|
|
8
7
|
from pydantic import SecretStr
|
|
8
|
+
from pydantic import model_validator
|
|
9
9
|
from pydantic_settings import BaseSettings
|
|
10
10
|
from pydantic_settings import SettingsConfigDict
|
|
11
11
|
|
|
@@ -17,14 +17,14 @@ class PublicEmailSettings(BaseModel):
|
|
|
17
17
|
Schema for `EmailSettings.public`, namely the ready-to-use settings.
|
|
18
18
|
|
|
19
19
|
Attributes:
|
|
20
|
-
sender: Sender email address
|
|
21
|
-
recipients: List of recipients email address
|
|
22
|
-
smtp_server: SMTP server address
|
|
23
|
-
port: SMTP server port
|
|
24
|
-
password: Sender password
|
|
25
|
-
instance_name: Name of SMTP server instance
|
|
26
|
-
use_starttls: Whether to use the security protocol
|
|
27
|
-
use_login: Whether to use login
|
|
20
|
+
sender: Sender email address.
|
|
21
|
+
recipients: List of recipients email address.
|
|
22
|
+
smtp_server: SMTP server address.
|
|
23
|
+
port: SMTP server port.
|
|
24
|
+
password: Sender password.
|
|
25
|
+
instance_name: Name of SMTP server instance.
|
|
26
|
+
use_starttls: Whether to use the security protocol.
|
|
27
|
+
use_login: Whether to use login.
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
sender: EmailStr
|
|
@@ -40,50 +40,42 @@ class PublicEmailSettings(BaseModel):
|
|
|
40
40
|
class EmailSettings(BaseSettings):
|
|
41
41
|
"""
|
|
42
42
|
Class with settings for email-sending feature.
|
|
43
|
+
|
|
44
|
+
Attributes:
|
|
45
|
+
FRACTAL_EMAIL_SENDER:
|
|
46
|
+
Address of the OAuth-signup email sender.
|
|
47
|
+
FRACTAL_EMAIL_PASSWORD:
|
|
48
|
+
Password for the OAuth-signup email sender.
|
|
49
|
+
FRACTAL_EMAIL_SMTP_SERVER:
|
|
50
|
+
SMTP server for the OAuth-signup emails.
|
|
51
|
+
FRACTAL_EMAIL_SMTP_PORT:
|
|
52
|
+
SMTP server port for the OAuth-signup emails.
|
|
53
|
+
FRACTAL_EMAIL_INSTANCE_NAME:
|
|
54
|
+
Fractal instance name, to be included in the OAuth-signup emails.
|
|
55
|
+
FRACTAL_EMAIL_RECIPIENTS:
|
|
56
|
+
Comma-separated list of recipients of the OAuth-signup emails.
|
|
57
|
+
FRACTAL_EMAIL_USE_STARTTLS:
|
|
58
|
+
Whether to use StartTLS when using the SMTP server.
|
|
59
|
+
FRACTAL_EMAIL_USE_LOGIN:
|
|
60
|
+
Whether to use login when using the SMTP server.
|
|
61
|
+
If 'true', FRACTAL_EMAIL_PASSWORD must be provided.
|
|
43
62
|
"""
|
|
44
63
|
|
|
45
64
|
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
46
65
|
|
|
47
66
|
FRACTAL_EMAIL_SENDER: EmailStr | None = None
|
|
48
|
-
"""
|
|
49
|
-
Address of the OAuth-signup email sender.
|
|
50
|
-
"""
|
|
51
67
|
FRACTAL_EMAIL_PASSWORD: SecretStr | None = None
|
|
52
|
-
"""
|
|
53
|
-
Password for the OAuth-signup email sender.
|
|
54
|
-
"""
|
|
55
68
|
FRACTAL_EMAIL_SMTP_SERVER: str | None = None
|
|
56
|
-
"""
|
|
57
|
-
SMTP server for the OAuth-signup emails.
|
|
58
|
-
"""
|
|
59
69
|
FRACTAL_EMAIL_SMTP_PORT: int | None = None
|
|
60
|
-
"""
|
|
61
|
-
SMTP server port for the OAuth-signup emails.
|
|
62
|
-
"""
|
|
63
70
|
FRACTAL_EMAIL_INSTANCE_NAME: str | None = None
|
|
64
|
-
"""
|
|
65
|
-
Fractal instance name, to be included in the OAuth-signup emails.
|
|
66
|
-
"""
|
|
67
71
|
FRACTAL_EMAIL_RECIPIENTS: str | None = None
|
|
68
|
-
"""
|
|
69
|
-
Comma-separated list of recipients of the OAuth-signup emails.
|
|
70
|
-
"""
|
|
71
72
|
FRACTAL_EMAIL_USE_STARTTLS: Literal["true", "false"] = "true"
|
|
72
|
-
"""
|
|
73
|
-
Whether to use StartTLS when using the SMTP server.
|
|
74
|
-
Accepted values: 'true', 'false'.
|
|
75
|
-
"""
|
|
76
73
|
FRACTAL_EMAIL_USE_LOGIN: Literal["true", "false"] = "true"
|
|
77
|
-
"""
|
|
78
|
-
Whether to use login when using the SMTP server.
|
|
79
|
-
If 'true', FRACTAL_EMAIL_PASSWORD must be provided.
|
|
80
|
-
Accepted values: 'true', 'false'.
|
|
81
|
-
"""
|
|
82
74
|
|
|
83
75
|
public: PublicEmailSettings | None = None
|
|
84
76
|
"""
|
|
85
|
-
The validated field which is actually used in `fractal-server
|
|
86
|
-
|
|
77
|
+
The validated field which is actually used in `fractal-server`,
|
|
78
|
+
automatically populated upon creation.
|
|
87
79
|
"""
|
|
88
80
|
|
|
89
81
|
@model_validator(mode="after")
|
fractal_server/config/_main.py
CHANGED
|
@@ -11,68 +11,54 @@ from ._settings_config import SETTINGS_CONFIG_DICT
|
|
|
11
11
|
|
|
12
12
|
class Settings(BaseSettings):
|
|
13
13
|
"""
|
|
14
|
-
Contains
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
Contains the general configuration variables for Fractal Server.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
JWT_EXPIRE_SECONDS:
|
|
18
|
+
JWT token lifetime, in seconds.
|
|
19
|
+
JWT_SECRET_KEY:
|
|
20
|
+
JWT secret.<br>
|
|
21
|
+
⚠️ Set this variable to a secure string, and do not disclose it.
|
|
22
|
+
COOKIE_EXPIRE_SECONDS:
|
|
23
|
+
Cookie token lifetime, in seconds.
|
|
24
|
+
FRACTAL_RUNNER_BACKEND:
|
|
25
|
+
Select which runner backend to use.
|
|
26
|
+
FRACTAL_LOGGING_LEVEL:
|
|
27
|
+
Logging-level threshold for logging
|
|
28
|
+
Only logs of with this level (or higher) will appear in the console
|
|
29
|
+
logs.
|
|
30
|
+
FRACTAL_API_MAX_JOB_LIST_LENGTH:
|
|
31
|
+
Number of ids that can be stored in the `jobs` attribute of
|
|
32
|
+
`app.state`.
|
|
33
|
+
FRACTAL_GRACEFUL_SHUTDOWN_TIME:
|
|
34
|
+
Waiting time for the shutdown phase of executors, in seconds.
|
|
35
|
+
FRACTAL_HELP_URL:
|
|
36
|
+
The URL of an instance-specific Fractal help page.
|
|
37
|
+
FRACTAL_DEFAULT_GROUP_NAME:
|
|
38
|
+
Name of the default user group.
|
|
39
|
+
|
|
40
|
+
If set to `"All"`, then the user group with that name is a special
|
|
41
|
+
user group (e.g. it cannot be deleted, and new users are
|
|
42
|
+
automatically added to it). If set to `None` (the default value),
|
|
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.
|
|
17
48
|
"""
|
|
18
49
|
|
|
19
50
|
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
20
51
|
|
|
21
52
|
JWT_EXPIRE_SECONDS: int = 180
|
|
22
|
-
"""
|
|
23
|
-
JWT token lifetime, in seconds.
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
53
|
JWT_SECRET_KEY: SecretStr
|
|
27
|
-
"""
|
|
28
|
-
JWT secret
|
|
29
|
-
|
|
30
|
-
⚠️ **IMPORTANT**: set this variable to a secure string, and do not disclose
|
|
31
|
-
it.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
54
|
COOKIE_EXPIRE_SECONDS: int = 86400
|
|
35
|
-
"""
|
|
36
|
-
Cookie token lifetime, in seconds.
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
55
|
# Note: we do not use ResourceType here to avoid circular imports
|
|
40
|
-
FRACTAL_RUNNER_BACKEND: Literal[
|
|
41
|
-
"local"
|
|
42
|
-
|
|
43
|
-
"""
|
|
44
|
-
Select which runner backend to use.
|
|
45
|
-
"""
|
|
46
|
-
|
|
56
|
+
FRACTAL_RUNNER_BACKEND: Literal["local", "slurm_ssh", "slurm_sudo"] = (
|
|
57
|
+
"local"
|
|
58
|
+
)
|
|
47
59
|
FRACTAL_LOGGING_LEVEL: int = logging.INFO
|
|
48
|
-
"""
|
|
49
|
-
Logging-level threshold for logging
|
|
50
|
-
|
|
51
|
-
Only logs of with this level (or higher) will appear in the console logs.
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
60
|
FRACTAL_API_MAX_JOB_LIST_LENGTH: int = 25
|
|
55
|
-
"""
|
|
56
|
-
Number of ids that can be stored in the `jobsV2` attribute of
|
|
57
|
-
`app.state`.
|
|
58
|
-
"""
|
|
59
|
-
|
|
60
61
|
FRACTAL_GRACEFUL_SHUTDOWN_TIME: float = 30.0
|
|
61
|
-
"""
|
|
62
|
-
Waiting time for the shutdown phase of executors
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
62
|
FRACTAL_HELP_URL: HttpUrl | None = None
|
|
66
|
-
"""
|
|
67
|
-
The URL of an instance-specific Fractal help page.
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
63
|
FRACTAL_DEFAULT_GROUP_NAME: Literal["All"] | None = None
|
|
71
|
-
|
|
72
|
-
Name of the default user group.
|
|
73
|
-
|
|
74
|
-
If set to `"All"`, then the user group with that name is a special user
|
|
75
|
-
group (e.g. it cannot be deleted, and new users are automatically added
|
|
76
|
-
to it). If set to `None` (the default value), then user groups are all
|
|
77
|
-
equivalent, independently on their name.
|
|
78
|
-
"""
|
|
64
|
+
FRACTAL_LONG_REQUEST_TIME: float = 30.0
|
fractal_server/config/_oauth.py
CHANGED
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
2
|
from typing import Self
|
|
3
3
|
|
|
4
|
-
from pydantic import model_validator
|
|
5
4
|
from pydantic import SecretStr
|
|
6
5
|
from pydantic import StringConstraints
|
|
6
|
+
from pydantic import model_validator
|
|
7
7
|
from pydantic_settings import BaseSettings
|
|
8
8
|
from pydantic_settings import SettingsConfigDict
|
|
9
9
|
|
|
10
|
-
from ._settings_config import SETTINGS_CONFIG_DICT
|
|
11
10
|
from fractal_server.types import NonEmptyStr
|
|
12
11
|
|
|
12
|
+
from ._settings_config import SETTINGS_CONFIG_DICT
|
|
13
|
+
|
|
13
14
|
|
|
14
15
|
class OAuthSettings(BaseSettings):
|
|
15
16
|
"""
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
Settings for integration with an OAuth identity provider.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
OAUTH_CLIENT_NAME: Name of the client.
|
|
21
|
+
OAUTH_CLIENT_ID: ID of client.
|
|
22
|
+
OAUTH_CLIENT_SECRET:
|
|
23
|
+
Secret to authorise against the identity provider.
|
|
24
|
+
OAUTH_OIDC_CONFIG_ENDPOINT:
|
|
25
|
+
OpenID Connect configuration endpoint, for autodiscovery of
|
|
26
|
+
relevant endpoints.
|
|
27
|
+
OAUTH_REDIRECT_URL:
|
|
28
|
+
String to be used as `redirect_url` argument in
|
|
29
|
+
`fastapi_users.get_oauth_router`, and then in
|
|
30
|
+
`httpx_oauth.integrations.fastapi.OAuth2AuthorizeCallback`.
|
|
18
31
|
"""
|
|
19
32
|
|
|
20
33
|
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
@@ -26,27 +39,10 @@ class OAuthSettings(BaseSettings):
|
|
|
26
39
|
]
|
|
27
40
|
| None
|
|
28
41
|
) = None
|
|
29
|
-
"""
|
|
30
|
-
The name of the client.
|
|
31
|
-
"""
|
|
32
42
|
OAUTH_CLIENT_ID: SecretStr | None = None
|
|
33
|
-
"""
|
|
34
|
-
ID of client.
|
|
35
|
-
"""
|
|
36
43
|
OAUTH_CLIENT_SECRET: SecretStr | None = None
|
|
37
|
-
"""
|
|
38
|
-
Secret to authorise against the identity provider.
|
|
39
|
-
"""
|
|
40
44
|
OAUTH_OIDC_CONFIG_ENDPOINT: SecretStr | None = None
|
|
41
|
-
"""
|
|
42
|
-
OpenID configuration endpoint, for autodiscovery of relevant endpoints.
|
|
43
|
-
"""
|
|
44
45
|
OAUTH_REDIRECT_URL: str | None = None
|
|
45
|
-
"""
|
|
46
|
-
String to be used as `redirect_url` argument in
|
|
47
|
-
`fastapi_users.get_oauth_router`, and then in
|
|
48
|
-
`httpx_oauth.integrations.fastapi.OAuth2AuthorizeCallback`
|
|
49
|
-
"""
|
|
50
46
|
|
|
51
47
|
@model_validator(mode="after")
|
|
52
48
|
def check_configuration(self: Self) -> Self:
|
|
@@ -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")
|