fractal-server 2.14.0a3__py3-none-any.whl → 2.14.0a4__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 +3 -1
- fractal_server/app/history/__init__.py +4 -4
- fractal_server/app/history/image_updates.py +124 -143
- fractal_server/app/history/status_enum.py +2 -2
- fractal_server/app/models/v2/__init__.py +6 -4
- fractal_server/app/models/v2/history.py +44 -20
- fractal_server/app/routes/api/__init__.py +1 -1
- fractal_server/app/routes/api/v2/__init__.py +4 -0
- fractal_server/app/routes/api/v2/_aux_functions_history.py +49 -0
- fractal_server/app/routes/api/v2/dataset.py +0 -12
- fractal_server/app/routes/api/v2/history.py +301 -186
- fractal_server/app/routes/api/v2/project.py +0 -25
- fractal_server/app/routes/api/v2/status_legacy.py +168 -0
- fractal_server/app/routes/api/v2/workflow.py +2 -17
- fractal_server/app/routes/api/v2/workflowtask.py +41 -71
- fractal_server/app/routes/auth/oauth.py +5 -3
- fractal_server/app/runner/executors/local/runner.py +10 -55
- fractal_server/app/runner/executors/slurm_sudo/runner.py +171 -108
- fractal_server/app/runner/v2/__init__.py +0 -20
- fractal_server/app/runner/v2/runner.py +45 -58
- fractal_server/app/runner/v2/runner_functions.py +164 -22
- fractal_server/app/schemas/_validators.py +13 -24
- fractal_server/app/schemas/user.py +10 -7
- fractal_server/app/schemas/user_settings.py +9 -21
- fractal_server/app/schemas/v2/dataset.py +8 -6
- fractal_server/app/schemas/v2/job.py +9 -5
- fractal_server/app/schemas/v2/manifest.py +2 -6
- fractal_server/app/schemas/v2/project.py +9 -7
- fractal_server/app/schemas/v2/task.py +41 -77
- fractal_server/app/schemas/v2/task_collection.py +14 -32
- fractal_server/app/schemas/v2/task_group.py +10 -9
- fractal_server/app/schemas/v2/workflow.py +10 -11
- fractal_server/app/security/signup_email.py +2 -2
- fractal_server/config.py +31 -32
- fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +120 -0
- fractal_server/tasks/v2/templates/2_pip_install.sh +1 -1
- fractal_server/tasks/v2/utils_templates.py +6 -0
- {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/METADATA +1 -1
- {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/RECORD +43 -44
- fractal_server/app/runner/executors/slurm_sudo/_executor_wait_thread.py +0 -130
- fractal_server/app/schemas/v2/history.py +0 -23
- fractal_server/migrations/versions/87cd72a537a2_add_historyitem_table.py +0 -68
- fractal_server/migrations/versions/954ddc64425a_image_status.py +0 -63
- {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/LICENSE +0 -0
- {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/WHEEL +0 -0
- {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/entry_points.txt +0 -0
@@ -12,8 +12,9 @@ from pydantic.types import AwareDatetime
|
|
12
12
|
|
13
13
|
from .._filter_validators import validate_attribute_filters
|
14
14
|
from .._filter_validators import validate_type_filters
|
15
|
+
from .._validators import cant_set_none
|
16
|
+
from .._validators import NonEmptyString
|
15
17
|
from .._validators import root_validate_dict_keys
|
16
|
-
from .._validators import valstr
|
17
18
|
from .project import ProjectReadV2
|
18
19
|
from fractal_server.images import SingleImage
|
19
20
|
from fractal_server.images.models import AttributeFiltersType
|
@@ -23,7 +24,7 @@ from fractal_server.urls import normalize_url
|
|
23
24
|
class DatasetCreateV2(BaseModel):
|
24
25
|
model_config = ConfigDict(extra="forbid")
|
25
26
|
|
26
|
-
name:
|
27
|
+
name: NonEmptyString
|
27
28
|
|
28
29
|
zarr_dir: Optional[str] = None
|
29
30
|
|
@@ -42,8 +43,6 @@ class DatasetCreateV2(BaseModel):
|
|
42
43
|
classmethod(validate_attribute_filters)
|
43
44
|
)
|
44
45
|
|
45
|
-
_name = field_validator("name")(classmethod(valstr("name")))
|
46
|
-
|
47
46
|
@field_validator("zarr_dir")
|
48
47
|
@classmethod
|
49
48
|
def normalize_zarr_dir(cls, v: Optional[str]) -> Optional[str]:
|
@@ -73,7 +72,7 @@ class DatasetReadV2(BaseModel):
|
|
73
72
|
class DatasetUpdateV2(BaseModel):
|
74
73
|
model_config = ConfigDict(extra="forbid")
|
75
74
|
|
76
|
-
name: Optional[
|
75
|
+
name: Optional[NonEmptyString] = None
|
77
76
|
zarr_dir: Optional[str] = None
|
78
77
|
type_filters: Optional[dict[str, bool]] = None
|
79
78
|
attribute_filters: Optional[dict[str, list[Any]]] = None
|
@@ -90,7 +89,10 @@ class DatasetUpdateV2(BaseModel):
|
|
90
89
|
classmethod(validate_attribute_filters)
|
91
90
|
)
|
92
91
|
|
93
|
-
|
92
|
+
@field_validator("name")
|
93
|
+
@classmethod
|
94
|
+
def _cant_set_none(cls, v):
|
95
|
+
return cant_set_none(v)
|
94
96
|
|
95
97
|
@field_validator("zarr_dir")
|
96
98
|
@classmethod
|
@@ -13,8 +13,9 @@ from pydantic.types import AwareDatetime
|
|
13
13
|
from pydantic.types import StrictStr
|
14
14
|
|
15
15
|
from .._filter_validators import validate_attribute_filters
|
16
|
+
from .._validators import cant_set_none
|
17
|
+
from .._validators import NonEmptyString
|
16
18
|
from .._validators import root_validate_dict_keys
|
17
|
-
from .._validators import valstr
|
18
19
|
from .dumps import DatasetDumpV2
|
19
20
|
from .dumps import ProjectDumpV2
|
20
21
|
from .dumps import WorkflowDumpV2
|
@@ -49,14 +50,17 @@ class JobCreateV2(BaseModel):
|
|
49
50
|
first_task_index: Optional[int] = None
|
50
51
|
last_task_index: Optional[int] = None
|
51
52
|
slurm_account: Optional[StrictStr] = None
|
52
|
-
worker_init: Optional[
|
53
|
+
worker_init: Optional[NonEmptyString] = None
|
53
54
|
|
54
55
|
attribute_filters: AttributeFiltersType = Field(default_factory=dict)
|
55
56
|
|
56
57
|
# Validators
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
|
59
|
+
@field_validator("worker_init")
|
60
|
+
@classmethod
|
61
|
+
def _cant_set_none(cls, v):
|
62
|
+
return cant_set_none(v)
|
63
|
+
|
60
64
|
_dict_keys = model_validator(mode="before")(
|
61
65
|
classmethod(root_validate_dict_keys)
|
62
66
|
)
|
@@ -7,7 +7,7 @@ from pydantic import field_validator
|
|
7
7
|
from pydantic import HttpUrl
|
8
8
|
from pydantic import model_validator
|
9
9
|
|
10
|
-
from .._validators import
|
10
|
+
from .._validators import NonEmptyString
|
11
11
|
|
12
12
|
|
13
13
|
class TaskManifestV2(BaseModel):
|
@@ -138,7 +138,7 @@ class ManifestV2(BaseModel):
|
|
138
138
|
task_list: list[TaskManifestV2]
|
139
139
|
has_args_schemas: bool = False
|
140
140
|
args_schema_version: Optional[str] = None
|
141
|
-
authors: Optional[
|
141
|
+
authors: Optional[NonEmptyString] = None
|
142
142
|
|
143
143
|
@model_validator(mode="after")
|
144
144
|
def _check_args_schemas_are_present(self):
|
@@ -181,7 +181,3 @@ class ManifestV2(BaseModel):
|
|
181
181
|
if value != "2":
|
182
182
|
raise ValueError(f"Wrong manifest version (given {value})")
|
183
183
|
return value
|
184
|
-
|
185
|
-
_authors = field_validator("authors")(
|
186
|
-
classmethod(valstr("authors", accept_none=True))
|
187
|
-
)
|
@@ -7,16 +7,15 @@ from pydantic import field_serializer
|
|
7
7
|
from pydantic import field_validator
|
8
8
|
from pydantic.types import AwareDatetime
|
9
9
|
|
10
|
-
from .._validators import
|
10
|
+
from .._validators import cant_set_none
|
11
|
+
from .._validators import NonEmptyString
|
11
12
|
|
12
13
|
|
13
14
|
class ProjectCreateV2(BaseModel):
|
14
15
|
|
15
16
|
model_config = ConfigDict(extra="forbid")
|
16
17
|
|
17
|
-
name:
|
18
|
-
# Validators
|
19
|
-
_name = field_validator("name")(classmethod(valstr("name")))
|
18
|
+
name: NonEmptyString
|
20
19
|
|
21
20
|
|
22
21
|
class ProjectReadV2(BaseModel):
|
@@ -34,6 +33,9 @@ class ProjectUpdateV2(BaseModel):
|
|
34
33
|
|
35
34
|
model_config = ConfigDict(extra="forbid")
|
36
35
|
|
37
|
-
name: Optional[
|
38
|
-
|
39
|
-
|
36
|
+
name: Optional[NonEmptyString] = None
|
37
|
+
|
38
|
+
@field_validator("name")
|
39
|
+
@classmethod
|
40
|
+
def _cant_set_none(cls, v):
|
41
|
+
return cant_set_none(v)
|
@@ -9,38 +9,50 @@ from pydantic import field_validator
|
|
9
9
|
from pydantic import HttpUrl
|
10
10
|
from pydantic import model_validator
|
11
11
|
|
12
|
+
from .._validators import cant_set_none
|
13
|
+
from fractal_server.app.schemas._validators import NonEmptyString
|
12
14
|
from fractal_server.app.schemas._validators import val_unique_list
|
13
15
|
from fractal_server.app.schemas._validators import valdict_keys
|
14
|
-
from fractal_server.app.schemas._validators import valstr
|
15
16
|
from fractal_server.string_tools import validate_cmd
|
16
17
|
|
17
18
|
|
18
19
|
class TaskCreateV2(BaseModel):
|
19
20
|
model_config = ConfigDict(extra="forbid")
|
20
21
|
|
21
|
-
name:
|
22
|
+
name: NonEmptyString
|
22
23
|
|
23
|
-
command_non_parallel: Optional[
|
24
|
-
command_parallel: Optional[
|
24
|
+
command_non_parallel: Optional[NonEmptyString] = None
|
25
|
+
command_parallel: Optional[NonEmptyString] = None
|
25
26
|
|
26
27
|
meta_non_parallel: Optional[dict[str, Any]] = None
|
27
28
|
meta_parallel: Optional[dict[str, Any]] = None
|
28
|
-
version: Optional[
|
29
|
+
version: Optional[NonEmptyString] = None
|
29
30
|
args_schema_non_parallel: Optional[dict[str, Any]] = None
|
30
31
|
args_schema_parallel: Optional[dict[str, Any]] = None
|
31
|
-
args_schema_version: Optional[
|
32
|
+
args_schema_version: Optional[NonEmptyString] = None
|
32
33
|
docs_info: Optional[str] = None
|
33
34
|
docs_link: Optional[str] = None
|
34
35
|
|
35
36
|
input_types: dict[str, bool] = Field(default={})
|
36
37
|
output_types: dict[str, bool] = Field(default={})
|
37
38
|
|
38
|
-
category: Optional[
|
39
|
-
modality: Optional[
|
40
|
-
tags: list[
|
41
|
-
authors: Optional[
|
39
|
+
category: Optional[NonEmptyString] = None
|
40
|
+
modality: Optional[NonEmptyString] = None
|
41
|
+
tags: list[NonEmptyString] = Field(default_factory=list)
|
42
|
+
authors: Optional[NonEmptyString] = None
|
42
43
|
|
43
44
|
# Validators
|
45
|
+
|
46
|
+
@field_validator(
|
47
|
+
"command_non_parallel",
|
48
|
+
"command_parallel",
|
49
|
+
"version",
|
50
|
+
"args_schema_version",
|
51
|
+
)
|
52
|
+
@classmethod
|
53
|
+
def _cant_set_none(cls, v):
|
54
|
+
return cant_set_none(v)
|
55
|
+
|
44
56
|
@model_validator(mode="after")
|
45
57
|
def validate_commands(self):
|
46
58
|
command_parallel = self.command_parallel
|
@@ -57,15 +69,6 @@ class TaskCreateV2(BaseModel):
|
|
57
69
|
|
58
70
|
return self
|
59
71
|
|
60
|
-
_name = field_validator("name")(classmethod(valstr("name")))
|
61
|
-
_command_non_parallel = field_validator("command_non_parallel")(
|
62
|
-
classmethod(valstr("command_non_parallel"))
|
63
|
-
)
|
64
|
-
_command_parallel = field_validator("command_parallel")(
|
65
|
-
classmethod(valstr("command_parallel"))
|
66
|
-
)
|
67
|
-
_version = field_validator("version")(classmethod(valstr("version")))
|
68
|
-
|
69
72
|
_meta_non_parallel = field_validator("meta_non_parallel")(
|
70
73
|
classmethod(valdict_keys("meta_non_parallel"))
|
71
74
|
)
|
@@ -78,9 +81,6 @@ class TaskCreateV2(BaseModel):
|
|
78
81
|
_args_schema_parallel = field_validator("args_schema_parallel")(
|
79
82
|
classmethod(valdict_keys("args_schema_parallel"))
|
80
83
|
)
|
81
|
-
_args_schema_version = field_validator("args_schema_version")(
|
82
|
-
classmethod(valstr("args_schema_version"))
|
83
|
-
)
|
84
84
|
_input_types = field_validator("input_types")(
|
85
85
|
classmethod(valdict_keys("input_types"))
|
86
86
|
)
|
@@ -88,21 +88,9 @@ class TaskCreateV2(BaseModel):
|
|
88
88
|
classmethod(valdict_keys("output_types"))
|
89
89
|
)
|
90
90
|
|
91
|
-
_category = field_validator("category")(
|
92
|
-
classmethod(valstr("category", accept_none=True))
|
93
|
-
)
|
94
|
-
_modality = field_validator("modality")(
|
95
|
-
classmethod(valstr("modality", accept_none=True))
|
96
|
-
)
|
97
|
-
_authors = field_validator("authors")(
|
98
|
-
classmethod(valstr("authors", accept_none=True))
|
99
|
-
)
|
100
|
-
|
101
91
|
@field_validator("tags")
|
102
92
|
@classmethod
|
103
93
|
def validate_list_of_strings(cls, value):
|
104
|
-
for i, tag in enumerate(value):
|
105
|
-
value[i] = valstr(f"tags[{i}]")(cls, tag)
|
106
94
|
return val_unique_list("tags")(cls, value)
|
107
95
|
|
108
96
|
@field_validator("docs_link", mode="after")
|
@@ -143,17 +131,23 @@ class TaskReadV2(BaseModel):
|
|
143
131
|
class TaskUpdateV2(BaseModel):
|
144
132
|
model_config = ConfigDict(extra="forbid")
|
145
133
|
|
146
|
-
command_parallel: Optional[
|
147
|
-
command_non_parallel: Optional[
|
134
|
+
command_parallel: Optional[NonEmptyString] = None
|
135
|
+
command_non_parallel: Optional[NonEmptyString] = None
|
148
136
|
input_types: Optional[dict[str, bool]] = None
|
149
137
|
output_types: Optional[dict[str, bool]] = None
|
150
138
|
|
151
|
-
category: Optional[
|
152
|
-
modality: Optional[
|
153
|
-
authors: Optional[
|
154
|
-
tags: Optional[list[
|
139
|
+
category: Optional[NonEmptyString] = None
|
140
|
+
modality: Optional[NonEmptyString] = None
|
141
|
+
authors: Optional[NonEmptyString] = None
|
142
|
+
tags: Optional[list[NonEmptyString]] = None
|
155
143
|
|
156
144
|
# Validators
|
145
|
+
|
146
|
+
@field_validator("command_parallel", "command_non_parallel")
|
147
|
+
@classmethod
|
148
|
+
def _cant_set_none(cls, v):
|
149
|
+
return cant_set_none(v)
|
150
|
+
|
157
151
|
@field_validator("input_types", "output_types")
|
158
152
|
@classmethod
|
159
153
|
def val_is_dict(cls, v):
|
@@ -161,12 +155,6 @@ class TaskUpdateV2(BaseModel):
|
|
161
155
|
raise ValueError
|
162
156
|
return v
|
163
157
|
|
164
|
-
_command_parallel = field_validator("command_parallel")(
|
165
|
-
classmethod(valstr("command_parallel"))
|
166
|
-
)
|
167
|
-
_command_non_parallel = field_validator("command_non_parallel")(
|
168
|
-
classmethod(valstr("command_non_parallel"))
|
169
|
-
)
|
170
158
|
_input_types = field_validator("input_types")(
|
171
159
|
classmethod(valdict_keys("input_types"))
|
172
160
|
)
|
@@ -174,49 +162,25 @@ class TaskUpdateV2(BaseModel):
|
|
174
162
|
classmethod(valdict_keys("output_types"))
|
175
163
|
)
|
176
164
|
|
177
|
-
_category = field_validator("category")(
|
178
|
-
classmethod(valstr("category", accept_none=True))
|
179
|
-
)
|
180
|
-
_modality = field_validator("modality")(
|
181
|
-
classmethod(valstr("modality", accept_none=True))
|
182
|
-
)
|
183
|
-
_authors = field_validator("authors")(
|
184
|
-
classmethod(valstr("authors", accept_none=True))
|
185
|
-
)
|
186
|
-
|
187
165
|
@field_validator("tags")
|
188
166
|
@classmethod
|
189
167
|
def validate_tags(cls, value):
|
190
|
-
for i, tag in enumerate(value):
|
191
|
-
value[i] = valstr(f"tags[{i}]")(cls, tag)
|
192
168
|
return val_unique_list("tags")(cls, value)
|
193
169
|
|
194
170
|
|
195
171
|
class TaskImportV2(BaseModel):
|
196
172
|
model_config = ConfigDict(extra="forbid")
|
197
173
|
|
198
|
-
pkg_name:
|
199
|
-
version: Optional[
|
200
|
-
name:
|
201
|
-
_pkg_name = field_validator("pkg_name")(classmethod(valstr("pkg_name")))
|
202
|
-
_version = field_validator("version")(
|
203
|
-
classmethod(valstr("version", accept_none=True))
|
204
|
-
)
|
205
|
-
_name = field_validator("name")(classmethod(valstr("name")))
|
174
|
+
pkg_name: NonEmptyString
|
175
|
+
version: Optional[NonEmptyString] = None
|
176
|
+
name: NonEmptyString
|
206
177
|
|
207
178
|
|
208
179
|
class TaskImportV2Legacy(BaseModel):
|
209
|
-
source:
|
210
|
-
_source = field_validator("source")(classmethod(valstr("source")))
|
180
|
+
source: NonEmptyString
|
211
181
|
|
212
182
|
|
213
183
|
class TaskExportV2(BaseModel):
|
214
|
-
pkg_name:
|
215
|
-
version: Optional[
|
216
|
-
name:
|
217
|
-
|
218
|
-
_pkg_name = field_validator("pkg_name")(classmethod(valstr("pkg_name")))
|
219
|
-
_version = field_validator("version")(
|
220
|
-
classmethod(valstr("version", accept_none=True))
|
221
|
-
)
|
222
|
-
_name = field_validator("name")(classmethod(valstr("name")))
|
184
|
+
pkg_name: NonEmptyString
|
185
|
+
version: Optional[NonEmptyString] = None
|
186
|
+
name: NonEmptyString
|
@@ -7,7 +7,7 @@ from pydantic import ConfigDict
|
|
7
7
|
from pydantic import field_validator
|
8
8
|
from pydantic import model_validator
|
9
9
|
|
10
|
-
from .._validators import
|
10
|
+
from .._validators import NonEmptyString
|
11
11
|
from fractal_server.app.schemas.v2 import ManifestV2
|
12
12
|
from fractal_server.string_tools import validate_cmd
|
13
13
|
|
@@ -46,9 +46,9 @@ class TaskCollectPipV2(BaseModel):
|
|
46
46
|
"""
|
47
47
|
|
48
48
|
model_config = ConfigDict(extra="forbid")
|
49
|
-
package: Optional[
|
50
|
-
package_version: Optional[
|
51
|
-
package_extras: Optional[
|
49
|
+
package: Optional[NonEmptyString] = None
|
50
|
+
package_version: Optional[NonEmptyString] = None
|
51
|
+
package_extras: Optional[NonEmptyString] = None
|
52
52
|
python_version: Optional[Literal["3.9", "3.10", "3.11", "3.12"]] = None
|
53
53
|
pinned_package_versions: Optional[dict[str, str]] = None
|
54
54
|
|
@@ -57,7 +57,6 @@ class TaskCollectPipV2(BaseModel):
|
|
57
57
|
def package_validator(cls, value: Optional[str]) -> Optional[str]:
|
58
58
|
if value is None:
|
59
59
|
return value
|
60
|
-
value = valstr("package")(cls, value)
|
61
60
|
validate_cmd(value, attribute_name="package")
|
62
61
|
return value
|
63
62
|
|
@@ -66,7 +65,6 @@ class TaskCollectPipV2(BaseModel):
|
|
66
65
|
def package_version_validator(cls, value: Optional[str]) -> Optional[str]:
|
67
66
|
if value is None:
|
68
67
|
return value
|
69
|
-
value = valstr("package_version")(cls, value)
|
70
68
|
validate_cmd(value, attribute_name="package_version")
|
71
69
|
return value
|
72
70
|
|
@@ -75,11 +73,11 @@ class TaskCollectPipV2(BaseModel):
|
|
75
73
|
def pinned_package_versions_validator(cls, value):
|
76
74
|
if value is None:
|
77
75
|
return value
|
76
|
+
|
78
77
|
old_keys = list(value.keys())
|
79
|
-
new_keys = [
|
80
|
-
|
81
|
-
|
82
|
-
]
|
78
|
+
new_keys = [key.strip() for key in old_keys]
|
79
|
+
if any(k == "" for k in new_keys):
|
80
|
+
raise ValueError(f"Empty string in {new_keys}.")
|
83
81
|
if len(new_keys) != len(set(new_keys)):
|
84
82
|
raise ValueError(
|
85
83
|
f"Dictionary contains multiple identical keys: {value}."
|
@@ -87,6 +85,7 @@ class TaskCollectPipV2(BaseModel):
|
|
87
85
|
for old_key, new_key in zip(old_keys, new_keys):
|
88
86
|
if new_key != old_key:
|
89
87
|
value[new_key] = value.pop(old_key)
|
88
|
+
|
90
89
|
for pkg, version in value.items():
|
91
90
|
validate_cmd(pkg)
|
92
91
|
validate_cmd(version)
|
@@ -97,7 +96,6 @@ class TaskCollectPipV2(BaseModel):
|
|
97
96
|
def package_extras_validator(cls, value: Optional[str]) -> Optional[str]:
|
98
97
|
if value is None:
|
99
98
|
return value
|
100
|
-
value = valstr("package_extras")(cls, value)
|
101
99
|
validate_cmd(value, attribute_name="package_extras")
|
102
100
|
return value
|
103
101
|
|
@@ -122,26 +120,11 @@ class TaskCollectCustomV2(BaseModel):
|
|
122
120
|
|
123
121
|
model_config = ConfigDict(extra="forbid")
|
124
122
|
manifest: ManifestV2
|
125
|
-
python_interpreter:
|
126
|
-
label:
|
127
|
-
package_root: Optional[
|
128
|
-
package_name: Optional[
|
129
|
-
version: Optional[
|
130
|
-
|
131
|
-
# Valstr
|
132
|
-
_python_interpreter = field_validator("python_interpreter")(
|
133
|
-
classmethod(valstr("python_interpreter"))
|
134
|
-
)
|
135
|
-
_label = field_validator("label")(classmethod(valstr("label")))
|
136
|
-
_package_root = field_validator("package_root")(
|
137
|
-
classmethod(valstr("package_root", accept_none=True))
|
138
|
-
)
|
139
|
-
_package_name = field_validator("package_name")(
|
140
|
-
classmethod(valstr("package_name", accept_none=True))
|
141
|
-
)
|
142
|
-
_version = field_validator("version")(
|
143
|
-
classmethod(valstr("version", accept_none=True))
|
144
|
-
)
|
123
|
+
python_interpreter: NonEmptyString
|
124
|
+
label: NonEmptyString
|
125
|
+
package_root: Optional[NonEmptyString] = None
|
126
|
+
package_name: Optional[NonEmptyString] = None
|
127
|
+
version: Optional[NonEmptyString] = None
|
145
128
|
|
146
129
|
@model_validator(mode="before")
|
147
130
|
@classmethod
|
@@ -165,7 +148,6 @@ class TaskCollectCustomV2(BaseModel):
|
|
165
148
|
"""
|
166
149
|
if value is not None:
|
167
150
|
validate_cmd(value)
|
168
|
-
value = valstr("package_name")(cls, value)
|
169
151
|
value = value.replace(" ", "")
|
170
152
|
return value
|
171
153
|
|
@@ -9,9 +9,10 @@ from pydantic import field_serializer
|
|
9
9
|
from pydantic import field_validator
|
10
10
|
from pydantic.types import AwareDatetime
|
11
11
|
|
12
|
+
from .._validators import cant_set_none
|
13
|
+
from .._validators import NonEmptyString
|
12
14
|
from .._validators import val_absolute_path
|
13
15
|
from .._validators import valdict_keys
|
14
|
-
from .._validators import valstr
|
15
16
|
from .task import TaskReadV2
|
16
17
|
|
17
18
|
|
@@ -42,15 +43,21 @@ class TaskGroupCreateV2(BaseModel):
|
|
42
43
|
origin: TaskGroupV2OriginEnum
|
43
44
|
pkg_name: str
|
44
45
|
version: Optional[str] = None
|
45
|
-
python_version: Optional[
|
46
|
+
python_version: Optional[NonEmptyString] = None
|
46
47
|
path: Optional[str] = None
|
47
48
|
venv_path: Optional[str] = None
|
48
49
|
wheel_path: Optional[str] = None
|
49
|
-
pip_extras: Optional[
|
50
|
+
pip_extras: Optional[NonEmptyString] = None
|
50
51
|
pip_freeze: Optional[str] = None
|
51
52
|
pinned_package_versions: dict[str, str] = Field(default_factory=dict)
|
52
53
|
|
53
54
|
# Validators
|
55
|
+
|
56
|
+
@field_validator("python_version", "pip_extras")
|
57
|
+
@classmethod
|
58
|
+
def _cant_set_none(cls, v):
|
59
|
+
return cant_set_none(v)
|
60
|
+
|
54
61
|
_path = field_validator("path")(classmethod(val_absolute_path("path")))
|
55
62
|
_venv_path = field_validator("venv_path")(
|
56
63
|
classmethod(val_absolute_path("venv_path"))
|
@@ -61,12 +68,6 @@ class TaskGroupCreateV2(BaseModel):
|
|
61
68
|
_pinned_package_versions = field_validator("pinned_package_versions")(
|
62
69
|
valdict_keys("pinned_package_versions")
|
63
70
|
)
|
64
|
-
_pip_extras = field_validator("pip_extras")(
|
65
|
-
classmethod(valstr("pip_extras"))
|
66
|
-
)
|
67
|
-
_python_version = field_validator("python_version")(
|
68
|
-
classmethod(valstr("python_version"))
|
69
|
-
)
|
70
71
|
|
71
72
|
|
72
73
|
class TaskGroupCreateV2Strict(TaskGroupCreateV2):
|
@@ -7,7 +7,8 @@ from pydantic import field_serializer
|
|
7
7
|
from pydantic import field_validator
|
8
8
|
from pydantic.types import AwareDatetime
|
9
9
|
|
10
|
-
from .._validators import
|
10
|
+
from .._validators import cant_set_none
|
11
|
+
from .._validators import NonEmptyString
|
11
12
|
from .project import ProjectReadV2
|
12
13
|
from .workflowtask import WorkflowTaskExportV2
|
13
14
|
from .workflowtask import WorkflowTaskImportV2
|
@@ -19,10 +20,7 @@ class WorkflowCreateV2(BaseModel):
|
|
19
20
|
|
20
21
|
model_config = ConfigDict(extra="forbid")
|
21
22
|
|
22
|
-
name:
|
23
|
-
|
24
|
-
# Validators
|
25
|
-
_name = field_validator("name")(classmethod(valstr("name")))
|
23
|
+
name: NonEmptyString
|
26
24
|
|
27
25
|
|
28
26
|
class WorkflowReadV2(BaseModel):
|
@@ -47,11 +45,15 @@ class WorkflowUpdateV2(BaseModel):
|
|
47
45
|
|
48
46
|
model_config = ConfigDict(extra="forbid")
|
49
47
|
|
50
|
-
name: Optional[
|
48
|
+
name: Optional[NonEmptyString] = None
|
51
49
|
reordered_workflowtask_ids: Optional[list[int]] = None
|
52
50
|
|
53
51
|
# Validators
|
54
|
-
|
52
|
+
|
53
|
+
@field_validator("name")
|
54
|
+
@classmethod
|
55
|
+
def _cant_set_none(cls, v):
|
56
|
+
return cant_set_none(v)
|
55
57
|
|
56
58
|
@field_validator("reordered_workflowtask_ids")
|
57
59
|
@classmethod
|
@@ -72,12 +74,9 @@ class WorkflowImportV2(BaseModel):
|
|
72
74
|
"""
|
73
75
|
|
74
76
|
model_config = ConfigDict(extra="forbid")
|
75
|
-
name:
|
77
|
+
name: NonEmptyString
|
76
78
|
task_list: list[WorkflowTaskImportV2]
|
77
79
|
|
78
|
-
# Validators
|
79
|
-
_name = field_validator("name")(classmethod(valstr("name")))
|
80
|
-
|
81
80
|
|
82
81
|
class WorkflowExportV2(BaseModel):
|
83
82
|
"""
|
@@ -36,8 +36,8 @@ def mail_new_oauth_signup(msg: str, email_settings: MailSettings):
|
|
36
36
|
server.ehlo()
|
37
37
|
if email_settings.use_login:
|
38
38
|
password = (
|
39
|
-
Fernet(email_settings.encryption_key)
|
40
|
-
.decrypt(email_settings.encrypted_password)
|
39
|
+
Fernet(email_settings.encryption_key.get_secret_value())
|
40
|
+
.decrypt(email_settings.encrypted_password.get_secret_value())
|
41
41
|
.decode("utf-8")
|
42
42
|
)
|
43
43
|
server.login(user=email_settings.sender, password=password)
|