fractal-server 1.4.10__py3-none-any.whl → 2.0.0a1__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 (126) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/app/models/__init__.py +3 -7
  3. fractal_server/app/models/linkuserproject.py +9 -0
  4. fractal_server/app/models/security.py +6 -0
  5. fractal_server/app/models/state.py +1 -1
  6. fractal_server/app/models/v1/__init__.py +11 -0
  7. fractal_server/app/models/{dataset.py → v1/dataset.py} +5 -5
  8. fractal_server/app/models/{job.py → v1/job.py} +5 -5
  9. fractal_server/app/models/{project.py → v1/project.py} +5 -5
  10. fractal_server/app/models/{task.py → v1/task.py} +7 -2
  11. fractal_server/app/models/{workflow.py → v1/workflow.py} +5 -5
  12. fractal_server/app/models/v2/__init__.py +20 -0
  13. fractal_server/app/models/v2/dataset.py +55 -0
  14. fractal_server/app/models/v2/job.py +51 -0
  15. fractal_server/app/models/v2/project.py +31 -0
  16. fractal_server/app/models/v2/task.py +93 -0
  17. fractal_server/app/models/v2/workflow.py +43 -0
  18. fractal_server/app/models/v2/workflowtask.py +90 -0
  19. fractal_server/app/routes/{admin.py → admin/v1.py} +42 -42
  20. fractal_server/app/routes/admin/v2.py +274 -0
  21. fractal_server/app/routes/api/v1/__init__.py +7 -7
  22. fractal_server/app/routes/api/v1/_aux_functions.py +2 -2
  23. fractal_server/app/routes/api/v1/dataset.py +37 -37
  24. fractal_server/app/routes/api/v1/job.py +14 -14
  25. fractal_server/app/routes/api/v1/project.py +23 -21
  26. fractal_server/app/routes/api/v1/task.py +24 -14
  27. fractal_server/app/routes/api/v1/task_collection.py +16 -14
  28. fractal_server/app/routes/api/v1/workflow.py +24 -24
  29. fractal_server/app/routes/api/v1/workflowtask.py +10 -10
  30. fractal_server/app/routes/api/v2/__init__.py +28 -0
  31. fractal_server/app/routes/api/v2/_aux_functions.py +497 -0
  32. fractal_server/app/routes/api/v2/dataset.py +309 -0
  33. fractal_server/app/routes/api/v2/images.py +207 -0
  34. fractal_server/app/routes/api/v2/job.py +200 -0
  35. fractal_server/app/routes/api/v2/project.py +202 -0
  36. fractal_server/app/routes/api/v2/submit.py +220 -0
  37. fractal_server/app/routes/api/v2/task.py +222 -0
  38. fractal_server/app/routes/api/v2/task_collection.py +229 -0
  39. fractal_server/app/routes/api/v2/workflow.py +397 -0
  40. fractal_server/app/routes/api/v2/workflowtask.py +269 -0
  41. fractal_server/app/routes/aux/_job.py +1 -1
  42. fractal_server/app/runner/async_wrap.py +27 -0
  43. fractal_server/app/runner/components.py +5 -0
  44. fractal_server/app/runner/exceptions.py +129 -0
  45. fractal_server/app/runner/executors/slurm/__init__.py +3 -0
  46. fractal_server/app/runner/{_slurm → executors/slurm}/_batching.py +1 -1
  47. fractal_server/app/runner/{_slurm → executors/slurm}/_check_jobs_status.py +1 -1
  48. fractal_server/app/runner/{_slurm → executors/slurm}/_executor_wait_thread.py +1 -1
  49. fractal_server/app/runner/{_slurm → executors/slurm}/_slurm_config.py +3 -152
  50. fractal_server/app/runner/{_slurm → executors/slurm}/_subprocess_run_as_user.py +1 -1
  51. fractal_server/app/runner/{_slurm → executors/slurm}/executor.py +32 -19
  52. fractal_server/app/runner/filenames.py +6 -0
  53. fractal_server/app/runner/set_start_and_last_task_index.py +39 -0
  54. fractal_server/app/runner/task_files.py +103 -0
  55. fractal_server/app/runner/{__init__.py → v1/__init__.py} +22 -20
  56. fractal_server/app/runner/{_common.py → v1/_common.py} +13 -120
  57. fractal_server/app/runner/{_local → v1/_local}/__init__.py +5 -5
  58. fractal_server/app/runner/{_local → v1/_local}/_local_config.py +6 -7
  59. fractal_server/app/runner/{_local → v1/_local}/_submit_setup.py +1 -5
  60. fractal_server/app/runner/v1/_slurm/__init__.py +310 -0
  61. fractal_server/app/runner/{_slurm → v1/_slurm}/_submit_setup.py +3 -9
  62. fractal_server/app/runner/v1/_slurm/get_slurm_config.py +163 -0
  63. fractal_server/app/runner/v1/common.py +117 -0
  64. fractal_server/app/runner/{handle_failed_job.py → v1/handle_failed_job.py} +8 -8
  65. fractal_server/app/runner/v2/__init__.py +336 -0
  66. fractal_server/app/runner/v2/_local/__init__.py +167 -0
  67. fractal_server/app/runner/v2/_local/_local_config.py +118 -0
  68. fractal_server/app/runner/v2/_local/_submit_setup.py +52 -0
  69. fractal_server/app/runner/v2/_local/executor.py +100 -0
  70. fractal_server/app/runner/{_slurm → v2/_slurm}/__init__.py +34 -45
  71. fractal_server/app/runner/v2/_slurm/_submit_setup.py +83 -0
  72. fractal_server/app/runner/v2/_slurm/get_slurm_config.py +179 -0
  73. fractal_server/app/runner/v2/deduplicate_list.py +22 -0
  74. fractal_server/app/runner/v2/handle_failed_job.py +156 -0
  75. fractal_server/app/runner/v2/merge_outputs.py +38 -0
  76. fractal_server/app/runner/v2/runner.py +267 -0
  77. fractal_server/app/runner/v2/runner_functions.py +341 -0
  78. fractal_server/app/runner/v2/runner_functions_low_level.py +134 -0
  79. fractal_server/app/runner/v2/task_interface.py +43 -0
  80. fractal_server/app/runner/v2/v1_compat.py +21 -0
  81. fractal_server/app/schemas/__init__.py +4 -42
  82. fractal_server/app/schemas/v1/__init__.py +42 -0
  83. fractal_server/app/schemas/{applyworkflow.py → v1/applyworkflow.py} +18 -18
  84. fractal_server/app/schemas/{dataset.py → v1/dataset.py} +30 -30
  85. fractal_server/app/schemas/{dumps.py → v1/dumps.py} +8 -8
  86. fractal_server/app/schemas/{manifest.py → v1/manifest.py} +5 -5
  87. fractal_server/app/schemas/{project.py → v1/project.py} +9 -9
  88. fractal_server/app/schemas/{task.py → v1/task.py} +12 -12
  89. fractal_server/app/schemas/{task_collection.py → v1/task_collection.py} +7 -7
  90. fractal_server/app/schemas/{workflow.py → v1/workflow.py} +38 -38
  91. fractal_server/app/schemas/v2/__init__.py +34 -0
  92. fractal_server/app/schemas/v2/dataset.py +89 -0
  93. fractal_server/app/schemas/v2/dumps.py +87 -0
  94. fractal_server/app/schemas/v2/job.py +114 -0
  95. fractal_server/app/schemas/v2/manifest.py +159 -0
  96. fractal_server/app/schemas/v2/project.py +37 -0
  97. fractal_server/app/schemas/v2/task.py +120 -0
  98. fractal_server/app/schemas/v2/task_collection.py +105 -0
  99. fractal_server/app/schemas/v2/workflow.py +79 -0
  100. fractal_server/app/schemas/v2/workflowtask.py +119 -0
  101. fractal_server/config.py +5 -4
  102. fractal_server/images/__init__.py +2 -0
  103. fractal_server/images/models.py +50 -0
  104. fractal_server/images/tools.py +85 -0
  105. fractal_server/main.py +11 -3
  106. fractal_server/migrations/env.py +0 -2
  107. fractal_server/migrations/versions/d71e732236cd_v2.py +239 -0
  108. fractal_server/tasks/__init__.py +0 -5
  109. fractal_server/tasks/endpoint_operations.py +13 -19
  110. fractal_server/tasks/utils.py +35 -0
  111. fractal_server/tasks/{_TaskCollectPip.py → v1/_TaskCollectPip.py} +3 -3
  112. fractal_server/tasks/{background_operations.py → v1/background_operations.py} +18 -50
  113. fractal_server/tasks/v1/get_collection_data.py +14 -0
  114. fractal_server/tasks/v2/_TaskCollectPip.py +103 -0
  115. fractal_server/tasks/v2/background_operations.py +381 -0
  116. fractal_server/tasks/v2/get_collection_data.py +14 -0
  117. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0a1.dist-info}/METADATA +1 -1
  118. fractal_server-2.0.0a1.dist-info/RECORD +160 -0
  119. fractal_server/app/runner/_slurm/.gitignore +0 -2
  120. fractal_server/app/runner/common.py +0 -311
  121. fractal_server-1.4.10.dist-info/RECORD +0 -98
  122. /fractal_server/app/runner/{_slurm → executors/slurm}/remote.py +0 -0
  123. /fractal_server/app/runner/{_local → v1/_local}/executor.py +0 -0
  124. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0a1.dist-info}/LICENSE +0 -0
  125. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0a1.dist-info}/WHEEL +0 -0
  126. {fractal_server-1.4.10.dist-info → fractal_server-2.0.0a1.dist-info}/entry_points.txt +0 -0
