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.
Files changed (108) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/app/db/__init__.py +2 -2
  3. fractal_server/app/models/security.py +8 -8
  4. fractal_server/app/models/user_settings.py +8 -10
  5. fractal_server/app/models/v2/accounting.py +2 -3
  6. fractal_server/app/models/v2/dataset.py +1 -2
  7. fractal_server/app/models/v2/history.py +3 -4
  8. fractal_server/app/models/v2/job.py +10 -11
  9. fractal_server/app/models/v2/project.py +1 -2
  10. fractal_server/app/models/v2/task.py +13 -14
  11. fractal_server/app/models/v2/task_group.py +15 -16
  12. fractal_server/app/models/v2/workflow.py +1 -2
  13. fractal_server/app/models/v2/workflowtask.py +6 -7
  14. fractal_server/app/routes/admin/v2/accounting.py +3 -4
  15. fractal_server/app/routes/admin/v2/job.py +13 -14
  16. fractal_server/app/routes/admin/v2/project.py +2 -4
  17. fractal_server/app/routes/admin/v2/task.py +11 -13
  18. fractal_server/app/routes/admin/v2/task_group.py +15 -17
  19. fractal_server/app/routes/admin/v2/task_group_lifecycle.py +5 -8
  20. fractal_server/app/routes/api/v2/__init__.py +2 -0
  21. fractal_server/app/routes/api/v2/_aux_functions.py +7 -9
  22. fractal_server/app/routes/api/v2/_aux_functions_history.py +1 -1
  23. fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +1 -3
  24. fractal_server/app/routes/api/v2/_aux_functions_tasks.py +5 -6
  25. fractal_server/app/routes/api/v2/dataset.py +6 -8
  26. fractal_server/app/routes/api/v2/history.py +5 -8
  27. fractal_server/app/routes/api/v2/images.py +2 -3
  28. fractal_server/app/routes/api/v2/job.py +5 -6
  29. fractal_server/app/routes/api/v2/pre_submission_checks.py +1 -3
  30. fractal_server/app/routes/api/v2/project.py +2 -4
  31. fractal_server/app/routes/api/v2/status_legacy.py +2 -4
  32. fractal_server/app/routes/api/v2/submit.py +3 -4
  33. fractal_server/app/routes/api/v2/task.py +6 -7
  34. fractal_server/app/routes/api/v2/task_collection.py +11 -13
  35. fractal_server/app/routes/api/v2/task_collection_custom.py +4 -4
  36. fractal_server/app/routes/api/v2/task_group.py +6 -8
  37. fractal_server/app/routes/api/v2/task_group_lifecycle.py +6 -9
  38. fractal_server/app/routes/api/v2/task_version_update.py +270 -0
  39. fractal_server/app/routes/api/v2/workflow.py +5 -6
  40. fractal_server/app/routes/api/v2/workflow_import.py +3 -5
  41. fractal_server/app/routes/api/v2/workflowtask.py +2 -114
  42. fractal_server/app/routes/auth/current_user.py +2 -2
  43. fractal_server/app/routes/pagination.py +2 -3
  44. fractal_server/app/runner/exceptions.py +15 -16
  45. fractal_server/app/runner/executors/base_runner.py +3 -3
  46. fractal_server/app/runner/executors/call_command_wrapper.py +1 -1
  47. fractal_server/app/runner/executors/local/get_local_config.py +2 -3
  48. fractal_server/app/runner/executors/local/runner.py +1 -1
  49. fractal_server/app/runner/executors/slurm_common/_batching.py +2 -3
  50. fractal_server/app/runner/executors/slurm_common/_slurm_config.py +27 -29
  51. fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +32 -14
  52. fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +2 -3
  53. fractal_server/app/runner/executors/slurm_common/remote.py +2 -2
  54. fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +2 -3
  55. fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +2 -3
  56. fractal_server/app/runner/executors/slurm_ssh/runner.py +5 -4
  57. fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -2
  58. fractal_server/app/runner/executors/slurm_sudo/runner.py +7 -8
  59. fractal_server/app/runner/set_start_and_last_task_index.py +2 -5
  60. fractal_server/app/runner/shutdown.py +5 -11
  61. fractal_server/app/runner/task_files.py +3 -5
  62. fractal_server/app/runner/v2/_local.py +3 -4
  63. fractal_server/app/runner/v2/_slurm_ssh.py +8 -7
  64. fractal_server/app/runner/v2/_slurm_sudo.py +8 -9
  65. fractal_server/app/runner/v2/runner.py +4 -5
  66. fractal_server/app/runner/v2/runner_functions.py +4 -5
  67. fractal_server/app/runner/v2/submit_workflow.py +12 -11
  68. fractal_server/app/runner/v2/task_interface.py +2 -3
  69. fractal_server/app/runner/versions.py +1 -2
  70. fractal_server/app/schemas/user.py +2 -4
  71. fractal_server/app/schemas/user_group.py +1 -2
  72. fractal_server/app/schemas/user_settings.py +19 -21
  73. fractal_server/app/schemas/v2/dataset.py +2 -3
  74. fractal_server/app/schemas/v2/dumps.py +13 -15
  75. fractal_server/app/schemas/v2/history.py +6 -7
  76. fractal_server/app/schemas/v2/job.py +17 -18
  77. fractal_server/app/schemas/v2/manifest.py +12 -13
  78. fractal_server/app/schemas/v2/status_legacy.py +2 -2
  79. fractal_server/app/schemas/v2/task.py +29 -30
  80. fractal_server/app/schemas/v2/task_collection.py +8 -9
  81. fractal_server/app/schemas/v2/task_group.py +22 -23
  82. fractal_server/app/schemas/v2/workflow.py +1 -2
  83. fractal_server/app/schemas/v2/workflowtask.py +27 -29
  84. fractal_server/app/security/__init__.py +10 -12
  85. fractal_server/config.py +32 -33
  86. fractal_server/images/models.py +2 -4
  87. fractal_server/images/tools.py +4 -7
  88. fractal_server/logger.py +3 -5
  89. fractal_server/ssh/_fabric.py +37 -12
  90. fractal_server/string_tools.py +2 -2
  91. fractal_server/syringe.py +1 -1
  92. fractal_server/tasks/v2/local/collect.py +2 -3
  93. fractal_server/tasks/v2/local/deactivate.py +1 -1
  94. fractal_server/tasks/v2/local/reactivate.py +1 -1
  95. fractal_server/tasks/v2/ssh/collect.py +256 -245
  96. fractal_server/tasks/v2/ssh/deactivate.py +210 -187
  97. fractal_server/tasks/v2/ssh/reactivate.py +154 -146
  98. fractal_server/tasks/v2/utils_background.py +2 -3
  99. fractal_server/types/__init__.py +1 -2
  100. fractal_server/types/validators/_filter_validators.py +1 -2
  101. fractal_server/utils.py +4 -5
  102. fractal_server/zip_tools.py +1 -1
  103. {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/METADATA +2 -3
  104. {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/RECORD +107 -107
  105. fractal_server/app/history/__init__.py +0 -0
  106. {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/LICENSE +0 -0
  107. {fractal_server-2.14.5.dist-info → fractal_server-2.14.7.dist-info}/WHEEL +0 -0
  108. {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
- Optional[Path],
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
- Optional[Path],
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
- Optional[Path],
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: Optional[str] = None,
73
- slurm_user: Optional[str] = None,
74
- user_cache_dir: Optional[str] = None,
75
- fractal_ssh: Optional[FractalSSH] = None,
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: Optional[JobV2] = db_sync.get(JobV2, job_id)
113
- dataset: Optional[DatasetV2] = db_sync.get(DatasetV2, dataset_id)
114
- workflow: Optional[WorkflowV2] = db_sync.get(
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(fractal_ssh=fractal_ssh)
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
- ) -> Optional[TaskOutput]:
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
- ) -> Optional[InitTaskOutput]:
73
+ ) -> InitTaskOutput | None:
75
74
  try:
76
75
  validated_init_task_output = InitTaskOutput(**init_task_output)
77
76
  return validated_init_task_output
@@ -1,11 +1,10 @@
1
1
  import json
2
2
  import sys
3
- from typing import Union
4
3
 
5
4
  import fractal_server
6
5
 
7
6
 
8
- def get_versions() -> dict[str, Union[list[int], str]]:
7
+ def get_versions() -> dict[str, list[int] | str]:
9
8
  """
10
9
  Extract versions of Python and fractal-server.
11
10
  """
@@ -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: Optional[str] = None
45
- group_ids_names: Optional[list[tuple[int, str]]] = None
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: Optional[list[int]] = None
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: Optional[str] = None
27
- ssh_username: Optional[str] = None
28
- ssh_private_key_path: Optional[str] = None
29
- ssh_tasks_dir: Optional[str] = None
30
- ssh_jobs_dir: Optional[str] = None
31
- slurm_user: Optional[str] = None
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: Optional[str] = None
31
+ project_dir: str | None = None
34
32
 
35
33
 
36
34
  class UserSettingsReadStrict(BaseModel):
37
- slurm_user: Optional[str] = None
35
+ slurm_user: str | None = None
38
36
  slurm_accounts: list[str]
39
- ssh_username: Optional[str] = None
40
- project_dir: Optional[str] = None
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: Optional[NonEmptyStr] = None
51
- ssh_username: Optional[NonEmptyStr] = None
52
- ssh_private_key_path: Optional[AbsolutePathStr] = None
53
- ssh_tasks_dir: Optional[AbsolutePathStr] = None
54
- ssh_jobs_dir: Optional[AbsolutePathStr] = None
55
- slurm_user: Optional[NonEmptyStr] = None
56
- slurm_accounts: Optional[ListUniqueNonEmptyString] = None
57
- project_dir: Optional[AbsolutePathStr] = None
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: Optional[ListUniqueNonEmptyString] = None
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: Optional[ZarrDirStr] = None
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: Optional[ZarrDirStr] = None
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: Optional[str] = None
33
- command_parallel: Optional[str] = None
34
- source: Optional[str] = None
35
- version: Optional[str] = None
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: Optional[int] = None
48
+ order: int | None = None
51
49
 
52
50
  type_filters: dict[str, bool]
53
51
 
54
- task_id: Optional[int] = None
55
- task: Optional[TaskDumpV2] = None
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: Optional[str] = None
85
- python_version: Optional[str] = None
86
- pip_extras: Optional[str] = None
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: Optional[str] = None
90
- venv_path: Optional[str] = None
91
- wheel_path: Optional[str] = None
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 Enum
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(str, Enum):
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(str, Enum):
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: Optional[str] = None
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: Optional[int] = None
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: Optional[HistoryUnitStatus] = None
79
+ status: HistoryUnitStatus | None = None
@@ -1,6 +1,5 @@
1
1
  from datetime import datetime
2
- from enum import Enum
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(str, Enum):
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: Optional[NonNegativeInt] = None
47
- last_task_index: Optional[NonNegativeInt] = None
48
- slurm_account: Optional[StrictStr] = None
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: Optional[int] = None
70
+ project_id: int | None = None
72
71
  project_dump: ProjectDumpV2
73
72
  user_email: str
74
- slurm_account: Optional[str] = None
75
- workflow_id: Optional[int] = None
73
+ slurm_account: str | None = None
74
+ workflow_id: int | None = None
76
75
  workflow_dump: WorkflowDumpV2
77
- dataset_id: Optional[int] = None
76
+ dataset_id: int | None = None
78
77
  dataset_dump: DatasetDumpV2
79
78
  start_timestamp: AwareDatetime
80
- end_timestamp: Optional[AwareDatetime] = None
79
+ end_timestamp: AwareDatetime | None = None
81
80
  status: str
82
- log: Optional[str] = None
83
- working_dir: Optional[str] = None
84
- working_dir_user: Optional[str] = None
85
- first_task_index: Optional[int] = None
86
- last_task_index: Optional[int] = None
87
- worker_init: Optional[str] = None
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: Optional[datetime]) -> Optional[str]:
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: Optional[str] = None
45
- executable_parallel: Optional[str] = None
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: Optional[DictStrAny] = None
51
- args_schema_parallel: Optional[DictStrAny] = None
52
- docs_info: Optional[str] = None
53
- docs_link: Optional[HttpUrlStr] = None
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: Optional[str] = None
56
- modality: Optional[str] = None
54
+ category: str | None = None
55
+ modality: str | None = None
57
56
  tags: list[str] = Field(default_factory=list)
58
57
 
59
- type: Optional[
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
- ] = None
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: Optional[str] = None
144
- authors: Optional[NonEmptyStr] = None
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 Enum
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(str, Enum):
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: Optional[DictStrAny] = None
39
- meta_parallel: Optional[DictStrAny] = None
37
+ meta_non_parallel: DictStrAny | None = None
38
+ meta_parallel: DictStrAny | None = None
40
39
  version: NonEmptyStr = None
41
- args_schema_non_parallel: Optional[DictStrAny] = None
42
- args_schema_parallel: Optional[DictStrAny] = None
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: Optional[str] = None
45
- docs_link: Optional[HttpUrlStr] = None
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: Optional[NonEmptyStr] = None
51
- modality: Optional[NonEmptyStr] = None
49
+ category: NonEmptyStr | None = None
50
+ modality: NonEmptyStr | None = None
52
51
  tags: ListUniqueNonEmptyString = Field(default_factory=list)
53
- authors: Optional[NonEmptyStr] = None
52
+ authors: NonEmptyStr | None = None
54
53
 
55
- type: Optional[TaskTypeType] = None
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: Optional[str] = None
96
- version: Optional[str] = None
94
+ source: str | None = None
95
+ version: str | None = None
97
96
 
98
- command_non_parallel: Optional[str] = None
99
- command_parallel: Optional[str] = None
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: Optional[dict[str, Any]] = None
103
- args_schema_parallel: Optional[dict[str, Any]] = None
104
- args_schema_version: Optional[str] = None
105
- docs_info: Optional[str] = None
106
- docs_link: Optional[str] = None
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: Optional[int] = None
109
+ taskgroupv2_id: int | None = None
111
110
 
112
- category: Optional[str] = None
113
- modality: Optional[str] = None
114
- authors: Optional[str] = None
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: Optional[NonEmptyStr] = None
127
- modality: Optional[NonEmptyStr] = None
128
- authors: Optional[NonEmptyStr] = None
129
- tags: Optional[ListUniqueNonEmptyString] = None
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: Optional[NonEmptyStr] = None
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: Optional[NonEmptyStr] = None
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: Optional[NonEmptyStr] = None
51
- package_version: Optional[NonEmptyStr] = None
52
- package_extras: Optional[NonEmptyStr] = None
53
- python_version: Optional[Literal["3.9", "3.10", "3.11", "3.12"]] = None
54
- pinned_package_versions: Optional[DictStrStr] = None
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: Optional[AbsolutePathStr] = None
98
- package_name: Optional[NonEmptyStr] = None
99
- version: Optional[NonEmptyStr] = None
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