fractal-server 2.6.4__py3-none-any.whl → 2.7.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 (71) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +1 -1
  3. fractal_server/app/models/linkusergroup.py +11 -0
  4. fractal_server/app/models/v2/__init__.py +2 -0
  5. fractal_server/app/models/v2/collection_state.py +1 -0
  6. fractal_server/app/models/v2/task.py +67 -2
  7. fractal_server/app/routes/admin/v2/__init__.py +16 -0
  8. fractal_server/app/routes/admin/{v2.py → v2/job.py} +20 -191
  9. fractal_server/app/routes/admin/v2/project.py +43 -0
  10. fractal_server/app/routes/admin/v2/task.py +133 -0
  11. fractal_server/app/routes/admin/v2/task_group.py +162 -0
  12. fractal_server/app/routes/api/v1/task_collection.py +4 -4
  13. fractal_server/app/routes/api/v2/__init__.py +8 -0
  14. fractal_server/app/routes/api/v2/_aux_functions.py +1 -68
  15. fractal_server/app/routes/api/v2/_aux_functions_tasks.py +343 -0
  16. fractal_server/app/routes/api/v2/submit.py +16 -35
  17. fractal_server/app/routes/api/v2/task.py +85 -110
  18. fractal_server/app/routes/api/v2/task_collection.py +184 -196
  19. fractal_server/app/routes/api/v2/task_collection_custom.py +70 -64
  20. fractal_server/app/routes/api/v2/task_group.py +173 -0
  21. fractal_server/app/routes/api/v2/workflow.py +39 -102
  22. fractal_server/app/routes/api/v2/workflow_import.py +360 -0
  23. fractal_server/app/routes/api/v2/workflowtask.py +4 -8
  24. fractal_server/app/routes/auth/_aux_auth.py +86 -40
  25. fractal_server/app/routes/auth/current_user.py +5 -5
  26. fractal_server/app/routes/auth/group.py +73 -23
  27. fractal_server/app/routes/auth/router.py +0 -2
  28. fractal_server/app/routes/auth/users.py +8 -7
  29. fractal_server/app/runner/executors/slurm/ssh/executor.py +82 -63
  30. fractal_server/app/runner/v2/__init__.py +13 -7
  31. fractal_server/app/runner/v2/task_interface.py +4 -9
  32. fractal_server/app/schemas/user.py +1 -2
  33. fractal_server/app/schemas/v2/__init__.py +7 -0
  34. fractal_server/app/schemas/v2/dataset.py +2 -7
  35. fractal_server/app/schemas/v2/dumps.py +1 -2
  36. fractal_server/app/schemas/v2/job.py +1 -1
  37. fractal_server/app/schemas/v2/manifest.py +25 -1
  38. fractal_server/app/schemas/v2/project.py +1 -1
  39. fractal_server/app/schemas/v2/task.py +95 -36
  40. fractal_server/app/schemas/v2/task_collection.py +8 -6
  41. fractal_server/app/schemas/v2/task_group.py +85 -0
  42. fractal_server/app/schemas/v2/workflow.py +7 -2
  43. fractal_server/app/schemas/v2/workflowtask.py +9 -6
  44. fractal_server/app/security/__init__.py +8 -1
  45. fractal_server/config.py +8 -28
  46. fractal_server/data_migrations/2_7_0.py +323 -0
  47. fractal_server/images/models.py +2 -4
  48. fractal_server/main.py +1 -1
  49. fractal_server/migrations/versions/034a469ec2eb_task_groups.py +184 -0
  50. fractal_server/ssh/_fabric.py +186 -73
  51. fractal_server/string_tools.py +6 -2
  52. fractal_server/tasks/utils.py +19 -5
  53. fractal_server/tasks/v1/_TaskCollectPip.py +1 -1
  54. fractal_server/tasks/v1/background_operations.py +5 -5
  55. fractal_server/tasks/v1/get_collection_data.py +2 -2
  56. fractal_server/tasks/v2/_venv_pip.py +67 -70
  57. fractal_server/tasks/v2/background_operations.py +180 -69
  58. fractal_server/tasks/v2/background_operations_ssh.py +57 -70
  59. fractal_server/tasks/v2/database_operations.py +44 -0
  60. fractal_server/tasks/v2/endpoint_operations.py +104 -116
  61. fractal_server/tasks/v2/templates/_1_create_venv.sh +9 -5
  62. fractal_server/tasks/v2/templates/{_2_upgrade_pip.sh → _2_preliminary_pip_operations.sh} +1 -0
  63. fractal_server/tasks/v2/utils.py +5 -0
  64. fractal_server/utils.py +3 -2
  65. {fractal_server-2.6.4.dist-info → fractal_server-2.7.0.dist-info}/METADATA +3 -7
  66. {fractal_server-2.6.4.dist-info → fractal_server-2.7.0.dist-info}/RECORD +69 -60
  67. fractal_server/app/routes/auth/group_names.py +0 -34
  68. fractal_server/tasks/v2/_TaskCollectPip.py +0 -132
  69. {fractal_server-2.6.4.dist-info → fractal_server-2.7.0.dist-info}/LICENSE +0 -0
  70. {fractal_server-2.6.4.dist-info → fractal_server-2.7.0.dist-info}/WHEEL +0 -0
  71. {fractal_server-2.6.4.dist-info → fractal_server-2.7.0.dist-info}/entry_points.txt +0 -0