@@ -6,18 +6,18 @@ from pydantic import Field
6
6
  from pydantic import HttpUrl
7
7
  from pydantic import validator
8
8
 
9
- from ._validators import valstr
9
+ from .._validators import valstr
10
10
 
11
11
  __all__ = (
12
- "TaskCreate",
13
- "TaskUpdate",
14
- "TaskRead",
15
- "TaskImport",
16
- "TaskExport",
12
+ "TaskCreateV1",
13
+ "TaskUpdateV1",
14
+ "TaskReadV1",
15
+ "TaskImportV1",
16
+ "TaskExportV1",
17
17
  )
18
18
 
19
19
 
20
- class _TaskBase(BaseModel):
20
+ class _TaskBaseV1(BaseModel):
21
21
  """
22
22
 
23
23
  Base class for `Task`.
@@ -32,7 +32,7 @@ class _TaskBase(BaseModel):
32
32
  _source = validator("source", allow_reuse=True)(valstr("source"))
33
33
 
34
34
 
35
- class TaskUpdate(_TaskBase):
35
+ class TaskUpdateV1(_TaskBaseV1):
36
36
  """
37
37
  Class for `Task` update.
38
38
 
@@ -76,7 +76,7 @@ class TaskUpdate(_TaskBase):
76
76
  )
