fractal-server 2.14.4a0__py3-none-any.whl → 2.14.6__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 (110) 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 +16 -22
  45. fractal_server/app/runner/executors/base_runner.py +19 -7
  46. fractal_server/app/runner/executors/call_command_wrapper.py +52 -0
  47. fractal_server/app/runner/executors/local/get_local_config.py +2 -3
  48. fractal_server/app/runner/executors/local/runner.py +52 -13
  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 +95 -63
  52. fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +2 -3
  53. fractal_server/app/runner/executors/slurm_common/remote.py +47 -92
  54. fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +22 -22
  55. fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +2 -3
  56. fractal_server/app/runner/executors/slurm_ssh/runner.py +4 -6
  57. fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +2 -6
  58. fractal_server/app/runner/executors/slurm_sudo/runner.py +9 -18
  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 -13
  62. fractal_server/app/runner/v2/_local.py +3 -4
  63. fractal_server/app/runner/v2/_slurm_ssh.py +5 -7
  64. fractal_server/app/runner/v2/_slurm_sudo.py +8 -10
  65. fractal_server/app/runner/v2/runner.py +4 -5
  66. fractal_server/app/runner/v2/runner_functions.py +20 -35
  67. fractal_server/app/runner/v2/submit_workflow.py +7 -10
  68. fractal_server/app/runner/v2/task_interface.py +2 -3
  69. fractal_server/app/runner/versions.py +3 -13
  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 -42
  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 +41 -13
  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.4a0.dist-info → fractal_server-2.14.6.dist-info}/METADATA +2 -9
  104. {fractal_server-2.14.4a0.dist-info → fractal_server-2.14.6.dist-info}/RECORD +107 -108
  105. fractal_server/app/history/__init__.py +0 -0
  106. fractal_server/app/runner/executors/slurm_common/utils_executors.py +0 -58
  107. fractal_server/app/runner/v2/runner_functions_low_level.py +0 -122
  108. {fractal_server-2.14.4a0.dist-info → fractal_server-2.14.6.dist-info}/LICENSE +0 -0
  109. {fractal_server-2.14.4a0.dist-info → fractal_server-2.14.6.dist-info}/WHEEL +0 -0
  110. {fractal_server-2.14.4a0.dist-info → fractal_server-2.14.6.dist-info}/entry_points.txt +0 -0
@@ -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
@@ -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
@@ -14,20 +13,20 @@ from fractal_server.types import DictStrStr
14
13
  from fractal_server.types import NonEmptyStr
15
14
 
16
15
 
17
- class TaskGroupV2OriginEnum(str, Enum):
16
+ class TaskGroupV2OriginEnum(StrEnum):
18
17
  PYPI = "pypi"
19
18
  WHEELFILE = "wheel-file"
20
19
  OTHER = "other"
21
20
 
22
21
 
23
- class TaskGroupActivityStatusV2(str, Enum):
22
+ class TaskGroupActivityStatusV2(StrEnum):
24
23
  PENDING = "pending"
25
24
  ONGOING = "ongoing"
26
25
  FAILED = "failed"
27
26
  OK = "OK"
28
27
 
29
28
 
30
- class TaskGroupActivityActionV2(str, Enum):
29
+ class TaskGroupActivityActionV2(StrEnum):
31
30
  COLLECT = "collect"
32
31
  DEACTIVATE = "deactivate"
33
32
  REACTIVATE = "reactivate"
@@ -36,17 +35,17 @@ class TaskGroupActivityActionV2(str, Enum):
36
35
  class TaskGroupCreateV2(BaseModel):
37
36
  model_config = ConfigDict(extra="forbid")
38
37
  user_id: int
39
- user_group_id: Optional[int] = None
38
+ user_group_id: int | None = None
40
39
  active: bool = True
41
40
  origin: TaskGroupV2OriginEnum
42
41
  pkg_name: str
43
- version: Optional[str] = None
42
+ version: str | None = None
44
43
  python_version: NonEmptyStr = None
45
44
  path: AbsolutePathStr = None
46
45
  venv_path: AbsolutePathStr = None
47
46
  wheel_path: AbsolutePathStr = None
48
47
  pip_extras: NonEmptyStr = None
49
- pip_freeze: Optional[str] = None
48
+ pip_freeze: str | None = None
50
49
  pinned_package_versions: DictStrStr = Field(default_factory=dict)