@@ -9,8 +9,9 @@ from pydantic import HttpUrl
9
9
  from pydantic import root_validator
10
10
  from pydantic import validator
11
11
 
12
- from .._validators import valdictkeys
13
- from .._validators import valstr
12
+ from fractal_server.app.schemas._validators import val_unique_list
13
+ from fractal_server.app.schemas._validators import valdictkeys
14
+ from fractal_server.app.schemas._validators import valstr
14
15
  from fractal_server.string_tools import validate_cmd
15
16
 
16
17
 
@@ -18,22 +19,26 @@ class TaskCreateV2(BaseModel, extra=Extra.forbid):
18
19
 
19
20
  name: str
20
21
 
21
- command_non_parallel: Optional[str]
22
- command_parallel: Optional[str]
23
- source: str
22
+ command_non_parallel: Optional[str] = None
23
+ command_parallel: Optional[str] = None
24
24
 
25
- meta_non_parallel: Optional[dict[str, Any]]
26
- meta_parallel: Optional[dict[str, Any]]
27
- version: Optional[str]
28
- args_schema_non_parallel: Optional[dict[str, Any]]
29
- args_schema_parallel: Optional[dict[str, Any]]
30
- args_schema_version: Optional[str]
31
- docs_info: Optional[str]
32
- docs_link: Optional[HttpUrl]
25
+ meta_non_parallel: Optional[dict[str, Any]] = None
26
+ meta_parallel: Optional[dict[str, Any]] = None
27
+ version: Optional[str] = None
28
+ args_schema_non_parallel: Optional[dict[str, Any]] = None
29
+ args_schema_parallel: Optional[dict[str, Any]] = None
30
+ args_schema_version: Optional[str] = None
31
+ docs_info: Optional[str] = None
32
+ docs_link: Optional[HttpUrl] = None
33
33
 
34
34
  input_types: dict[str, bool] = Field(default={})
35
35
  output_types: dict[str, bool] = Field(default={})
36
36
 
37
+ category: Optional[str] = None
38
+ modality: Optional[str] = None
39
+ tags: list[str] = Field(default_factory=list)
40
+ authors: Optional[str] = None
41
+
37
42
  # Validators
38
43
  @root_validator
39
44
  def validate_commands(cls, values):
@@ -58,7 +63,6 @@ class TaskCreateV2(BaseModel, extra=Extra.forbid):
58
63
  _command_parallel = validator("command_parallel", allow_reuse=True)(
59
64
  valstr("command_parallel")
60
65
  )
61
- _source = validator("source", allow_reuse=True)(valstr("source"))
62
66
  _version = validator("version", allow_reuse=True)(valstr("version"))
63
67
 
64
68
  _meta_non_parallel = validator("meta_non_parallel", allow_reuse=True)(
@@ -83,37 +87,62 @@ class TaskCreateV2(BaseModel, extra=Extra.forbid):
83
87
  valdictkeys("output_types")
84
88
  )