77
77
 
78
78
 
79
- class TaskImport(_TaskBase):
79
+ class TaskImportV1(_TaskBaseV1):
80
80
  """
81
81
  Class for `Task` import.
82
82
  """
@@ -84,7 +84,7 @@ class TaskImport(_TaskBase):
84
84
  pass
85
85
 
86
86
 
87
- class TaskExport(_TaskBase):
87
+ class TaskExportV1(_TaskBaseV1):
88
88
  """
89
89
  Class for `Task` export.
90
90
  """
@@ -92,7 +92,7 @@ class TaskExport(_TaskBase):
92
92
  pass
93
93
 
94
94
 
95
- class TaskRead(_TaskBase):
95
+ class TaskReadV1(_TaskBaseV1):
96
96
  """
97
97
  Class for `Task` read from database.
98
98
 
@@ -124,7 +124,7 @@ class TaskRead(_TaskBase):
124
124
  docs_link: Optional[HttpUrl]
125
125
 
126
126
 
127
- class TaskCreate(_TaskBase):
127
+ class TaskCreateV1(_TaskBaseV1):
128
128
  """
129
129
  Class for `Task` creation.
130
130
 
@@ -6,16 +6,16 @@ from pydantic import BaseModel
6
6
  from pydantic import Field
7
7
  from pydantic import validator
8
8
 
9
- from ._validators import valstr
10
- from .task import TaskRead
9
+ from .._validators import valstr
10
+ from .task import TaskReadV1
11
11
 