51
50
 
52
51
 
@@ -66,21 +65,21 @@ class TaskGroupReadV2(BaseModel):
66
65
  task_list: list[TaskReadV2]
67
66
 
68
67
  user_id: int
69
- user_group_id: Optional[int] = None
68
+ user_group_id: int | None = None
70
69
 
71
70
  origin: TaskGroupV2OriginEnum
72
71
  pkg_name: str
73
- version: Optional[str] = None
74
- python_version: Optional[str] = None
75
- path: Optional[str] = None
76
- venv_path: Optional[str] = None
77
- wheel_path: Optional[str] = None
78
- pip_freeze: Optional[str] = None
79
- pip_extras: Optional[str] = None
72
+ version: str | None = None
73
+ python_version: str | None = None
74
+ path: str | None = None
75
+ venv_path: str | None = None
76
+ wheel_path: str | None = None
77
+ pip_freeze: str | None = None
78
+ pip_extras: str | None = None
80
79
  pinned_package_versions: dict[str, str] = Field(default_factory=dict)
81
80
 
82
- venv_size_in_kB: Optional[int] = None
83
- venv_file_number: Optional[int] = None
81
+ venv_size_in_kB: int | None = None
82
+ venv_file_number: int | None = None
84
83
 
85
84
  active: bool
86
85
  timestamp_created: AwareDatetime
@@ -93,27 +92,27 @@ class TaskGroupReadV2(BaseModel):
93
92
 
94
93
  class TaskGroupUpdateV2(BaseModel):
95
94
  model_config = ConfigDict(extra="forbid")
96
- user_group_id: Optional[int] = None
95
+ user_group_id: int | None = None
97
96
 
98
97
 
99
98
  class TaskGroupActivityV2Read(BaseModel):
100
99
  id: int
101
100
  user_id: int
102
- taskgroupv2_id: Optional[int] = None
101
+ taskgroupv2_id: int | None = None
103
102
  timestamp_started: AwareDatetime
104
- timestamp_ended: Optional[AwareDatetime] = None
103
+ timestamp_ended: AwareDatetime | None = None
105
104
  pkg_name: str
106
105
  version: str
107
106
  status: TaskGroupActivityStatusV2
108
107
  action: TaskGroupActivityActionV2
109
- log: Optional[str] = None
108
+ log: str | None = None
110
109
 
111
110
  @field_serializer("timestamp_started")
112
111
  def serialize_datetime_start(v: datetime) -> str:
113
112
  return v.isoformat()
114
113
 
115
114
  @field_serializer("timestamp_ended")
116
- def serialize_datetime_end(v: Optional[datetime]) -> Optional[str]:
115
+ def serialize_datetime_end(v: datetime | None) -> str | None:
117
116
  if v is None:
118
117
  return None
119
118
  else:
@@ -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
@@ -47,7 +46,7 @@ class WorkflowUpdateV2(BaseModel):
47
46
  model_config = ConfigDict(extra="forbid")
48
47
 
49
48
  name: NonEmptyStr = None
50
- reordered_workflowtask_ids: Optional[ListUniqueNonNegativeInt] = None
49
+ reordered_workflowtask_ids: ListUniqueNonNegativeInt | None = None
51
50
 
52
51
 
53
52
  class WorkflowImportV2(BaseModel):
@@ -1,6 +1,4 @@
1
1
  from typing import Any
2
- from typing import Optional
3
- from typing import Union
4
2
 
5
3
  from pydantic import BaseModel
6
4
  from pydantic import ConfigDict
@@ -20,30 +18,30 @@ from fractal_server.types import WorkflowTaskArgument
20
18
  class WorkflowTaskCreateV2(BaseModel):
21
19
  model_config = ConfigDict(extra="forbid")
22
20
 
23
- meta_non_parallel: Optional[DictStrAny] = None
24
- meta_parallel: Optional[DictStrAny] = None
25
- args_non_parallel: Optional[WorkflowTaskArgument] = None
26
- args_parallel: Optional[WorkflowTaskArgument] = None
21
+ meta_non_parallel: DictStrAny | None = None
22
+ meta_parallel: DictStrAny | None = None
23
+ args_non_parallel: WorkflowTaskArgument | None = None
24
+ args_parallel: WorkflowTaskArgument | None = None
27
25
  type_filters: TypeFilters = Field(default_factory=dict)