85
89
 
90
+ _category = validator("category", allow_reuse=True)(
91
+ valstr("category", accept_none=True)
92
+ )
93
+ _modality = validator("modality", allow_reuse=True)(
94
+ valstr("modality", accept_none=True)
95
+ )
96
+ _authors = validator("authors", allow_reuse=True)(
97
+ valstr("authors", accept_none=True)
98
+ )
99
+
100
+ @validator("tags")
101
+ def validate_list_of_strings(cls, value):
102
+ for i, tag in enumerate(value):
103
+ value[i] = valstr(f"tags[{i}]")(tag)
104
+ return val_unique_list("tags")(value)
105
+
86
106
 
87
107
  class TaskReadV2(BaseModel):
88
108
 
89
109
  id: int
90
110
  name: str
91
111
  type: Literal["parallel", "non_parallel", "compound"]
92
- source: str
93
- owner: Optional[str]
94
- version: Optional[str]
112
+ source: Optional[str] = None
113
+ version: Optional[str] = None
95
114
 
96
- command_non_parallel: Optional[str]
97
- command_parallel: Optional[str]
115
+ command_non_parallel: Optional[str] = None
116
+ command_parallel: Optional[str] = None
98
117
  meta_parallel: dict[str, Any]
99
118
  meta_non_parallel: dict[str, Any]
100
119
  args_schema_non_parallel: Optional[dict[str, Any]] = None
101
120
  args_schema_parallel: Optional[dict[str, Any]] = None
102
- args_schema_version: Optional[str]
103
- docs_info: Optional[str]
104
- docs_link: Optional[HttpUrl]
121
+ args_schema_version: Optional[str] = None
122
+ docs_info: Optional[str] = None
123
+ docs_link: Optional[HttpUrl] = None
105
124
  input_types: dict[str, bool]
106
125
  output_types: dict[str, bool]
107
126
 
127
+ taskgroupv2_id: Optional[int] = None
128
+
129
+ category: Optional[str] = None
130
+ modality: Optional[str] = None
131
+ authors: Optional[str] = None
132
+ tags: list[str]
133
+
108
134
 
109
- class TaskUpdateV2(BaseModel):
135
+ class TaskUpdateV2(BaseModel, extra=Extra.forbid):
110
136
 
111
- name: Optional[str]
112
- version: Optional[str]
113
- command_parallel: Optional[str]
114
- command_non_parallel: Optional[str]
115
- input_types: Optional[dict[str, bool]]
116
- output_types: Optional[dict[str, bool]]
137
+ command_parallel: Optional[str] = None
138
+ command_non_parallel: Optional[str] = None
139
+ input_types: Optional[dict[str, bool]] = None
140
+ output_types: Optional[dict[str, bool]] = None
141
+
142
+ category: Optional[str] = None
143
+ modality: Optional[str] = None
144
+ authors: Optional[str] = None
145
+ tags: Optional[list[str]] = None
117
146
 
118
147
  # Validators
119
148
  @validator("input_types", "output_types")
@@ -122,10 +151,6 @@ class TaskUpdateV2(BaseModel):
122
151
  raise ValueError
123
152
  return v
124
153
 
125
- _name = validator("name", allow_reuse=True)(valstr("name"))
126
- _version = validator("version", allow_reuse=True)(
127
- valstr("version", accept_none=True)
128
- )
129
154
  _command_parallel = validator("command_parallel", allow_reuse=True)(
130
155
  valstr("command_parallel")
131
156
  )
@@ -139,14 +164,48 @@ class TaskUpdateV2(BaseModel):
139
164
  valdictkeys("output_types")
140
165
  )
141
166
 