12
12
  __all__ = (
13
- "TaskCollectPip",
14
- "TaskCollectStatus",
13
+ "TaskCollectPipV1",
14
+ "TaskCollectStatusV1",
15
15
  )
16
16
 
17
17
 
18
- class TaskCollectPip(BaseModel):
18
+ class TaskCollectPipV1(BaseModel):
19
19
  """
20
20
  TaskCollectPip class
21
21
 
@@ -81,7 +81,7 @@ class TaskCollectPip(BaseModel):
81
81
  return v
82
82
 
83
83
 
84
- class TaskCollectStatus(BaseModel):
84
+ class TaskCollectStatusV1(BaseModel):
85
85
  """
86
86
  TaskCollectStatus class
87
87
 
@@ -97,7 +97,7 @@ class TaskCollectStatus(BaseModel):
97
97
  status: Literal["pending", "installing", "collecting", "fail", "OK"]
98
98
  package: str
99
99
  venv_path: Path
100
- task_list: Optional[list[TaskRead]] = Field(default=[])
100
+ task_list: Optional[list[TaskReadV1]] = Field(default=[])
101
101
  log: Optional[str]
102
102
  info: Optional[str]
103
103
 
@@ -6,30 +6,30 @@ from typing import Optional
6
6
  from pydantic import BaseModel
7
7
  from pydantic import validator
8
8
 
9
- from ._validators import valint
10
- from ._validators import valstr
11
- from ._validators import valutc
12
- from .project import ProjectRead
13
- from .task import TaskExport
14
- from .task import TaskImport
15
- from .task import TaskRead
9
+ from .._validators import valint
10
+ from .._validators import valstr
11
+ from .._validators import valutc
12
+ from .project import ProjectReadV1
13
+ from .task import TaskExportV1
14
+ from .task import TaskImportV1
15
+ from .task import TaskReadV1
16
16
 
17
17
  __all__ = (
18
- "WorkflowCreate",
19
- "WorkflowRead",
20
- "WorkflowUpdate",
21
- "WorkflowImport",
22
- "WorkflowExport",
23
- "WorkflowTaskCreate",
24
- "WorkflowTaskImport",
25
- "WorkflowTaskExport",
26
- "WorkflowTaskRead",
27
- "WorkflowTaskUpdate",
28
- "WorkflowTaskStatusType",
18
+ "WorkflowCreateV1",
19
+ "WorkflowReadV1",
20
+ "WorkflowUpdateV1",
21
+ "WorkflowImportV1",
22
+ "WorkflowExportV1",
23
+ "WorkflowTaskCreateV1",
24
+ "WorkflowTaskImportV1",
25
+ "WorkflowTaskExportV1",
26
+ "WorkflowTaskReadV1",
27
+ "WorkflowTaskUpdateV1",
28
+ "WorkflowTaskStatusTypeV1",
29
29
  )
30
30
 
31
31
 
32
- class _WorkflowTaskBase(BaseModel):
32
+ class _WorkflowTaskBaseV1(BaseModel):
33
33
  """
34
34
  Base class for `WorkflowTask`.
35
35
  """
@@ -38,7 +38,7 @@ class _WorkflowTaskBase(BaseModel):
38
38
  args: Optional[dict[str, Any]] = None
39
39
 
40
40
 
41
- class WorkflowTaskCreate(_WorkflowTaskBase):
41
+ class WorkflowTaskCreateV1(_WorkflowTaskBaseV1):
42
42
  """
43
43
  Class for `WorkflowTask` creation.
44
44
 
@@ -51,7 +51,7 @@ class WorkflowTaskCreate(_WorkflowTaskBase):
51
51
  _order = validator("order", allow_reuse=True)(valint("order", min_val=0))
52
52
 
53
53
 
54
- class WorkflowTaskRead(_WorkflowTaskBase):
54
+ class WorkflowTaskReadV1(_WorkflowTaskBaseV1):
55
55
  """
56
56
  Class for `WorkflowTask` read from database.
57
57
 
@@ -67,10 +67,10 @@ class WorkflowTaskRead(_WorkflowTaskBase):
67
67
  order: Optional[int]