28
26
 
29
27
 
30
28
  class WorkflowTaskReplaceV2(BaseModel):
31
29
  """Used by 'replace-task' endpoint"""
32
30
 
33
- args_non_parallel: Optional[dict[str, Any]] = None
34
- args_parallel: Optional[dict[str, Any]] = None
31
+ args_non_parallel: dict[str, Any] | None = None
32
+ args_parallel: dict[str, Any] | None = None
35
33
 
36
34
 
37
35
  class WorkflowTaskReadV2(BaseModel):
38
36
  id: int
39
37
 
40
38
  workflow_id: int
41
- order: Optional[int] = None
42
- meta_non_parallel: Optional[dict[str, Any]] = None
43
- meta_parallel: Optional[dict[str, Any]] = None
39
+ order: int | None = None
40
+ meta_non_parallel: dict[str, Any] | None = None
41
+ meta_parallel: dict[str, Any] | None = None
44
42
 
45
- args_non_parallel: Optional[dict[str, Any]] = None
46
- args_parallel: Optional[dict[str, Any]] = None
43
+ args_non_parallel: dict[str, Any] | None = None
44
+ args_parallel: dict[str, Any] | None = None
47
45
 
48
46
  type_filters: dict[str, bool]
49
47
 
@@ -53,30 +51,30 @@ class WorkflowTaskReadV2(BaseModel):
53
51
 
54
52
 
55
53
  class WorkflowTaskReadV2WithWarning(WorkflowTaskReadV2):
56
- warning: Optional[str] = None
54
+ warning: str | None = None
57
55
 
58
56
 
59
57
  class WorkflowTaskUpdateV2(BaseModel):
60
58
  model_config = ConfigDict(extra="forbid")
61
59
 
62
- meta_non_parallel: Optional[DictStrAny] = None
63
- meta_parallel: Optional[DictStrAny] = None
64
- args_non_parallel: Optional[WorkflowTaskArgument] = None
65
- args_parallel: Optional[WorkflowTaskArgument] = None
60
+ meta_non_parallel: DictStrAny | None = None
61
+ meta_parallel: DictStrAny | None = None
62
+ args_non_parallel: WorkflowTaskArgument | None = None
63
+ args_parallel: WorkflowTaskArgument | None = None
66
64
  type_filters: TypeFilters = None
67
65
 
68
66
 
69
67
  class WorkflowTaskImportV2(BaseModel):
70
68
  model_config = ConfigDict(extra="forbid")
71
69
 
72
- meta_non_parallel: Optional[DictStrAny] = None
73
- meta_parallel: Optional[DictStrAny] = None
74
- args_non_parallel: Optional[DictStrAny] = None
75
- args_parallel: Optional[DictStrAny] = None
76
- type_filters: Optional[TypeFilters] = None
77
- input_filters: Optional[dict[str, Any]] = None
70
+ meta_non_parallel: DictStrAny | None = None
71
+ meta_parallel: DictStrAny | None = None
72
+ args_non_parallel: DictStrAny | None = None
73
+ args_parallel: DictStrAny | None = None
74
+ type_filters: TypeFilters | None = None
75
+ input_filters: dict[str, Any] | None = None
78
76
 
79
- task: Union[TaskImportV2, TaskImportV2Legacy]
77
+ task: TaskImportV2 | TaskImportV2Legacy
80
78
 
81
79
  @model_validator(mode="before")
82
80
  @classmethod
@@ -108,10 +106,10 @@ class WorkflowTaskImportV2(BaseModel):
108
106
 
109
107
 
110
108
  class WorkflowTaskExportV2(BaseModel):
111
- meta_non_parallel: Optional[dict[str, Any]] = None
112
- meta_parallel: Optional[dict[str, Any]] = None
113
- args_non_parallel: Optional[dict[str, Any]] = None
114
- args_parallel: Optional[dict[str, Any]] = None
109
+ meta_non_parallel: dict[str, Any] | None = None
110
+ meta_parallel: dict[str, Any] | None = None
111
+ args_non_parallel: dict[str, Any] | None = None
112
+ args_parallel: dict[str, Any] | None = None
115
113
  type_filters: dict[str, bool] = Field(default_factory=dict)
116
114
 
117
115
  task: TaskExportV2