167
+ _category = validator("category", allow_reuse=True)(
168
+ valstr("category", accept_none=True)
169
+ )
170
+ _modality = validator("modality", allow_reuse=True)(
171
+ valstr("modality", accept_none=True)
172
+ )
173
+ _authors = validator("authors", allow_reuse=True)(
174
+ valstr("authors", accept_none=True)
175
+ )
176
+
177
+ @validator("tags")
178
+ def validate_tags(cls, value):
179
+ for i, tag in enumerate(value):
180
+ value[i] = valstr(f"tags[{i}]")(tag)
181
+ return val_unique_list("tags")(value)
182
+
183
+
184
+ class TaskImportV2(BaseModel, extra=Extra.forbid):
142
185
 
143
- class TaskImportV2(BaseModel):
186
+ pkg_name: str
187
+ version: Optional[str] = None
188
+ name: str
189
+ _pkg_name = validator("pkg_name", allow_reuse=True)(valstr("pkg_name"))
190
+ _version = validator("version", allow_reuse=True)(
191
+ valstr("version", accept_none=True)
192
+ )
193
+ _name = validator("name", allow_reuse=True)(valstr("name"))
144
194
 
195
+
196
+ class TaskImportV2Legacy(BaseModel):
145
197
  source: str
146
198
  _source = validator("source", allow_reuse=True)(valstr("source"))
147
199
 
148
200
 
149
201
  class TaskExportV2(BaseModel):
150
202
 
151
- source: str
152
- _source = validator("source", allow_reuse=True)(valstr("source"))
203
+ pkg_name: str
204
+ version: Optional[str] = None
205
+ name: str
206
+
207
+ _pkg_name = validator("pkg_name", allow_reuse=True)(valstr("pkg_name"))
208
+ _version = validator("version", allow_reuse=True)(
209
+ valstr("version", accept_none=True)
210
+ )
211
+ _name = validator("name", allow_reuse=True)(valstr("name"))
@@ -6,6 +6,7 @@ from typing import Literal
6
6
  from typing import Optional
7
7
 
8
8
  from pydantic import BaseModel
9
+ from pydantic import Extra
9
10
  from pydantic import root_validator
10
11
  from pydantic import validator
11
12
 
@@ -24,7 +25,7 @@ class CollectionStatusV2(str, Enum):
24
25
  OK = "OK"
25
26
 
26
27
 
27
- class TaskCollectPipV2(BaseModel):
28
+ class TaskCollectPipV2(BaseModel, extra=Extra.forbid):
28
29
  """
29
30
  TaskCollectPipV2 class
30
31
 
@@ -70,7 +71,7 @@ class TaskCollectPipV2(BaseModel):
70
71
 
71
72
  @validator("package")
72
73
  def package_validator(cls, value):
73
- if "/" in value:
74
+ if "/" in value or value.endswith(".whl"):
74
75
  if not value.endswith(".whl"):
75
76
  raise ValueError(
76
77
  "Local-package path must be a wheel file "
@@ -92,14 +93,15 @@ class TaskCollectPipV2(BaseModel):
92
93
  return v
93
94
 
94
95
 
95
- class TaskCollectCustomV2(BaseModel):
96
+ class TaskCollectCustomV2(BaseModel, extra=Extra.forbid):
96
97
  """
97
98
  Attributes:
98
99
  manifest: Manifest of a Fractal task package (this is typically the
99
100
  content of `__FRACTAL_MANIFEST__.json`).
100
101
  python_interpreter: Absolute path to the Python interpreter to be used
101
102
  for running tasks.
102
- source: A common label identifying this package.
103
+ name: A name identifying this package, that will fill the
104
+ `TaskGroupV2.pkg_name` column.
103
105
  package_root: The folder where the package is installed.
104
106
  If not provided, it will be extracted via `pip show`
105
107
  (requires `package_name` to be set).
@@ -111,7 +113,7 @@ class TaskCollectCustomV2(BaseModel):
111
113
 
112
114
  manifest: ManifestV2
113
115
  python_interpreter: str
114
- source: str
116
+ label: str
115
117
  package_root: Optional[str]
116
118
  package_name: Optional[str]
117
119
  version: Optional[str]
@@ -120,7 +122,7 @@ class TaskCollectCustomV2(BaseModel):
120
122
  _python_interpreter = validator("python_interpreter", allow_reuse=True)(
121
123
  valstr("python_interpreter")
122
124
  )
