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.
Files changed (108) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +2 -1
  3. fractal_server/app/models/linkuserproject.py +40 -0
  4. fractal_server/app/models/security.py +7 -5
  5. fractal_server/app/models/v2/job.py +13 -2
  6. fractal_server/app/models/v2/resource.py +13 -0
  7. fractal_server/app/routes/admin/v2/__init__.py +11 -11
  8. fractal_server/app/routes/admin/v2/accounting.py +2 -2
  9. fractal_server/app/routes/admin/v2/job.py +34 -23
  10. fractal_server/app/routes/admin/v2/sharing.py +103 -0
  11. fractal_server/app/routes/admin/v2/task.py +9 -8
  12. fractal_server/app/routes/admin/v2/task_group.py +94 -16
  13. fractal_server/app/routes/admin/v2/task_group_lifecycle.py +20 -20
  14. fractal_server/app/routes/api/__init__.py +0 -9
  15. fractal_server/app/routes/api/v2/__init__.py +47 -47
  16. fractal_server/app/routes/api/v2/_aux_functions.py +65 -64
  17. fractal_server/app/routes/api/v2/_aux_functions_history.py +8 -3
  18. fractal_server/app/routes/api/v2/_aux_functions_sharing.py +97 -0
  19. fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +4 -4
  20. fractal_server/app/routes/api/v2/_aux_functions_tasks.py +2 -2
  21. fractal_server/app/routes/api/v2/dataset.py +89 -77
  22. fractal_server/app/routes/api/v2/history.py +28 -16
  23. fractal_server/app/routes/api/v2/images.py +22 -8
  24. fractal_server/app/routes/api/v2/job.py +40 -24
  25. fractal_server/app/routes/api/v2/pre_submission_checks.py +13 -6
  26. fractal_server/app/routes/api/v2/project.py +48 -25
  27. fractal_server/app/routes/api/v2/sharing.py +311 -0
  28. fractal_server/app/routes/api/v2/status_legacy.py +22 -33
  29. fractal_server/app/routes/api/v2/submit.py +76 -71
  30. fractal_server/app/routes/api/v2/task.py +15 -17
  31. fractal_server/app/routes/api/v2/task_collection.py +18 -18
  32. fractal_server/app/routes/api/v2/task_collection_custom.py +11 -13
  33. fractal_server/app/routes/api/v2/task_collection_pixi.py +9 -9
  34. fractal_server/app/routes/api/v2/task_group.py +18 -18
  35. fractal_server/app/routes/api/v2/task_group_lifecycle.py +26 -26
  36. fractal_server/app/routes/api/v2/task_version_update.py +12 -9
  37. fractal_server/app/routes/api/v2/workflow.py +41 -29
  38. fractal_server/app/routes/api/v2/workflow_import.py +25 -23
  39. fractal_server/app/routes/api/v2/workflowtask.py +25 -17
  40. fractal_server/app/routes/auth/_aux_auth.py +100 -0
  41. fractal_server/app/routes/auth/current_user.py +0 -63
  42. fractal_server/app/routes/auth/group.py +1 -30
  43. fractal_server/app/routes/auth/router.py +2 -0
  44. fractal_server/app/routes/auth/users.py +9 -0
  45. fractal_server/app/routes/auth/viewer_paths.py +43 -0
  46. fractal_server/app/schemas/user.py +29 -12
  47. fractal_server/app/schemas/user_group.py +0 -15
  48. fractal_server/app/schemas/v2/__init__.py +55 -48
  49. fractal_server/app/schemas/v2/dataset.py +35 -13
  50. fractal_server/app/schemas/v2/dumps.py +9 -9
  51. fractal_server/app/schemas/v2/job.py +11 -11
  52. fractal_server/app/schemas/v2/project.py +3 -3
  53. fractal_server/app/schemas/v2/resource.py +13 -4
  54. fractal_server/app/schemas/v2/sharing.py +99 -0
  55. fractal_server/app/schemas/v2/status_legacy.py +3 -3
  56. fractal_server/app/schemas/v2/task.py +6 -6
  57. fractal_server/app/schemas/v2/task_collection.py +4 -4
  58. fractal_server/app/schemas/v2/task_group.py +16 -16
  59. fractal_server/app/schemas/v2/workflow.py +16 -16
  60. fractal_server/app/schemas/v2/workflowtask.py +14 -14
  61. fractal_server/app/security/__init__.py +1 -1
  62. fractal_server/app/shutdown.py +6 -6
  63. fractal_server/config/__init__.py +0 -6
  64. fractal_server/config/_data.py +0 -79
  65. fractal_server/config/_main.py +6 -1
  66. fractal_server/data_migrations/2_18_0.py +30 -0
  67. fractal_server/images/models.py +1 -2
  68. fractal_server/main.py +72 -11
  69. fractal_server/migrations/versions/7910eed4cf97_user_project_dirs_and_usergroup_viewer_.py +60 -0
  70. fractal_server/migrations/versions/88270f589c9b_add_prevent_new_submissions.py +39 -0
  71. fractal_server/migrations/versions/bc0e8b3327a7_project_sharing.py +72 -0
  72. fractal_server/migrations/versions/f0702066b007_one_submitted_job_per_dataset.py +40 -0
  73. fractal_server/runner/config/_slurm.py +2 -0
  74. fractal_server/runner/executors/slurm_common/_batching.py +4 -10
  75. fractal_server/runner/executors/slurm_common/slurm_config.py +1 -0
  76. fractal_server/runner/executors/slurm_ssh/runner.py +1 -1
  77. fractal_server/runner/executors/slurm_sudo/runner.py +1 -1
  78. fractal_server/runner/v2/_local.py +4 -3
  79. fractal_server/runner/v2/_slurm_ssh.py +4 -3
  80. fractal_server/runner/v2/_slurm_sudo.py +4 -3
  81. fractal_server/runner/v2/runner.py +36 -17
  82. fractal_server/runner/v2/runner_functions.py +11 -14
  83. fractal_server/runner/v2/submit_workflow.py +22 -9
  84. fractal_server/tasks/v2/local/_utils.py +2 -2
  85. fractal_server/tasks/v2/local/collect.py +5 -6
  86. fractal_server/tasks/v2/local/collect_pixi.py +5 -6
  87. fractal_server/tasks/v2/local/deactivate.py +7 -7
  88. fractal_server/tasks/v2/local/deactivate_pixi.py +3 -3
  89. fractal_server/tasks/v2/local/delete.py +5 -5
  90. fractal_server/tasks/v2/local/reactivate.py +5 -5
  91. fractal_server/tasks/v2/local/reactivate_pixi.py +5 -5
  92. fractal_server/tasks/v2/ssh/collect.py +5 -5
  93. fractal_server/tasks/v2/ssh/collect_pixi.py +5 -5
  94. fractal_server/tasks/v2/ssh/deactivate.py +7 -7
  95. fractal_server/tasks/v2/ssh/deactivate_pixi.py +2 -2
  96. fractal_server/tasks/v2/ssh/delete.py +5 -5
  97. fractal_server/tasks/v2/ssh/reactivate.py +5 -5
  98. fractal_server/tasks/v2/ssh/reactivate_pixi.py +5 -5
  99. fractal_server/tasks/v2/utils_background.py +7 -7
  100. fractal_server/tasks/v2/utils_database.py +5 -5
  101. fractal_server/types/__init__.py +22 -0
  102. fractal_server/types/validators/__init__.py +3 -0
  103. fractal_server/types/validators/_common_validators.py +32 -0
  104. {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/METADATA +3 -2
  105. {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/RECORD +108 -98
  106. {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/WHEEL +0 -0
  107. {fractal_server-2.17.2.dist-info → fractal_server-2.18.0.dist-info}/entry_points.txt +0 -0
  108. {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 WorkflowTaskStatusTypeV2(StrEnum):
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 LegacyStatusReadV2(BaseModel):
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
- WorkflowTaskStatusTypeV2,
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 TaskCreateV2(BaseModel):
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 TaskReadV2(BaseModel):
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 TaskUpdateV2(BaseModel):
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 TaskImportV2(BaseModel):
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 TaskImportV2Legacy(BaseModel):
142
+ class TaskImportLegacy(BaseModel):
143
143
  source: NonEmptyStr
144
144
 
145
145
 
146
- class TaskExportV2(BaseModel):
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 TaskCollectPipV2(BaseModel):
24
+ class TaskCollectPip(BaseModel):
25
25
  """
26
- TaskCollectPipV2 class
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 TaskCollectCustomV2(BaseModel):
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
- `TaskGroupV2.pkg_name` column.
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 TaskReadV2
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 TaskGroupV2OriginEnum(StrEnum):
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 TaskGroupActivityStatusV2(StrEnum):
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 TaskGroupActivityActionV2(StrEnum):
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 TaskGroupCreateV2(BaseModel):
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: TaskGroupV2OriginEnum
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 TaskGroupCreateV2Strict(TaskGroupCreateV2):
57
+ class TaskGroupCreateStrict(TaskGroupCreate):
58
58
  """
59
- A strict version of TaskGroupCreateV2, to be used for task collection.
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 TaskGroupReadV2(BaseModel):
68
+ class TaskGroupRead(BaseModel):
69
69
  id: int
70
- task_list: list[TaskReadV2]
70
+ task_list: list[TaskRead]
71
71
 
72
72
  user_id: int
73
73
  user_group_id: int | None = None
74
74
 
75
- origin: TaskGroupV2OriginEnum
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(TaskGroupReadV2):
99
+ class TaskGroupReadSuperuser(TaskGroupRead):
100
100
  resource_id: int
101
101
 
102
102
 
103
- class TaskGroupUpdateV2(BaseModel):
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 TaskGroupActivityV2Read(BaseModel):
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: TaskGroupActivityStatusV2
117
- action: TaskGroupActivityActionV2
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 ProjectReadV2
9
- from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskExportV2
10
- from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskImportV2
11
- from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskReadV2
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
- WorkflowTaskReadV2WithWarning,
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 WorkflowCreateV2(BaseModel):
19
+ class WorkflowCreate(BaseModel):
20
20
  model_config = ConfigDict(extra="forbid")
21
21
 
22
22
  name: NonEmptyStr
23
23
 
24
24
 
25
- class WorkflowReadV2(BaseModel):
25
+ class WorkflowRead(BaseModel):
26
26
  id: int
27
27
  name: str
28
28
  project_id: int
29
- task_list: list[WorkflowTaskReadV2]
30
- project: ProjectReadV2
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 WorkflowReadV2WithWarnings(WorkflowReadV2):
39
- task_list: list[WorkflowTaskReadV2WithWarning]
38
+ class WorkflowReadWithWarnings(WorkflowRead):
39
+ task_list: list[WorkflowTaskReadWithWarning]
40
40
 
41
41
 
42
- class WorkflowUpdateV2(BaseModel):
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 WorkflowImportV2(BaseModel):
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[WorkflowTaskImportV2]
59
+ task_list: list[WorkflowTaskImport]
60
60
 
61
61
 
62
- class WorkflowExportV2(BaseModel):
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[WorkflowTaskExportV2]
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 TaskExportV2
13
- from .task import TaskImportV2
14
- from .task import TaskImportV2Legacy
15
- from .task import TaskReadV2
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 WorkflowTaskCreateV2(BaseModel):
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 WorkflowTaskReplaceV2(BaseModel):
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 WorkflowTaskReadV2(BaseModel):
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: TaskReadV2
51
+ task: TaskRead
52
52
 
53
53
 
54
- class WorkflowTaskReadV2WithWarning(WorkflowTaskReadV2):
54
+ class WorkflowTaskReadWithWarning(WorkflowTaskRead):
55
55
  warning: str | None = None
56
56
 
57
57
 
58
- class WorkflowTaskUpdateV2(BaseModel):
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 WorkflowTaskImportV2(BaseModel):
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: TaskImportV2 | TaskImportV2Legacy
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 WorkflowTaskExportV2(BaseModel):
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: TaskExportV2
116
+ task: TaskExport
@@ -425,7 +425,7 @@ async def _create_first_user(
425
425
  kwargs = dict(
426
426
  email=email,
427
427
  password=password,
428
- project_dir=project_dir,
428
+ project_dirs=[project_dir],
429
429
  profile_id=profile_id,
430
430
  is_superuser=is_superuser,
431
431
  is_verified=is_verified,
@@ -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 JobStatusTypeV2
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(*, jobsV2: list[int], logger_name: str):
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_(jobsV2))
21
- .where(JobV2.status == JobStatusTypeV2.SUBMITTED)
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_(jobsV2))
26
- .where(JobV2.status == JobStatusTypeV2.SUBMITTED)
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
@@ -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
@@ -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 `jobsV2` attribute of
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")
@@ -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: ZarrDirStr | None = None
23
+ origin: ZarrUrlStr | None = None
25
24
 
26
25
  attributes: DictStrAny = Field(default_factory=dict)
27
26
  types: ImageTypes = Field(default_factory=dict)