68
68
  workflow_id: int
69
69
  task_id: int
70
- task: TaskRead
70
+ task: TaskReadV1
71
71
 
72
72
 
73
- class WorkflowTaskImport(_WorkflowTaskBase):
73
+ class WorkflowTaskImportV1(_WorkflowTaskBaseV1):
74
74
  """
75
75
  Class for `WorkflowTask` import.
76
76
 
@@ -78,10 +78,10 @@ class WorkflowTaskImport(_WorkflowTaskBase):
78
78
  task:
79
79
  """
80
80
 
81
- task: TaskImport
81
+ task: TaskImportV1
82
82
 
83
83
 
84
- class WorkflowTaskExport(_WorkflowTaskBase):
84
+ class WorkflowTaskExportV1(_WorkflowTaskBaseV1):
85
85
  """
86
86
  Class for `WorkflowTask` export.
87
87
 
@@ -89,10 +89,10 @@ class WorkflowTaskExport(_WorkflowTaskBase):
89
89
  task:
90
90
  """
91
91
 
92
- task: TaskExport
92
+ task: TaskExportV1
93
93
 
94
94
 
95
- class WorkflowTaskUpdate(_WorkflowTaskBase):
95
+ class WorkflowTaskUpdateV1(_WorkflowTaskBaseV1):
96
96
  """
97
97
  Class for `WorkflowTask` update.
98
98
  """
@@ -107,7 +107,7 @@ class WorkflowTaskUpdate(_WorkflowTaskBase):
107
107
  return m
108
108
 
109
109
 
110
- class _WorkflowBase(BaseModel):
110
+ class _WorkflowBaseV1(BaseModel):
111
111
  """
112
112
  Base class for `Workflow`.
113
113
 
@@ -118,7 +118,7 @@ class _WorkflowBase(BaseModel):
118
118
  name: str
119
119
 
120
120
 
121
- class WorkflowRead(_WorkflowBase):
121
+ class WorkflowReadV1(_WorkflowBaseV1):
122
122
  """
123
123
  Task for `Workflow` read from database.
124
124
 
@@ -131,8 +131,8 @@ class WorkflowRead(_WorkflowBase):
131
131
 
132
132
  id: int
133
133
  project_id: int
134
- task_list: list[WorkflowTaskRead]
135
- project: ProjectRead
134
+ task_list: list[WorkflowTaskReadV1]
135
+ project: ProjectReadV1
136
136
  timestamp_created: datetime
137
137
 
138
138
  _timestamp_created = validator("timestamp_created", allow_reuse=True)(
@@ -140,7 +140,7 @@ class WorkflowRead(_WorkflowBase):
140
140
  )
141
141
 
142
142
 
143
- class WorkflowCreate(_WorkflowBase):
143
+ class WorkflowCreateV1(_WorkflowBaseV1):
144
144
  """
145
145
  Task for `Workflow` creation.
146
146
  """
@@ -149,7 +149,7 @@ class WorkflowCreate(_WorkflowBase):
149
149
  _name = validator("name", allow_reuse=True)(valstr("name"))
150
150
 
151
151
 
152
- class WorkflowUpdate(_WorkflowBase):
152
+ class WorkflowUpdateV1(_WorkflowBaseV1):
153
153
  """
154
154
  Task for `Workflow` update.
155
155
 
@@ -173,7 +173,7 @@ class WorkflowUpdate(_WorkflowBase):
173
173
  return value
174
174
 
175
175
 
176
- class WorkflowImport(_WorkflowBase):
176
+ class WorkflowImportV1(_WorkflowBaseV1):
177
177
  """
178
178
  Class for `Workflow` import.
179
179
 
@@ -181,13 +181,13 @@ class WorkflowImport(_WorkflowBase):
181
181
  task_list:
182
182
  """
183
183
 
184
- task_list: list[WorkflowTaskImport]
184
+ task_list: list[WorkflowTaskImportV1]
185
185
 
186
186
  # Validators
187
187
  _name = validator("name", allow_reuse=True)(valstr("name"))
188
188
 
189
189
 
190
- class WorkflowExport(_WorkflowBase):
190
+ class WorkflowExportV1(_WorkflowBaseV1):
191
191
  """