123
- _source = validator("source", allow_reuse=True)(valstr("source"))
125
+ _label = validator("label", allow_reuse=True)(valstr("label"))
124
126
  _package_root = validator("package_root", allow_reuse=True)(
125
127
  valstr("package_root", accept_none=True)
126
128
  )
@@ -0,0 +1,85 @@
1
+ from datetime import datetime
2
+ from enum import Enum
3
+ from typing import Literal
4
+ from typing import Optional
5
+
6
+ from pydantic import BaseModel
7
+ from pydantic import Extra
8
+ from pydantic import Field
9
+ from pydantic import validator
10
+
11
+ from .._validators import val_absolute_path
12
+ from .._validators import valdictkeys
13
+ from .._validators import valstr
14
+ from .task import TaskReadV2
15
+
16
+
17
+ class TaskGroupV2OriginEnum(str, Enum):
18
+ PYPI = "pypi"
19
+ WHEELFILE = "wheel-file"
20
+ OTHER = "other"
21
+
22
+
23
+ class TaskGroupCreateV2(BaseModel, extra=Extra.forbid):
24
+ user_id: int
25
+ user_group_id: Optional[int] = None
26
+ active: bool = True
27
+ origin: TaskGroupV2OriginEnum
28
+ pkg_name: str
29
+ version: Optional[str] = None
30
+ python_version: Optional[str] = None
31
+ path: Optional[str] = None
32
+ venv_path: Optional[str] = None
33
+ wheel_path: Optional[str] = None
34
+ pip_extras: Optional[str] = None
35
+ pinned_package_versions: dict[str, str] = Field(default_factory=dict)
36
+
37
+ # Validators
38
+ _path = validator("path", allow_reuse=True)(val_absolute_path("path"))
39
+ _venv_path = validator("venv_path", allow_reuse=True)(
40
+ val_absolute_path("venv_path")
41
+ )
42
+ _wheel_path = validator("wheel_path", allow_reuse=True)(
43
+ val_absolute_path("wheel_path")
44
+ )
45
+ _pinned_package_versions = validator(
46
+ "pinned_package_versions", allow_reuse=True
47
+ )(valdictkeys("pinned_package_versions"))
48
+ _pip_extras = validator("pip_extras", allow_reuse=True)(
49
+ valstr("pip_extras")
50
+ )
51
+ _python_version = validator("python_version", allow_reuse=True)(
52
+ valstr("python_version")
53
+ )
54
+
55
+
56
+ class TaskGroupReadV2(BaseModel):
57
+ id: int
58
+ task_list: list[TaskReadV2]
59
+
60
+ user_id: int
61
+ user_group_id: Optional[int] = None
62
+
63
+ origin: Literal["pypi", "wheel-file", "other"]
64
+ pkg_name: str
65
+ version: Optional[str] = None
66
+ python_version: Optional[str] = None
67
+ path: Optional[str] = None
68
+ venv_path: Optional[str] = None
69
+ wheel_path: Optional[str] = None
70
+ pip_extras: Optional[str] = None
71
+ pinned_package_versions: dict[str, str] = Field(default_factory=dict)
72
+
73
+ active: bool
74
+ timestamp_created: datetime
75
+
76
+
77
+ class TaskGroupUpdateV2(BaseModel, extra=Extra.forbid):
78
+ user_group_id: Optional[int] = None
79
+ active: Optional[bool] = None
80
+
81
+ @validator("active")
82
+ def active_cannot_be_None(cls, value):
83
+ if value is None:
84
+ raise ValueError("`active` cannot be set to None")
85
+ return value
@@ -11,6 +11,7 @@ from .project import ProjectReadV2
11
11
  from .workflowtask import WorkflowTaskExportV2
12
12
  from .workflowtask import WorkflowTaskImportV2
13
13
  from .workflowtask import WorkflowTaskReadV2
14
+ from .workflowtask import WorkflowTaskReadV2WithWarning
14
15
 
15
16
 
16
17
  class WorkflowCreateV2(BaseModel, extra=Extra.forbid):
@@ -35,7 +36,11 @@ class WorkflowReadV2(BaseModel):
35
36
  )
36
37
 
