fractal-server 2.14.5__py3-none-any.whl → 2.14.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fractal_server/__init__.py +1 -1
- fractal_server/app/db/__init__.py +2 -2
- fractal_server/app/models/security.py +8 -8
- fractal_server/app/models/user_settings.py +8 -10
- fractal_server/app/models/v2/accounting.py +2 -3
- fractal_server/app/models/v2/dataset.py +1 -2
- fractal_server/app/models/v2/history.py +3 -4
- fractal_server/app/models/v2/job.py +10 -11
- fractal_server/app/models/v2/project.py +1 -2
- fractal_server/app/models/v2/task.py +13 -14
- fractal_server/app/models/v2/task_group.py +15 -16
- fractal_server/app/models/v2/workflow.py +1 -2
- fractal_server/app/models/v2/workflowtask.py +6 -7
- fractal_server/app/routes/admin/v2/accounting.py +3 -4
- fractal_server/app/routes/admin/v2/job.py +13 -14
- fractal_server/app/routes/admin/v2/project.py +2 -4
- fractal_server/app/routes/admin/v2/task.py +11 -13
- fractal_server/app/routes/admin/v2/task_group.py +15 -17
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +5 -8
- fractal_server/app/routes/api/v2/__init__.py +2 -0
- fractal_server/app/routes/api/v2/_aux_functions.py +7 -9
- fractal_server/app/routes/api/v2/_aux_functions_history.py +1 -1
- fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +1 -3
- fractal_server/app/routes/api/v2/_aux_functions_tasks.py +5 -6
- fractal_server/app/routes/api/v2/dataset.py +6 -8
- fractal_server/app/routes/api/v2/history.py +5 -8
- fractal_server/app/routes/api/v2/images.py +2 -3
- fractal_server/app/routes/api/v2/job.py +5 -6
- fractal_server/app/routes/api/v2/pre_submission_checks.py +1 -3
- fractal_server/app/routes/api/v2/project.py +2 -4
- fractal_server/app/routes/api/v2/status_legacy.py +2 -4
- fractal_server/app/routes/api/v2/submit.py +3 -4
- fractal_server/app/routes/api/v2/task.py +6 -7
- fractal_server/app/routes/api/v2/task_collection.py +11 -13
- fractal_server/app/routes/api/v2/task_collection_custom.py +4 -4
- fractal_server/app/routes/api/v2/task_group.py +6 -8
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +6 -9
- fractal_server/app/routes/api/v2/task_version_update.py +270 -0
- fractal_server/app/routes/api/v2/workflow.py +5 -6
- fractal_server/app/routes/api/v2/workflow_import.py +3 -5
- fractal_server/app/routes/api/v2/workflowtask.py +2 -114
- fractal_server/app/routes/auth/current_user.py +2 -2
- fractal_server/app/routes/pagination.py +2 -3
- fractal_server/app/runner/exceptions.py +15 -16
- fractal_server/app/runner/executors/base_runner.py +3 -3
- fractal_server/app/runner/executors/call_command_wrapper.py +1 -1
- fractal_server/app/runner/executors/local/get_local_config.py +2 -3
- fractal_server/app/runner/executors/local/runner.py +1 -1
- fractal_server/app/runner/executors/slurm_common/_batching.py +2 -3
- fractal_server/app/runner/executors/slurm_common/_slurm_config.py +27 -29
- fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +32 -14
- fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +2 -3
- fractal_server/app/runner/executors/slurm_common/remote.py +2 -2
- fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/runner.py +5 -4
- fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -2
- fractal_server/app/runner/executors/slurm_sudo/runner.py +7 -8
- fractal_server/app/runner/set_start_and_last_task_index.py +2 -5
- fractal_server/app/runner/shutdown.py +5 -11
- fractal_server/app/runner/task_files.py +3 -5
- fractal_server/app/runner/v2/_local.py +3 -4
- fractal_server/app/runner/v2/_slurm_ssh.py +8 -7
- fractal_server/app/runner/v2/_slurm_sudo.py +8 -9
- fractal_server/app/runner/v2/runner.py +4 -5
- fractal_server/app/runner/v2/runner_functions.py +4 -5
- fractal_server/app/runner/v2/submit_workflow.py +12 -11
- fractal_server/app/runner/v2/task_interface.py +2 -3
- fractal_server/app/runner/versions.py +1 -2
- fractal_server/app/schemas/user.py +2 -4
- fractal_server/app/schemas/user_group.py +1 -2
- fractal_server/app/schemas/user_settings.py +19 -21
- fractal_server/app/schemas/v2/dataset.py +2 -3
- fractal_server/app/schemas/v2/dumps.py +13 -15
- fractal_server/app/schemas/v2/history.py +6 -7
- fractal_server/app/schemas/v2/job.py +17 -18
- fractal_server/app/schemas/v2/manifest.py +12 -13
- fractal_server/app/schemas/v2/status_legacy.py +2 -2
- fractal_server/app/schemas/v2/task.py +29 -30
- fractal_server/app/schemas/v2/task_collection.py +8 -9
- fractal_server/app/schemas/v2/task_group.py +22 -23
- fractal_server/app/schemas/v2/workflow.py +1 -2
- fractal_server/app/schemas/v2/workflowtask.py +27 -29
- fractal_server/app/security/__init__.py +10 -12
- fractal_server/config.py +32 -33
- fractal_server/images/models.py +2 -4
- fractal_server/images/tools.py +4 -7
- fractal_server/logger.py +3 -5
- fractal_server/ssh/_fabric.py +37 -12
- fractal_server/string_tools.py +2 -2
- fractal_server/syringe.py +1 -1
- fractal_server/tasks/v2/local/collect.py +2 -3
- fractal_server/tasks/v2/local/deactivate.py +1 -1
- fractal_server/tasks/v2/local/reactivate.py +1 -1
- fractal_server/tasks/v2/ssh/collect.py +256 -245
- fractal_server/tasks/v2/ssh/deactivate.py +210 -187
- fractal_server/tasks/v2/ssh/reactivate.py +154 -146
- fractal_server/tasks/v2/utils_background.py +2 -3
- fractal_server/types/__init__.py +1 -2
- fractal_server/types/validators/_filter_validators.py +1 -2
- fractal_server/utils.py +4 -5
- fractal_server/zip_tools.py +1 -1
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/METADATA +2 -3
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/RECORD +107 -107
- fractal_server/app/history/__init__.py +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/LICENSE +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/WHEEL +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/entry_points.txt +0 -0
@@ -1,8 +1,7 @@
|
|
1
|
+
from collections.abc import Callable
|
1
2
|
from pathlib import Path
|
2
3
|
from typing import Any
|
3
|
-
from typing import Callable
|
4
4
|
from typing import Literal
|
5
|
-
from typing import Optional
|
6
5
|
|
7
6
|
from pydantic import BaseModel
|
8
7
|
from pydantic import ConfigDict
|
@@ -129,7 +128,7 @@ def run_v2_task_non_parallel(
|
|
129
128
|
[
|
130
129
|
WorkflowTaskV2,
|
131
130
|
Literal["non_parallel", "parallel"],
|
132
|
-
|
131
|
+
Path | None,
|
133
132
|
int,
|
134
133
|
],
|
135
134
|
Any,
|
@@ -251,7 +250,7 @@ def run_v2_task_parallel(
|
|
251
250
|
[
|
252
251
|
WorkflowTaskV2,
|
253
252
|
Literal["non_parallel", "parallel"],
|
254
|
-
|
253
|
+
Path | None,
|
255
254
|
int,
|
256
255
|
],
|
257
256
|
Any,
|
@@ -382,7 +381,7 @@ def run_v2_task_compound(
|
|
382
381
|
[
|
383
382
|
WorkflowTaskV2,
|
384
383
|
Literal["non_parallel", "parallel"],
|
385
|
-
|
384
|
+
Path | None,
|
386
385
|
int,
|
387
386
|
],
|
388
387
|
Any,
|
@@ -8,7 +8,6 @@ the individual backends.
|
|
8
8
|
import os
|
9
9
|
import traceback
|
10
10
|
from pathlib import Path
|
11
|
-
from typing import Optional
|
12
11
|
|
13
12
|
from sqlalchemy.orm import Session as DBSyncSession
|
14
13
|
|
@@ -69,10 +68,10 @@ def submit_workflow(
|
|
69
68
|
job_id: int,
|
70
69
|
user_id: int,
|
71
70
|
user_settings: UserSettings,
|
72
|
-
worker_init:
|
73
|
-
slurm_user:
|
74
|
-
user_cache_dir:
|
75
|
-
fractal_ssh:
|
71
|
+
worker_init: str | None = None,
|
72
|
+
slurm_user: str | None = None,
|
73
|
+
user_cache_dir: str | None = None,
|
74
|
+
fractal_ssh: FractalSSH | None = None,
|
76
75
|
) -> None:
|
77
76
|
"""
|
78
77
|
Prepares a workflow and applies it to a dataset
|
@@ -109,11 +108,9 @@ def submit_workflow(
|
|
109
108
|
|
110
109
|
with next(DB.get_sync_db()) as db_sync:
|
111
110
|
try:
|
112
|
-
job:
|
113
|
-
dataset:
|
114
|
-
workflow:
|
115
|
-
WorkflowV2, workflow_id
|
116
|
-
)
|
111
|
+
job: JobV2 | None = db_sync.get(JobV2, job_id)
|
112
|
+
dataset: DatasetV2 | None = db_sync.get(DatasetV2, dataset_id)
|
113
|
+
workflow: WorkflowV2 | None = db_sync.get(WorkflowV2, workflow_id)
|
117
114
|
except Exception as e:
|
118
115
|
logger.error(
|
119
116
|
f"Error connecting to the database. Original error: {str(e)}"
|
@@ -239,6 +236,7 @@ def submit_workflow(
|
|
239
236
|
elif FRACTAL_RUNNER_BACKEND == "slurm_ssh":
|
240
237
|
logger.debug(f"ssh_user: {user_settings.ssh_username}")
|
241
238
|
logger.debug(f"base dir: {user_settings.ssh_tasks_dir}")
|
239
|
+
logger.debug(f"slurm_account: {job.slurm_account}")
|
242
240
|
logger.debug(f"worker_init: {worker_init}")
|
243
241
|
logger.debug(f"job.id: {job.id}")
|
244
242
|
logger.debug(f"job.working_dir: {job.working_dir}")
|
@@ -260,7 +258,10 @@ def submit_workflow(
|
|
260
258
|
)
|
261
259
|
elif FRACTAL_RUNNER_BACKEND == "slurm_ssh":
|
262
260
|
process_workflow = slurm_ssh_process_workflow
|
263
|
-
backend_specific_kwargs = dict(
|
261
|
+
backend_specific_kwargs = dict(
|
262
|
+
fractal_ssh=fractal_ssh,
|
263
|
+
slurm_account=job.slurm_account,
|
264
|
+
)
|
264
265
|
else:
|
265
266
|
raise RuntimeError(
|
266
267
|
f"Invalid runner backend {FRACTAL_RUNNER_BACKEND=}"
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from typing import Any
|
2
|
-
from typing import Optional
|
3
2
|
|
4
3
|
from pydantic import BaseModel
|
5
4
|
from pydantic import ConfigDict
|
@@ -57,7 +56,7 @@ class InitTaskOutput(BaseModel):
|
|
57
56
|
|
58
57
|
def _cast_and_validate_TaskOutput(
|
59
58
|
task_output: dict[str, Any]
|
60
|
-
) ->
|
59
|
+
) -> TaskOutput | None:
|
61
60
|
try:
|
62
61
|
validated_task_output = TaskOutput(**task_output)
|
63
62
|
return validated_task_output
|
@@ -71,7 +70,7 @@ def _cast_and_validate_TaskOutput(
|
|
71
70
|
|
72
71
|
def _cast_and_validate_InitTaskOutput(
|
73
72
|
init_task_output: dict[str, Any],
|
74
|
-
) ->
|
73
|
+
) -> InitTaskOutput | None:
|
75
74
|
try:
|
76
75
|
validated_init_task_output = InitTaskOutput(**init_task_output)
|
77
76
|
return validated_init_task_output
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import Optional
|
2
|
-
|
3
1
|
from fastapi_users import schemas
|
4
2
|
from pydantic import BaseModel
|
5
3
|
from pydantic import ConfigDict
|
@@ -41,8 +39,8 @@ class UserRead(schemas.BaseUser[int]):
|
|
41
39
|
username:
|
42
40
|
"""
|
43
41
|
|
44
|
-
username:
|
45
|
-
group_ids_names:
|
42
|
+
username: str | None = None
|
43
|
+
group_ids_names: list[tuple[int, str]] | None = None
|
46
44
|
oauth_accounts: list[OAuthAccountRead]
|
47
45
|
|
48
46
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import Optional
|
3
2
|
|
4
3
|
from pydantic import BaseModel
|
5
4
|
from pydantic import ConfigDict
|
@@ -33,7 +32,7 @@ class UserGroupRead(BaseModel):
|
|
33
32
|
id: int
|
34
33
|
name: str
|
35
34
|
timestamp_created: AwareDatetime
|
36
|
-
user_ids:
|
35
|
+
user_ids: list[int] | None = None
|
37
36
|
viewer_paths: list[str]
|
38
37
|
|
39
38
|
@field_serializer("timestamp_created")
|
@@ -1,5 +1,3 @@
|
|
1
|
-
from typing import Optional
|
2
|
-
|
3
1
|
from pydantic import BaseModel
|
4
2
|
from pydantic import ConfigDict
|
5
3
|
from pydantic import field_validator
|
@@ -23,21 +21,21 @@ class UserSettingsRead(BaseModel):
|
|
23
21
|
"""
|
24
22
|
|
25
23
|
id: int
|
26
|
-
ssh_host:
|
27
|
-
ssh_username:
|
28
|
-
ssh_private_key_path:
|
29
|
-
ssh_tasks_dir:
|
30
|
-
ssh_jobs_dir:
|
31
|
-
slurm_user:
|
24
|
+
ssh_host: str | None = None
|
25
|
+
ssh_username: str | None = None
|
26
|
+
ssh_private_key_path: str | None = None
|
27
|
+
ssh_tasks_dir: str | None = None
|
28
|
+
ssh_jobs_dir: str | None = None
|
29
|
+
slurm_user: str | None = None
|
32
30
|
slurm_accounts: list[str]
|
33
|
-
project_dir:
|
31
|
+
project_dir: str | None = None
|
34
32
|
|
35
33
|
|
36
34
|
class UserSettingsReadStrict(BaseModel):
|
37
|
-
slurm_user:
|
35
|
+
slurm_user: str | None = None
|
38
36
|
slurm_accounts: list[str]
|
39
|
-
ssh_username:
|
40
|
-
project_dir:
|
37
|
+
ssh_username: str | None = None
|
38
|
+
project_dir: str | None = None
|
41
39
|
|
42
40
|
|
43
41
|
class UserSettingsUpdate(BaseModel):
|
@@ -47,14 +45,14 @@ class UserSettingsUpdate(BaseModel):
|
|
47
45
|
|
48
46
|
model_config = ConfigDict(extra="forbid")
|
49
47
|
|
50
|
-
ssh_host:
|
51
|
-
ssh_username:
|
52
|
-
ssh_private_key_path:
|
53
|
-
ssh_tasks_dir:
|
54
|
-
ssh_jobs_dir:
|
55
|
-
slurm_user:
|
56
|
-
slurm_accounts:
|
57
|
-
project_dir:
|
48
|
+
ssh_host: NonEmptyStr | None = None
|
49
|
+
ssh_username: NonEmptyStr | None = None
|
50
|
+
ssh_private_key_path: AbsolutePathStr | None = None
|
51
|
+
ssh_tasks_dir: AbsolutePathStr | None = None
|
52
|
+
ssh_jobs_dir: AbsolutePathStr | None = None
|
53
|
+
slurm_user: NonEmptyStr | None = None
|
54
|
+
slurm_accounts: ListUniqueNonEmptyString | None = None
|
55
|
+
project_dir: AbsolutePathStr | None = None
|
58
56
|
|
59
57
|
@field_validator("project_dir", mode="after")
|
60
58
|
@classmethod
|
@@ -66,4 +64,4 @@ class UserSettingsUpdate(BaseModel):
|
|
66
64
|
|
67
65
|
class UserSettingsUpdateStrict(BaseModel):
|
68
66
|
model_config = ConfigDict(extra="forbid")
|
69
|
-
slurm_accounts:
|
67
|
+
slurm_accounts: ListUniqueNonEmptyString | None = None
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import Optional
|
3
2
|
|
4
3
|
from pydantic import BaseModel
|
5
4
|
from pydantic import ConfigDict
|
@@ -19,7 +18,7 @@ class DatasetCreateV2(BaseModel):
|
|
19
18
|
|
20
19
|
name: NonEmptyStr
|
21
20
|
|
22
|
-
zarr_dir:
|
21
|
+
zarr_dir: ZarrDirStr | None = None
|
23
22
|
|
24
23
|
attribute_filters: AttributeFilters = Field(default_factory=dict)
|
25
24
|
|
@@ -44,7 +43,7 @@ class DatasetUpdateV2(BaseModel):
|
|
44
43
|
model_config = ConfigDict(extra="forbid")
|
45
44
|
|
46
45
|
name: NonEmptyStr = None
|
47
|
-
zarr_dir:
|
46
|
+
zarr_dir: ZarrDirStr | None = None
|
48
47
|
|
49
48
|
|
50
49
|
class DatasetImportV2(BaseModel):
|
@@ -7,8 +7,6 @@ These models are used in at least two situations:
|
|
7
7
|
1. In the "*_dump" attributes of Job models;
|
8
8
|
2. In the history items, to trim their size.
|
9
9
|
"""
|
10
|
-
from typing import Optional
|
11
|
-
|
12
10
|
from pydantic import BaseModel
|
13
11
|
from pydantic import ConfigDict
|
14
12
|
from pydantic import Field
|
@@ -29,10 +27,10 @@ class TaskDumpV2(BaseModel):
|
|
29
27
|
name: str
|
30
28
|
type: TaskTypeType
|
31
29
|
|
32
|
-
command_non_parallel:
|
33
|
-
command_parallel:
|
34
|
-
source:
|
35
|
-
version:
|
30
|
+
command_non_parallel: str | None = None
|
31
|
+
command_parallel: str | None = None
|
32
|
+
source: str | None = None
|
33
|
+
version: str | None = None
|
36
34
|
|
37
35
|
input_types: dict[str, bool]
|
38
36
|
output_types: dict[str, bool]
|
@@ -47,12 +45,12 @@ class WorkflowTaskDumpV2(BaseModel):
|
|
47
45
|
|
48
46
|
id: int
|
49
47
|
workflow_id: int
|
50
|
-
order:
|
48
|
+
order: int | None = None
|
51
49
|
|
52
50
|
type_filters: dict[str, bool]
|
53
51
|
|
54
|
-
task_id:
|
55
|
-
task:
|
52
|
+
task_id: int | None = None
|
53
|
+
task: TaskDumpV2 | None = None
|
56
54
|
|
57
55
|
|
58
56
|
class WorkflowDumpV2(BaseModel):
|
@@ -81,11 +79,11 @@ class TaskGroupDumpV2(BaseModel):
|
|
81
79
|
id: int
|
82
80
|
origin: TaskGroupV2OriginEnum
|
83
81
|
pkg_name: str
|
84
|
-
version:
|
85
|
-
python_version:
|
86
|
-
pip_extras:
|
82
|
+
version: str | None = None
|
83
|
+
python_version: str | None = None
|
84
|
+
pip_extras: str | None = None
|
87
85
|
pinned_package_versions: dict[str, str] = Field(default_factory=dict)
|
88
86
|
|
89
|
-
path:
|
90
|
-
venv_path:
|
91
|
-
wheel_path:
|
87
|
+
path: str | None = None
|
88
|
+
venv_path: str | None = None
|
89
|
+
wheel_path: str | None = None
|
@@ -1,7 +1,6 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from enum import
|
2
|
+
from enum import StrEnum
|
3
3
|
from typing import Any
|
4
|
-
from typing import Optional
|
5
4
|
|
6
5
|
from pydantic import AwareDatetime
|
7
6
|
from pydantic import BaseModel
|
@@ -10,7 +9,7 @@ from pydantic import field_serializer
|
|
10
9
|
from ....images import SingleImage
|
11
10
|
|
12
11
|
|
13
|
-
class HistoryUnitStatus(
|
12
|
+
class HistoryUnitStatus(StrEnum):
|
14
13
|
"""
|
15
14
|
Available status for images
|
16
15
|
|
@@ -25,7 +24,7 @@ class HistoryUnitStatus(str, Enum):
|
|
25
24
|
FAILED = "failed"
|
26
25
|
|
27
26
|
|
28
|
-
class HistoryUnitStatusQuery(
|
27
|
+
class HistoryUnitStatusQuery(StrEnum):
|
29
28
|
|
30
29
|
SUBMITTED = "submitted"
|
31
30
|
DONE = "done"
|
@@ -36,7 +35,7 @@ class HistoryUnitStatusQuery(str, Enum):
|
|
36
35
|
|
37
36
|
class HistoryUnitRead(BaseModel):
|
38
37
|
id: int
|
39
|
-
logfile:
|
38
|
+
logfile: str | None = None
|
40
39
|
status: HistoryUnitStatus
|
41
40
|
zarr_urls: list[str]
|
42
41
|
|
@@ -44,7 +43,7 @@ class HistoryUnitRead(BaseModel):
|
|
44
43
|
class HistoryRunRead(BaseModel):
|
45
44
|
id: int
|
46
45
|
dataset_id: int
|
47
|
-
workflowtask_id:
|
46
|
+
workflowtask_id: int | None = None
|
48
47
|
job_id: int
|
49
48
|
workflowtask_dump: dict[str, Any]
|
50
49
|
task_group_dump: dict[str, Any]
|
@@ -77,4 +76,4 @@ class ImageLogsRequest(BaseModel):
|
|
77
76
|
|
78
77
|
|
79
78
|
class SingleImageWithStatus(SingleImage):
|
80
|
-
status:
|
79
|
+
status: HistoryUnitStatus | None = None
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from enum import
|
3
|
-
from typing import Optional
|
2
|
+
from enum import StrEnum
|
4
3
|
|
5
4
|
from pydantic import BaseModel
|
6
5
|
from pydantic import ConfigDict
|
@@ -19,7 +18,7 @@ from fractal_server.types import NonEmptyStr
|
|
19
18
|
from fractal_server.types import TypeFilters
|
20
19
|
|
21
20
|
|
22
|
-
class JobStatusTypeV2(
|
21
|
+
class JobStatusTypeV2(StrEnum):
|
23
22
|
"""
|
24
23
|
Define the available job statuses
|
25
24
|
|
@@ -43,9 +42,9 @@ class JobStatusTypeV2(str, Enum):
|
|
43
42
|
class JobCreateV2(BaseModel):
|
44
43
|
model_config = ConfigDict(extra="forbid")
|
45
44
|
|
46
|
-
first_task_index:
|
47
|
-
last_task_index:
|
48
|
-
slurm_account:
|
45
|
+
first_task_index: NonNegativeInt | None = None
|
46
|
+
last_task_index: NonNegativeInt | None = None
|
47
|
+
slurm_account: StrictStr | None = None
|
49
48
|
worker_init: NonEmptyStr = None
|
50
49
|
|
51
50
|
attribute_filters: AttributeFilters = Field(default_factory=dict)
|
@@ -68,23 +67,23 @@ class JobCreateV2(BaseModel):
|
|
68
67
|
|
69
68
|
class JobReadV2(BaseModel):
|
70
69
|
id: int
|
71
|
-
project_id:
|
70
|
+
project_id: int | None = None
|
72
71
|
project_dump: ProjectDumpV2
|
73
72
|
user_email: str
|
74
|
-
slurm_account:
|
75
|
-
workflow_id:
|
73
|
+
slurm_account: str | None = None
|
74
|
+
workflow_id: int | None = None
|
76
75
|
workflow_dump: WorkflowDumpV2
|
77
|
-
dataset_id:
|
76
|
+
dataset_id: int | None = None
|
78
77
|
dataset_dump: DatasetDumpV2
|
79
78
|
start_timestamp: AwareDatetime
|
80
|
-
end_timestamp:
|
79
|
+
end_timestamp: AwareDatetime | None = None
|
81
80
|
status: str
|
82
|
-
log:
|
83
|
-
working_dir:
|
84
|
-
working_dir_user:
|
85
|
-
first_task_index:
|
86
|
-
last_task_index:
|
87
|
-
worker_init:
|
81
|
+
log: str | None = None
|
82
|
+
working_dir: str | None = None
|
83
|
+
working_dir_user: str | None = None
|
84
|
+
first_task_index: int | None = None
|
85
|
+
last_task_index: int | None = None
|
86
|
+
worker_init: str | None = None
|
88
87
|
attribute_filters: AttributeFilters
|
89
88
|
type_filters: dict[str, bool]
|
90
89
|
|
@@ -93,7 +92,7 @@ class JobReadV2(BaseModel):
|
|
93
92
|
return v.isoformat()
|
94
93
|
|
95
94
|
@field_serializer("end_timestamp")
|
96
|
-
def serialize_datetime_end(v:
|
95
|
+
def serialize_datetime_end(v: datetime | None) -> str | None:
|
97
96
|
if v is None:
|
98
97
|
return None
|
99
98
|
else:
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from typing import Literal
|
2
|
-
from typing import Optional
|
3
2
|
|
4
3
|
from pydantic import BaseModel
|
5
4
|
from pydantic import Field
|
@@ -41,22 +40,22 @@ class TaskManifestV2(BaseModel):
|
|
41
40
|
"""
|
42
41
|
|
43
42
|
name: str
|
44
|
-
executable_non_parallel:
|
45
|
-
executable_parallel:
|
43
|
+
executable_non_parallel: str | None = None
|
44
|
+
executable_parallel: str | None = None
|
46
45
|
input_types: dict[str, bool] = Field(default_factory=dict)
|
47
46
|
output_types: dict[str, bool] = Field(default_factory=dict)
|
48
47
|
meta_non_parallel: DictStrAny = Field(default_factory=dict)
|
49
48
|
meta_parallel: DictStrAny = Field(default_factory=dict)
|
50
|
-
args_schema_non_parallel:
|
51
|
-
args_schema_parallel:
|
52
|
-
docs_info:
|
53
|
-
docs_link:
|
49
|
+
args_schema_non_parallel: DictStrAny | None = None
|
50
|
+
args_schema_parallel: DictStrAny | None = None
|
51
|
+
docs_info: str | None = None
|
52
|
+
docs_link: HttpUrlStr | None = None
|
54
53
|
|
55
|
-
category:
|
56
|
-
modality:
|
54
|
+
category: str | None = None
|
55
|
+
modality: str | None = None
|
57
56
|
tags: list[str] = Field(default_factory=list)
|
58
57
|
|
59
|
-
type:
|
58
|
+
type: None | (
|
60
59
|
Literal[
|
61
60
|
"compound",
|
62
61
|
"converter_compound",
|
@@ -64,7 +63,7 @@ class TaskManifestV2(BaseModel):
|
|
64
63
|
"converter_non_parallel",
|
65
64
|
"parallel",
|
66
65
|
]
|
67
|
-
|
66
|
+
) = None
|
68
67
|
|
69
68
|
@model_validator(mode="after")
|
70
69
|
def validate_executable_args_meta(self):
|
@@ -140,8 +139,8 @@ class ManifestV2(BaseModel):
|
|
140
139
|
manifest_version: Literal["2"]
|
141
140
|
task_list: list[TaskManifestV2]
|
142
141
|
has_args_schemas: bool = False
|
143
|
-
args_schema_version:
|
144
|
-
authors:
|
142
|
+
args_schema_version: str | None = None
|
143
|
+
authors: NonEmptyStr | None = None
|
145
144
|
|
146
145
|
@model_validator(mode="after")
|
147
146
|
def _check_args_schemas_are_present(self):
|
@@ -1,10 +1,10 @@
|
|
1
|
-
from enum import
|
1
|
+
from enum import StrEnum
|
2
2
|
|
3
3
|
from pydantic import BaseModel
|
4
4
|
from pydantic import Field
|
5
5
|
|
6
6
|
|
7
|
-
class WorkflowTaskStatusTypeV2(
|
7
|
+
class WorkflowTaskStatusTypeV2(StrEnum):
|
8
8
|
"""
|
9
9
|
Define the available values for the status of a `WorkflowTask`.
|
10
10
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from typing import Any
|
2
2
|
from typing import Literal
|
3
|
-
from typing import Optional
|
4
3
|
|
5
4
|
from pydantic import BaseModel
|
6
5
|
from pydantic import ConfigDict
|
@@ -35,24 +34,24 @@ class TaskCreateV2(BaseModel):
|
|
35
34
|
command_non_parallel: NonEmptyStr = None
|
36
35
|
command_parallel: NonEmptyStr = None
|
37
36
|
|
38
|
-
meta_non_parallel:
|
39
|
-
meta_parallel:
|
37
|
+
meta_non_parallel: DictStrAny | None = None
|
38
|
+
meta_parallel: DictStrAny | None = None
|
40
39
|
version: NonEmptyStr = None
|
41
|
-
args_schema_non_parallel:
|
42
|
-
args_schema_parallel:
|
40
|
+
args_schema_non_parallel: DictStrAny | None = None
|
41
|
+
args_schema_parallel: DictStrAny | None = None
|
43
42
|
args_schema_version: NonEmptyStr = None
|
44
|
-
docs_info:
|
45
|
-
docs_link:
|
43
|
+
docs_info: str | None = None
|
44
|
+
docs_link: HttpUrlStr | None = None
|
46
45
|
|
47
46
|
input_types: TypeFilters = Field(default={})
|
48
47
|
output_types: TypeFilters = Field(default={})
|
49
48
|
|
50
|
-
category:
|
51
|
-
modality:
|
49
|
+
category: NonEmptyStr | None = None
|
50
|
+
modality: NonEmptyStr | None = None
|
52
51
|
tags: ListUniqueNonEmptyString = Field(default_factory=list)
|
53
|
-
authors:
|
52
|
+
authors: NonEmptyStr | None = None
|
54
53
|
|
55
|
-
type:
|
54
|
+
type: TaskTypeType | None = None
|
56
55
|
|
57
56
|
@model_validator(mode="after")
|
58
57
|
def validate_commands(self):
|
@@ -92,26 +91,26 @@ class TaskReadV2(BaseModel):
|
|
92
91
|
id: int
|
93
92
|
name: str
|
94
93
|
type: TaskTypeType
|
95
|
-
source:
|
96
|
-
version:
|
94
|
+
source: str | None = None
|
95
|
+
version: str | None = None
|
97
96
|
|
98
|
-
command_non_parallel:
|
99
|
-
command_parallel:
|
97
|
+
command_non_parallel: str | None = None
|
98
|
+
command_parallel: str | None = None
|
100
99
|
meta_parallel: dict[str, Any]
|
101
100
|
meta_non_parallel: dict[str, Any]
|
102
|
-
args_schema_non_parallel:
|
103
|
-
args_schema_parallel:
|
104
|
-
args_schema_version:
|
105
|
-
docs_info:
|
106
|
-
docs_link:
|
101
|
+
args_schema_non_parallel: dict[str, Any] | None = None
|
102
|
+
args_schema_parallel: dict[str, Any] | None = None
|
103
|
+
args_schema_version: str | None = None
|
104
|
+
docs_info: str | None = None
|
105
|
+
docs_link: str | None = None
|
107
106
|
input_types: dict[str, bool]
|
108
107
|
output_types: dict[str, bool]
|
109
108
|
|
110
|
-
taskgroupv2_id:
|
109
|
+
taskgroupv2_id: int | None = None
|
111
110
|
|
112
|
-
category:
|
113
|
-
modality:
|
114
|
-
authors:
|
111
|
+
category: str | None = None
|
112
|
+
modality: str | None = None
|
113
|
+
authors: str | None = None
|
115
114
|
tags: list[str]
|
116
115
|
|
117
116
|
|
@@ -123,17 +122,17 @@ class TaskUpdateV2(BaseModel):
|
|
123
122
|
input_types: TypeFilters = None
|
124
123
|
output_types: TypeFilters = None
|
125
124
|
|
126
|
-
category:
|
127
|
-
modality:
|
128
|
-
authors:
|
129
|
-
tags:
|
125
|
+
category: NonEmptyStr | None = None
|
126
|
+
modality: NonEmptyStr | None = None
|
127
|
+
authors: NonEmptyStr | None = None
|
128
|
+
tags: ListUniqueNonEmptyString | None = None
|
130
129
|
|
131
130
|
|
132
131
|
class TaskImportV2(BaseModel):
|
133
132
|
model_config = ConfigDict(extra="forbid")
|
134
133
|
|
135
134
|
pkg_name: NonEmptyStr
|
136
|
-
version:
|
135
|
+
version: NonEmptyStr | None = None
|
137
136
|
name: NonEmptyStr
|
138
137
|
|
139
138
|
|
@@ -143,5 +142,5 @@ class TaskImportV2Legacy(BaseModel):
|
|
143
142
|
|
144
143
|
class TaskExportV2(BaseModel):
|
145
144
|
pkg_name: NonEmptyStr
|
146
|
-
version:
|
145
|
+
version: NonEmptyStr | None = None
|
147
146
|
name: NonEmptyStr
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from typing import Literal
|
2
|
-
from typing import Optional
|
3
2
|
|
4
3
|
from pydantic import BaseModel
|
5
4
|
from pydantic import ConfigDict
|
@@ -47,11 +46,11 @@ class TaskCollectPipV2(BaseModel):
|
|
47
46
|
"""
|
48
47
|
|
49
48
|
model_config = ConfigDict(extra="forbid")
|
50
|
-
package:
|
51
|
-
package_version:
|
52
|
-
package_extras:
|
53
|
-
python_version:
|
54
|
-
pinned_package_versions:
|
49
|
+
package: NonEmptyStr | None = None
|
50
|
+
package_version: NonEmptyStr | None = None
|
51
|
+
package_extras: NonEmptyStr | None = None
|
52
|
+
python_version: Literal["3.9", "3.10", "3.11", "3.12"] | None = None
|
53
|
+
pinned_package_versions: DictStrStr | None = None
|
55
54
|
|
56
55
|
@field_validator(
|
57
56
|
"package", "package_version", "package_extras", mode="after"
|
@@ -94,9 +93,9 @@ class TaskCollectCustomV2(BaseModel):
|
|
94
93
|
manifest: ManifestV2
|
95
94
|
python_interpreter: AbsolutePathStr
|
96
95
|
label: NonEmptyStr
|
97
|
-
package_root:
|
98
|
-
package_name:
|
99
|
-
version:
|
96
|
+
package_root: AbsolutePathStr | None = None
|
97
|
+
package_name: NonEmptyStr | None = None
|
98
|
+
version: NonEmptyStr | None = None
|
100
99
|
|
101
100
|
@field_validator("package_name", mode="after")
|
102
101
|
@classmethod
|