192
192
  Class for `Workflow` export.
193
193
 
@@ -195,10 +195,10 @@ class WorkflowExport(_WorkflowBase):
195
195
  task_list:
196
196
  """
197
197
 
198
- task_list: list[WorkflowTaskExport]
198
+ task_list: list[WorkflowTaskExportV1]
199
199
 
200
200
 
201
- class WorkflowTaskStatusType(str, Enum):
201
+ class WorkflowTaskStatusTypeV1(str, Enum):
202
202
  """
203
203
  Define the available values for the status of a `WorkflowTask`.
204
204
 
@@ -0,0 +1,34 @@
1
+ from .dataset import DatasetCreateV2 # noqa F401
2
+ from .dataset import DatasetReadV2 # noqa F401
3
+ from .dataset import DatasetUpdateV2 # noqa F401
4
+ from .dumps import DatasetDumpV2 # noqa F401
5
+ from .dumps import ProjectDumpV2 # noqa F401
6
+ from .dumps import TaskDumpV2 # noqa F401
7
+ from .dumps import WorkflowDumpV2 # noqa F401
8
+ from .dumps import WorkflowTaskDumpV2 # noqa F401
9
+ from .job import JobCreateV2 # noqa F401
10
+ from .job import JobReadV2 # noqa F401
11
+ from .job import JobStatusTypeV2 # noqa F401
12
+ from .job import JobUpdateV2 # noqa F401
13
+ from .manifest import ManifestV2 # noqa F401
14
+ from .project import ProjectCreateV2 # noqa F401
15
+ from .project import ProjectReadV2 # noqa F401
16
+ from .project import ProjectUpdateV2 # noqa F401
17
+ from .task import TaskCreateV2 # noqa F401
18
+ from .task import TaskExportV2 # noqa F401
19
+ from .task import TaskImportV2 # noqa F401
20
+ from .task import TaskReadV2 # noqa F401
21
+ from .task import TaskUpdateV2 # noqa F401
22
+ from .task_collection import TaskCollectPipV2 # noqa F401
23
+ from .task_collection import TaskCollectStatusV2 # noqa F401
24
+ from .workflow import WorkflowCreateV2 # noqa F401
25
+ from .workflow import WorkflowExportV2 # noqa F401
26
+ from .workflow import WorkflowImportV2 # noqa F401
27
+ from .workflow import WorkflowReadV2 # noqa F401
28
+ from .workflow import WorkflowUpdateV2 # noqa F401
29
+ from .workflowtask import WorkflowTaskCreateV2 # noqa F401
30
+ from .workflowtask import WorkflowTaskExportV2 # noqa F401
31
+ from .workflowtask import WorkflowTaskImportV2 # noqa F401
32
+ from .workflowtask import WorkflowTaskReadV2 # noqa F401
33
+ from .workflowtask import WorkflowTaskStatusTypeV2 # noqa F401
34
+ from .workflowtask import WorkflowTaskUpdateV2 # noqa F401
@@ -0,0 +1,89 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+
4
+ from pydantic import BaseModel
5
+ from pydantic import Extra
6
+ from pydantic import Field
7
+ from pydantic import validator
8
+
9
+ from .._validators import valstr
10
+ from .._validators import valutc
11
+ from ..v1.project import ProjectReadV1
12
+ from .dumps import WorkflowTaskDumpV2
13
+ from .workflowtask import WorkflowTaskStatusTypeV2
14
+ from fractal_server.images import Filters
15
+
16
+
17
+ class _DatasetHistoryItemV2(BaseModel):
18
+ """
19
+ Class for an item of `Dataset.history`.
20
+ """
21
+
22
+ workflowtask: WorkflowTaskDumpV2
23
+ status: WorkflowTaskStatusTypeV2
24
+ parallelization: Optional[dict]
25
+
26
+
27
+ class DatasetStatusReadV2(BaseModel):
28
+ """
29
+ Response type for the
30
+ `/project/{project_id}/dataset/{dataset_id}/status/` endpoint
31
+ """
32
+
33
+ status: Optional[
34
+ dict[
35
+ str,
36
+ WorkflowTaskStatusTypeV2,
37
+ ]
38
+ ] = None
39
+
40
+
41
+ # CRUD
42
+
43
+
44
+ class DatasetCreateV2(BaseModel, extra=Extra.forbid):
45
+
46
+ name: str
47
+
48
+ read_only: bool = False
49
+ zarr_dir: str
50
+
51
+ filters: Filters = Field(default_factory=Filters)
52
+
53
+ # Validators
54
+ _name = validator("name", allow_reuse=True)(valstr("name"))
55
+
56
+
57
+ class DatasetReadV2(BaseModel):
58
+
59
+ id: int
60
+ name: str
61
+
62
+ project_id: int
63
+ project: ProjectReadV1
64
+
65
+ history: list[_DatasetHistoryItemV2]
66
+ read_only: bool
67
+
68
+ timestamp_created: datetime
69
+
70
+ zarr_dir: str
71
+ filters: Filters = Field(default_factory=Filters)
72
+
73
+ # Validators
74
+ _timestamp_created = validator("timestamp_created", allow_reuse=True)(
75
+ valutc("timestamp_created")
76
+ )
77
+
78
+
79
+ class DatasetUpdateV2(BaseModel):
80
+ class Config:
81
+ extra = "forbid"
82
+
83
+ name: Optional[str]
84
+ read_only: Optional[bool]
85
+ zarr_dir: Optional[str]
86
+ filters: Optional[Filters]
87
+
88
+ # Validators
89
+ _name = validator("name", allow_reuse=True)(valstr("name"))
@@ -0,0 +1,87 @@
1
+ """
2
+
3
+ Dump models differ from their Read counterpart in that:
4
+ * They are directly JSON-able, without any additional encoder.
5
+ * They may only include a subset of the Read attributes.
6
+
7
+ These models are used in at least two situations:
8
+ 1. In the "*_dump" attributes of ApplyWorkflow models;
9
+ 2. In the `_DatasetHistoryItem.workflowtask` model, to trim its size.
10
+ """
11
+ from typing import Optional
12
+
13
+ from pydantic import BaseModel
14
+ from pydantic import Extra
15
+ from pydantic import root_validator
16
+
17
+ from fractal_server.app.schemas.v1.dumps import TaskDumpV1
18
+ from fractal_server.images import Filters
19
+
20
+
21
+ class ProjectDumpV2(BaseModel, extra=Extra.forbid):
22
+
23
+ id: int
24
+ name: str
25
+ read_only: bool
26
+ timestamp_created: str
27
+
28
+
29
+ class TaskDumpV2(BaseModel):
30
+ id: int
31
+ name: str
32
+ type: str
33
+
34
+ command_non_parallel: Optional[str]
35
+ command_parallel: Optional[str]
36
+ source: str
37
+ owner: Optional[str]
38
+ version: Optional[str]
39
+
40
+ input_types: dict[str, bool]
41
+ output_types: dict[str, bool]
42
+
43
+
44
+ class WorkflowTaskDumpV2(BaseModel):
45
+ id: int
46
+ workflow_id: int
47
+ order: Optional[int]
48
+
49
+ input_filters: Filters
50
+
51
+ task_id: Optional[int]
52
+ task: Optional[TaskDumpV2]
53
+ task_legacy_id: Optional[int]
54
+ task_legacy: Optional[TaskDumpV1]
55
+
56
+ # Validators
57
+ @root_validator
58
+ def task_v1_or_v2(cls, values):
59
+ v1 = values.get("task_legacy_id")
60
+ v2 = values.get("task_id")
61
+ if ((v1 is not None) and (v2 is not None)) or (
62
+ (v1 is None) and (v2 is None)
63
+ ):
64
+ message = "both" if (v1 and v2) else "none"
65
+ raise ValueError(
66
+ "One and only one must be provided between "
67
+ f"'task_legacy_id' and 'task_id' (you provided {message})"
68
+ )
69
+ return values
70
+
71
+
72
+ class WorkflowDumpV2(BaseModel):
73
+ id: int
74
+ name: str
75
+ project_id: int
76
+ timestamp_created: str
77
+
78
+
79
+ class DatasetDumpV2(BaseModel):
80
+ id: int
81
+ name: str
82
+ project_id: int
83
+ read_only: bool
84
+ timestamp_created: str
85
+
86
+ zarr_dir: str
87
+ filters: Filters
@@ -0,0 +1,114 @@
1
+ from datetime import datetime
2
+ from enum import Enum
3
+ from typing import Optional
4
+
5
+ from pydantic import BaseModel
6
+ from pydantic import Extra
7
+ from pydantic import validator
8
+ from pydantic.types import StrictStr
9
+
10
+ from .._validators import valstr
11
+ from .._validators import valutc
12
+ from .dumps import DatasetDumpV2
13
+ from .dumps import ProjectDumpV2
14
+ from .dumps import WorkflowDumpV2
15
+
16
+
17
+ class JobStatusTypeV2(str, Enum):
18
+ """
19
+ Define the available job statuses
20
+
21
+ Attributes:
22
+ SUBMITTED:
23
+ The job was created. This does not guarantee that it was also
24
+ submitted to an executor (e.g. other errors could have prevented
25
+ this), nor that it is actually running (e.g. SLURM jobs could be
26
+ still in the queue).
27
+ DONE:
28
+ The job successfully reached its end.
29
+ FAILED:
30
+ The workflow terminated with an error.
31
+ """
32
+
33
+ SUBMITTED = "submitted"
34
+ DONE = "done"
35
+ FAILED = "failed"
36
+
37
+
38
+ class JobCreateV2(BaseModel, extra=Extra.forbid):
39
+
40
+ first_task_index: Optional[int] = None
41
+ last_task_index: Optional[int] = None
42
+ slurm_account: Optional[StrictStr] = None
43
+ worker_init: Optional[str]
44
+
45
+ # Validators
46
+ _worker_init = validator("worker_init", allow_reuse=True)(
47
+ valstr("worker_init")
48
+ )
49
+
50
+ @validator("first_task_index", always=True)
51
+ def first_task_index_non_negative(cls, v, values):
52
+ """
53
+ Check that `first_task_index` is non-negative.
54
+ """
55
+ if v is not None and v < 0:
56
+ raise ValueError(
57
+ f"first_task_index cannot be negative (given: {v})"
58
+ )
59
+ return v
60
+
61
+ @validator("last_task_index", always=True)
62
+ def first_last_task_indices(cls, v, values):
63
+ """
64
+ Check that `last_task_index` is non-negative, and that it is not
65
+ smaller than `first_task_index`.
66
+ """
67
+ if v is not None and v < 0:
68
+ raise ValueError(
69
+ f"last_task_index cannot be negative (given: {v})"
70
+ )
71
+
72
+ first_task_index = values.get("first_task_index")
73
+ last_task_index = v
74
+ if first_task_index is not None and last_task_index is not None:
75
+ if first_task_index > last_task_index:
76
+ raise ValueError(
77
+ f"{first_task_index=} cannot be larger than "
78
+ f"{last_task_index=}"
79
+ )
80
+ return v
81
+
82
+
83
+ class JobReadV2(BaseModel):
84
+
85
+ id: int
86
+ project_id: Optional[int]
87
+ project_dump: ProjectDumpV2
88
+ user_email: str
89
+ slurm_account: Optional[str]
90
+ workflow_id: Optional[int]
91
+ workflow_dump: WorkflowDumpV2
92
+ dataset_id: Optional[int]
93
+ dataset_dump: DatasetDumpV2
94
+ start_timestamp: datetime
95
+ end_timestamp: Optional[datetime]
96
+ status: str
97
+ log: Optional[str]
98
+ working_dir: Optional[str]
99
+ working_dir_user: Optional[str]
100
+ first_task_index: Optional[int]
101
+ last_task_index: Optional[int]
102
+ worker_init: Optional[str]
103
+
104
+ _start_timestamp = validator("start_timestamp", allow_reuse=True)(
105
+ valutc("start_timestamp")
106
+ )
107
+ _end_timestamp = validator("end_timestamp", allow_reuse=True)(
108
+ valutc("end_timestamp")
109
+ )
110
+
111
+
112
+ class JobUpdateV2(BaseModel):
113
+
114
+ status: JobStatusTypeV2