37
38
 
38
- class WorkflowUpdateV2(BaseModel):
39
+ class WorkflowReadV2WithWarnings(WorkflowReadV2):
40
+ task_list: list[WorkflowTaskReadV2WithWarning]
41
+
42
+
43
+ class WorkflowUpdateV2(BaseModel, extra=Extra.forbid):
39
44
 
40
45
  name: Optional[str]
41
46
  reordered_workflowtask_ids: Optional[list[int]]
@@ -52,7 +57,7 @@ class WorkflowUpdateV2(BaseModel):
52
57
  return value
53
58
 
54
59
 
55
- class WorkflowImportV2(BaseModel):
60
+ class WorkflowImportV2(BaseModel, extra=Extra.forbid):
56
61
  """
57
62
  Class for `Workflow` import.
58
63
 
@@ -1,6 +1,7 @@
1
1
  from enum import Enum
2
2
  from typing import Any
3
3
  from typing import Optional
4
+ from typing import Union
4
5
 
5
6
  from pydantic import BaseModel
6
7
  from pydantic import Extra
@@ -8,9 +9,9 @@ from pydantic import Field
8
9
  from pydantic import validator
9
10
 
10
11
  from .._validators import valdictkeys
11
- from .._validators import valint
12
12
  from .task import TaskExportV2
13
13
  from .task import TaskImportV2
14
+ from .task import TaskImportV2Legacy
14
15
  from .task import TaskReadV2
15
16
  from fractal_server.images import Filters
16
17
 
@@ -42,7 +43,6 @@ class WorkflowTaskCreateV2(BaseModel, extra=Extra.forbid):
42
43
  meta_parallel: Optional[dict[str, Any]]
43
44
  args_non_parallel: Optional[dict[str, Any]]
44
45
  args_parallel: Optional[dict[str, Any]]
45
- order: Optional[int]
46
46
  input_filters: Filters = Field(default_factory=Filters)
47
47
 
48
48
  # Validators
@@ -52,7 +52,6 @@ class WorkflowTaskCreateV2(BaseModel, extra=Extra.forbid):
52
52
  _meta_parallel = validator("meta_parallel", allow_reuse=True)(
53
53
  valdictkeys("meta_parallel")
54
54
  )
55
- _order = validator("order", allow_reuse=True)(valint("order", min_val=0))
56
55
 
57
56
  @validator("args_non_parallel")
58
57
  def validate_args_non_parallel(cls, value):
@@ -102,7 +101,11 @@ class WorkflowTaskReadV2(BaseModel):
102
101
  task: TaskReadV2
103
102
 
104
103
 
105
- class WorkflowTaskUpdateV2(BaseModel):
104
+ class WorkflowTaskReadV2WithWarning(WorkflowTaskReadV2):
105
+ warning: Optional[str] = None
106
+
107
+
108
+ class WorkflowTaskUpdateV2(BaseModel, extra=Extra.forbid):
106
109
 
107
110
  meta_non_parallel: Optional[dict[str, Any]]
108
111
  meta_parallel: Optional[dict[str, Any]]
@@ -147,7 +150,7 @@ class WorkflowTaskUpdateV2(BaseModel):
147
150
  return value
148
151
 
149
152
 
150
- class WorkflowTaskImportV2(BaseModel):
153
+ class WorkflowTaskImportV2(BaseModel, extra=Extra.forbid):
151
154
 
152
155
  meta_non_parallel: Optional[dict[str, Any]] = None
153
156
  meta_parallel: Optional[dict[str, Any]] = None
@@ -156,7 +159,7 @@ class WorkflowTaskImportV2(BaseModel):
156
159
 
157
160
  input_filters: Optional[Filters] = None
158
161
 
159
- task: TaskImportV2
162
+ task: Union[TaskImportV2, TaskImportV2Legacy]
160
163
 
161
164
  _meta_non_parallel = validator("meta_non_parallel", allow_reuse=True)(
162
165
  valdictkeys("meta_non_parallel")
@@ -315,13 +315,20 @@ async def _create_first_user(
315
315
 
316
316
 
317
317
  def _create_first_group():
318
+ """
319
+ Create a `UserGroup` with `name=FRACTAL_DEFAULT_GROUP_NAME`, if missing.
320
+ """
318
321
  function_logger = set_logger("fractal_server.create_first_group")
319
322
 
320
323
  function_logger.info(
321
324
  f"START _create_first_group, with name '{FRACTAL_DEFAULT_GROUP_NAME}'"
322
325
  )
323
326
  with next(get_sync_db()) as db:
324
- group_all = db.execute(select(UserGroup))
327
+ group_all = db.execute(
328
+ select(UserGroup).where(
329
+ UserGroup.name == FRACTAL_DEFAULT_GROUP_NAME
330
+ )
331
+ )
325
332
  if group_all.scalars().one_or_none() is None:
326
333
  first_group = UserGroup(name=FRACTAL_DEFAULT_GROUP_NAME)
327
334
  db.add(first_group)
fractal_server/config.py CHANGED
@@ -167,9 +167,9 @@ class Settings(BaseSettings):
167
167
  ###########################################################################
168
168
  # DATABASE
169
169
  ###########################################################################
170
- DB_ENGINE: Literal["sqlite", "postgres", "postgres-psycopg"] = "sqlite"
170
+ DB_ENGINE: Literal["sqlite", "postgres-psycopg"] = "sqlite"
171
171
  """
172
- Select which database engine to use (supported: `sqlite` and `postgres`).
172
+ Database engine to use (supported: `sqlite`, `postgres-psycopg`).
173
173
  """
174
174
  DB_ECHO: bool = False
175
175
  """
@@ -203,16 +203,7 @@ class Settings(BaseSettings):
203
203
 
204
204
  @property
205
205
  def DATABASE_ASYNC_URL(self) -> URL:
206
- if self.DB_ENGINE == "postgres":
207
- url = URL.create(
208
- drivername="postgresql+asyncpg",
209
- username=self.POSTGRES_USER,
210
- password=self.POSTGRES_PASSWORD,
211
- host=self.POSTGRES_HOST,
212
- port=self.POSTGRES_PORT,
213
- database=self.POSTGRES_DB,
214
- )
215
- elif self.DB_ENGINE == "postgres-psycopg":
206
+ if self.DB_ENGINE == "postgres-psycopg":
216
207
  url = URL.create(
217
208
  drivername="postgresql+psycopg",
218
209
  username=self.POSTGRES_USER,
@@ -235,11 +226,7 @@ class Settings(BaseSettings):
235
226
 
236
227
  @property
237
228
  def DATABASE_SYNC_URL(self):
238
- if self.DB_ENGINE == "postgres":
239
- return self.DATABASE_ASYNC_URL.set(
240
- drivername="postgresql+psycopg2"
241
- )
242
- elif self.DB_ENGINE == "postgres-psycopg":
229
+ if self.DB_ENGINE == "postgres-psycopg":
243
230
  return self.DATABASE_ASYNC_URL.set(drivername="postgresql+psycopg")
244
231
  else:
245
232
  if not self.SQLITE_PATH:
@@ -546,20 +533,13 @@ class Settings(BaseSettings):
546
533
  """
547
534
  Checks that db environment variables are properly set.
548
535
  """
549
- if self.DB_ENGINE == "postgres":
536
+ if self.DB_ENGINE == "postgres-psycopg":
550
537
  if not self.POSTGRES_DB:
551
538
  raise FractalConfigurationError(
552
- "POSTGRES_DB cannot be None when DB_ENGINE=postgres."
553
- )
554
- try:
555
- import psycopg2 # noqa: F401
556
- import asyncpg # noqa: F401
557
- except ModuleNotFoundError:
558
- raise FractalConfigurationError(
559
- "DB engine is `postgres` but `psycopg2` or `asyncpg` "
560
- "are not available"
539
+ "POSTGRES_DB cannot be None when DB_ENGINE="
540
+ "postgres-psycopg."
561
541
  )
562
- elif self.DB_ENGINE == "postgres-psycopg":
542
+
563
543
  try:
564
544
  import psycopg # noqa: F401
565
545
  except ModuleNotFoundError: