fractal-server 2.17.1a1__py3-none-any.whl → 2.18.0__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 (225) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +21 -19
  3. fractal_server/app/db/__init__.py +3 -3
  4. fractal_server/app/models/__init__.py +1 -0
  5. fractal_server/app/models/linkuserproject.py +43 -1
  6. fractal_server/app/models/security.py +28 -8
  7. fractal_server/app/models/v2/__init__.py +3 -1
  8. fractal_server/app/models/v2/accounting.py +9 -1
  9. fractal_server/app/models/v2/dataset.py +5 -1
  10. fractal_server/app/models/v2/history.py +15 -1
  11. fractal_server/app/models/v2/job.py +17 -2
  12. fractal_server/app/models/v2/profile.py +29 -0
  13. fractal_server/app/models/v2/project.py +4 -10
  14. fractal_server/app/models/v2/resource.py +17 -0
  15. fractal_server/app/models/v2/task_group.py +4 -3
  16. fractal_server/app/models/v2/workflow.py +2 -1
  17. fractal_server/app/routes/admin/v2/__init__.py +12 -13
  18. fractal_server/app/routes/admin/v2/accounting.py +3 -3
  19. fractal_server/app/routes/admin/v2/job.py +35 -24
  20. fractal_server/app/routes/admin/v2/profile.py +3 -2
  21. fractal_server/app/routes/admin/v2/resource.py +5 -5
  22. fractal_server/app/routes/admin/v2/sharing.py +103 -0
  23. fractal_server/app/routes/admin/v2/task.py +37 -26
  24. fractal_server/app/routes/admin/v2/task_group.py +94 -17
  25. fractal_server/app/routes/admin/v2/task_group_lifecycle.py +21 -22
  26. fractal_server/app/routes/api/__init__.py +1 -9
  27. fractal_server/app/routes/api/v2/__init__.py +49 -50
  28. fractal_server/app/routes/api/v2/_aux_functions.py +132 -124
  29. fractal_server/app/routes/api/v2/_aux_functions_history.py +51 -23
  30. fractal_server/app/routes/api/v2/_aux_functions_sharing.py +97 -0
  31. fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +6 -8
  32. fractal_server/app/routes/api/v2/_aux_functions_tasks.py +7 -9
  33. fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +1 -2
  34. fractal_server/app/routes/api/v2/dataset.py +95 -102
  35. fractal_server/app/routes/api/v2/history.py +59 -33
  36. fractal_server/app/routes/api/v2/images.py +24 -9
  37. fractal_server/app/routes/api/v2/job.py +52 -33
  38. fractal_server/app/routes/api/v2/pre_submission_checks.py +16 -8
  39. fractal_server/app/routes/api/v2/project.py +65 -37
  40. fractal_server/app/routes/api/v2/sharing.py +311 -0
  41. fractal_server/app/routes/api/v2/status_legacy.py +31 -41
  42. fractal_server/app/routes/api/v2/submit.py +82 -78
  43. fractal_server/app/routes/api/v2/task.py +19 -20
  44. fractal_server/app/routes/api/v2/task_collection.py +41 -43
  45. fractal_server/app/routes/api/v2/task_collection_custom.py +19 -20
  46. fractal_server/app/routes/api/v2/task_collection_pixi.py +10 -11
  47. fractal_server/app/routes/api/v2/task_group.py +25 -24
  48. fractal_server/app/routes/api/v2/task_group_lifecycle.py +32 -32
  49. fractal_server/app/routes/api/v2/task_version_update.py +23 -19
  50. fractal_server/app/routes/api/v2/workflow.py +50 -55
  51. fractal_server/app/routes/api/v2/workflow_import.py +37 -37
  52. fractal_server/app/routes/api/v2/workflowtask.py +32 -26
  53. fractal_server/app/routes/auth/__init__.py +1 -3
  54. fractal_server/app/routes/auth/_aux_auth.py +101 -2
  55. fractal_server/app/routes/auth/current_user.py +2 -66
  56. fractal_server/app/routes/auth/group.py +8 -35
  57. fractal_server/app/routes/auth/login.py +1 -0
  58. fractal_server/app/routes/auth/oauth.py +4 -3
  59. fractal_server/app/routes/auth/register.py +4 -2
  60. fractal_server/app/routes/auth/router.py +2 -0
  61. fractal_server/app/routes/auth/users.py +19 -10
  62. fractal_server/app/routes/auth/viewer_paths.py +43 -0
  63. fractal_server/app/routes/aux/_job.py +1 -1
  64. fractal_server/app/routes/aux/_runner.py +2 -2
  65. fractal_server/app/routes/pagination.py +1 -1
  66. fractal_server/app/schemas/user.py +29 -12
  67. fractal_server/app/schemas/user_group.py +0 -15
  68. fractal_server/app/schemas/v2/__init__.py +55 -48
  69. fractal_server/app/schemas/v2/accounting.py +11 -0
  70. fractal_server/app/schemas/v2/dataset.py +57 -11
  71. fractal_server/app/schemas/v2/dumps.py +10 -9
  72. fractal_server/app/schemas/v2/job.py +11 -11
  73. fractal_server/app/schemas/v2/manifest.py +4 -3
  74. fractal_server/app/schemas/v2/profile.py +53 -2
  75. fractal_server/app/schemas/v2/project.py +3 -3
  76. fractal_server/app/schemas/v2/resource.py +121 -16
  77. fractal_server/app/schemas/v2/sharing.py +99 -0
  78. fractal_server/app/schemas/v2/status_legacy.py +3 -3
  79. fractal_server/app/schemas/v2/task.py +6 -7
  80. fractal_server/app/schemas/v2/task_collection.py +5 -5
  81. fractal_server/app/schemas/v2/task_group.py +16 -16
  82. fractal_server/app/schemas/v2/workflow.py +16 -16
  83. fractal_server/app/schemas/v2/workflowtask.py +16 -15
  84. fractal_server/app/security/__init__.py +5 -8
  85. fractal_server/app/security/signup_email.py +4 -5
  86. fractal_server/app/shutdown.py +6 -6
  87. fractal_server/config/__init__.py +0 -6
  88. fractal_server/config/_data.py +0 -68
  89. fractal_server/config/_database.py +19 -20
  90. fractal_server/config/_email.py +30 -38
  91. fractal_server/config/_main.py +38 -52
  92. fractal_server/config/_oauth.py +17 -21
  93. fractal_server/data_migrations/2_18_0.py +30 -0
  94. fractal_server/exceptions.py +4 -0
  95. fractal_server/images/models.py +4 -5
  96. fractal_server/images/status_tools.py +4 -2
  97. fractal_server/logger.py +1 -1
  98. fractal_server/main.py +75 -13
  99. fractal_server/migrations/versions/034a469ec2eb_task_groups.py +4 -8
  100. fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +1 -1
  101. fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +1 -0
  102. fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +1 -1
  103. fractal_server/migrations/versions/1a83a5260664_rename.py +1 -1
  104. fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +1 -0
  105. fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +1 -1
  106. fractal_server/migrations/versions/40d6d6511b20_add_index_to_history_models.py +47 -0
  107. fractal_server/migrations/versions/45fbb391d7af_make_resource_id_fk_non_nullable.py +1 -1
  108. fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +1 -0
  109. fractal_server/migrations/versions/49d0856e9569_drop_table.py +2 -3
  110. fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +1 -1
  111. fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +1 -1
  112. fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +2 -1
  113. fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +7 -19
  114. fractal_server/migrations/versions/5bf02391cfef_v2.py +4 -10
  115. fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +1 -0
  116. fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +1 -1
  117. fractal_server/migrations/versions/7673fe18c05d_remove_project_dir_server_default.py +1 -1
  118. fractal_server/migrations/versions/7910eed4cf97_user_project_dirs_and_usergroup_viewer_.py +60 -0
  119. fractal_server/migrations/versions/791ce783d3d8_add_indices.py +1 -1
  120. fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +1 -0
  121. fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +1 -0
  122. fractal_server/migrations/versions/88270f589c9b_add_prevent_new_submissions.py +39 -0
  123. fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +2 -4
  124. fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +1 -1
  125. fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +1 -0
  126. fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +1 -1
  127. fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +1 -1
  128. fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +1 -1
  129. fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +2 -4
  130. fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +1 -1
  131. fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +1 -1
  132. fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +1 -1
  133. fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +1 -1
  134. fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +1 -0
  135. fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +1 -0
  136. fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +1 -1
  137. fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +1 -0
  138. fractal_server/migrations/versions/bc0e8b3327a7_project_sharing.py +72 -0
  139. fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +1 -1
  140. fractal_server/migrations/versions/caba9fb1ea5e_drop_useroauth_user_settings_id.py +1 -1
  141. fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +4 -9
  142. fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +1 -0
  143. fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +1 -1
  144. fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +1 -0
  145. fractal_server/migrations/versions/e0e717ae2f26_delete_linkuserproject_ondelete_project.py +50 -0
  146. fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +1 -0
  147. fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +1 -1
  148. fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +1 -0
  149. fractal_server/migrations/versions/f0702066b007_one_submitted_job_per_dataset.py +40 -0
  150. fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +1 -1
  151. fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +1 -0
  152. fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +4 -9
  153. fractal_server/runner/config/_local.py +8 -5
  154. fractal_server/runner/config/_slurm.py +39 -33
  155. fractal_server/runner/config/slurm_mem_to_MB.py +0 -1
  156. fractal_server/runner/executors/base_runner.py +29 -4
  157. fractal_server/runner/executors/local/get_local_config.py +1 -0
  158. fractal_server/runner/executors/local/runner.py +14 -13
  159. fractal_server/runner/executors/slurm_common/_batching.py +9 -20
  160. fractal_server/runner/executors/slurm_common/base_slurm_runner.py +53 -27
  161. fractal_server/runner/executors/slurm_common/get_slurm_config.py +14 -7
  162. fractal_server/runner/executors/slurm_common/remote.py +3 -1
  163. fractal_server/runner/executors/slurm_common/slurm_config.py +2 -0
  164. fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +1 -3
  165. fractal_server/runner/executors/slurm_ssh/runner.py +16 -11
  166. fractal_server/runner/executors/slurm_ssh/tar_commands.py +1 -0
  167. fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -0
  168. fractal_server/runner/executors/slurm_sudo/runner.py +16 -11
  169. fractal_server/runner/task_files.py +9 -3
  170. fractal_server/runner/v2/_local.py +12 -6
  171. fractal_server/runner/v2/_slurm_ssh.py +14 -7
  172. fractal_server/runner/v2/_slurm_sudo.py +14 -7
  173. fractal_server/runner/v2/db_tools.py +0 -1
  174. fractal_server/runner/v2/deduplicate_list.py +2 -1
  175. fractal_server/runner/v2/runner.py +44 -28
  176. fractal_server/runner/v2/runner_functions.py +22 -28
  177. fractal_server/runner/v2/submit_workflow.py +29 -15
  178. fractal_server/ssh/_fabric.py +6 -13
  179. fractal_server/string_tools.py +0 -1
  180. fractal_server/syringe.py +1 -1
  181. fractal_server/tasks/config/_pixi.py +1 -1
  182. fractal_server/tasks/config/_python.py +16 -9
  183. fractal_server/tasks/utils.py +0 -1
  184. fractal_server/tasks/v2/local/_utils.py +3 -3
  185. fractal_server/tasks/v2/local/collect.py +15 -18
  186. fractal_server/tasks/v2/local/collect_pixi.py +14 -16
  187. fractal_server/tasks/v2/local/deactivate.py +14 -15
  188. fractal_server/tasks/v2/local/deactivate_pixi.py +7 -7
  189. fractal_server/tasks/v2/local/delete.py +6 -8
  190. fractal_server/tasks/v2/local/reactivate.py +12 -12
  191. fractal_server/tasks/v2/local/reactivate_pixi.py +12 -12
  192. fractal_server/tasks/v2/ssh/_utils.py +3 -3
  193. fractal_server/tasks/v2/ssh/collect.py +19 -24
  194. fractal_server/tasks/v2/ssh/collect_pixi.py +22 -24
  195. fractal_server/tasks/v2/ssh/deactivate.py +17 -15
  196. fractal_server/tasks/v2/ssh/deactivate_pixi.py +8 -7
  197. fractal_server/tasks/v2/ssh/delete.py +12 -10
  198. fractal_server/tasks/v2/ssh/reactivate.py +16 -16
  199. fractal_server/tasks/v2/ssh/reactivate_pixi.py +13 -14
  200. fractal_server/tasks/v2/templates/1_create_venv.sh +2 -0
  201. fractal_server/tasks/v2/templates/2_pip_install.sh +2 -0
  202. fractal_server/tasks/v2/templates/3_pip_freeze.sh +2 -0
  203. fractal_server/tasks/v2/templates/4_pip_show.sh +2 -0
  204. fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +3 -1
  205. fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +2 -0
  206. fractal_server/tasks/v2/templates/pixi_1_extract.sh +2 -0
  207. fractal_server/tasks/v2/templates/pixi_2_install.sh +2 -0
  208. fractal_server/tasks/v2/templates/pixi_3_post_install.sh +2 -0
  209. fractal_server/tasks/v2/utils_background.py +10 -10
  210. fractal_server/tasks/v2/utils_database.py +5 -5
  211. fractal_server/tasks/v2/utils_package_names.py +1 -2
  212. fractal_server/tasks/v2/utils_pixi.py +1 -3
  213. fractal_server/types/__init__.py +98 -1
  214. fractal_server/types/validators/__init__.py +3 -0
  215. fractal_server/types/validators/_common_validators.py +33 -3
  216. fractal_server/types/validators/_workflow_task_arguments_validators.py +1 -2
  217. fractal_server/utils.py +1 -0
  218. fractal_server/zip_tools.py +34 -0
  219. {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/METADATA +3 -2
  220. fractal_server-2.18.0.dist-info/RECORD +275 -0
  221. fractal_server/app/routes/admin/v2/project.py +0 -41
  222. fractal_server-2.17.1a1.dist-info/RECORD +0 -264
  223. {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/WHEEL +0 -0
  224. {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/entry_points.txt +0 -0
  225. {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/licenses/LICENSE +0 -0
@@ -7,8 +7,8 @@ from typing import Self
7
7
  from pydantic import AfterValidator
8
8
  from pydantic import BaseModel
9
9
  from pydantic import Discriminator
10
- from pydantic import model_validator
11
10
  from pydantic import Tag
11
+ from pydantic import model_validator
12
12
  from pydantic import validate_call
13
13
  from pydantic.types import AwareDatetime
14
14
 
@@ -21,23 +21,46 @@ from fractal_server.types import NonEmptyStr
21
21
 
22
22
 
23
23
  class ResourceType(StrEnum):
24
+ """
25
+ Enum for the possible resource types.
26
+ """
27
+
24
28
  SLURM_SUDO = "slurm_sudo"
29
+ """
30
+ Enum entry for resource type `slurm_sudo`.
31
+ """
32
+
25
33
  SLURM_SSH = "slurm_ssh"
34
+ """
35
+ Enum entry for resource type `slurm_ssh`.
36
+ """
37
+
26
38
  LOCAL = "local"
39
+ """
40
+ Enum entry for resource type `local`.
41
+ """
27
42
 
28
43
 
29
44
  def cast_serialize_pixi_settings(
30
- v: dict[NonEmptyStr, Any],
45
+ value: dict[NonEmptyStr, Any],
31
46
  ) -> dict[NonEmptyStr, Any]:
32
47
  """
33
- Validate current value, and enrich it with default values.
48
+ Cast/serialize round trip for `tasks_pixi_config` through the
49
+ `TasksPixiSettings` schema.
50
+
51
+ Arguments:
52
+ value: Current `tasks_pixi_config` value.
34
53
  """
35
- if v != {}:
36
- v = TasksPixiSettings(**v).model_dump()
37
- return v
54
+ if value != {}:
55
+ value = TasksPixiSettings(**value).model_dump()
56
+ return value
38
57
 
39
58
 
40
- class _ValidResourceBase(BaseModel):
59
+ class ValidResourceBase(BaseModel):
60
+ """
61
+ Base resource schema.
62
+ """
63
+
41
64
  type: ResourceType
42
65
  name: NonEmptyStr
43
66
 
@@ -54,6 +77,8 @@ class _ValidResourceBase(BaseModel):
54
77
  jobs_runner_config: dict[NonEmptyStr, Any]
55
78
  jobs_poll_interval: int = 5
56
79
 
80
+ prevent_new_submissions: bool = False
81
+
57
82
  @model_validator(mode="after")
58
83
  def _pixi_slurm_config(self) -> Self:
59
84
  if (
@@ -61,27 +86,98 @@ class _ValidResourceBase(BaseModel):
61
86
  and self.type == ResourceType.SLURM_SSH
62
87
  and self.tasks_pixi_config["SLURM_CONFIG"] is None
63
88
  ):
64
- raise ValueError(
65
- "`tasks_pixi_config` must include `SLURM_CONFIG`."
66
- )
89
+ raise ValueError("`tasks_pixi_config` must include `SLURM_CONFIG`.")
67
90
  return self
68
91
 
69
92
 
70
- class ValidResourceLocal(_ValidResourceBase):
93
+ class ValidResourceLocal(ValidResourceBase):
94
+ """
95
+ Valid local resource.
96
+
97
+ Attributes:
98
+ name: Resource name.
99
+ type: Resource type.
100
+ prevent_new_submissions:
101
+ When set to true: Prevent new job submissions and stop execution of
102
+ ongoing jobs as soon as the current task is complete.
103
+ tasks_python_config:
104
+ Configuration of Python interpreters used for task collection.
105
+ tasks_pixi_config:
106
+ Configuration of `pixi` interpreters used for task collection.
107
+ tasks_local_dir:
108
+ Local base folder for task environments.
109
+ jobs_local_dir:
110
+ Local base folder for job folders.
111
+ jobs_runner_config:
112
+ Runner configuration.
113
+ """
114
+
71
115
  type: Literal[ResourceType.LOCAL]
72
116
  jobs_runner_config: JobRunnerConfigLocal
73
117
  jobs_slurm_python_worker: None = None
74
118
  host: None = None
75
119
 
76
120
 
77
- class ValidResourceSlurmSudo(_ValidResourceBase):
121
+ class ValidResourceSlurmSudo(ValidResourceBase):
122
+ """
123
+ Valid SLURM-sudo resource.
124
+
125
+ Attributes:
126
+ name: Resource name.
127
+ type: Resource type.
128
+ prevent_new_submissions:
129
+ When set to true: Prevent new job submissions and stop execution of
130
+ ongoing jobs as soon as the current task is complete.
131
+ tasks_python_config:
132
+ Configuration of Python interpreters used for task collection.
133
+ tasks_pixi_config:
134
+ Configuration of `pixi` interpreters used for task collection.
135
+ tasks_local_dir:
136
+ Local base folder for task environments.
137
+ jobs_local_dir:
138
+ Local base folder for job folders.
139
+ jobs_runner_config:
140
+ Runner configuration.
141
+ jobs_poll_interval:
142
+ `squeue` polling interval.
143
+ jobs_slurm_python_worker:
144
+ Python worker to be used in SLURM jobs.
145
+ """
146
+
78
147
  type: Literal[ResourceType.SLURM_SUDO]
79
148
  jobs_slurm_python_worker: AbsolutePathStr
80
149
  jobs_runner_config: JobRunnerConfigSLURM
81
150
  host: None = None
82
151
 
83
152
 
84
- class ValidResourceSlurmSSH(_ValidResourceBase):
153
+ class ValidResourceSlurmSSH(ValidResourceBase):
154
+ """
155
+ Valid SLURM-SSH resource.
156
+
157
+ Attributes:
158
+ name: Resource name
159
+ type: Resource type.
160
+ prevent_new_submissions:
161
+ When set to true: Prevent new job submissions and stop execution of
162
+ ongoing jobs as soon as the current task is complete.
163
+ tasks_python_config:
164
+ Configuration of Python interpreters used for task collection.
165
+ tasks_pixi_config:
166
+ Configuration of `pixi` interpreters used for task collection.
167
+ tasks_local_dir:
168
+ Local base folder for task environments.
169
+ jobs_local_dir:
170
+ Local base folder for job folders.
171
+ jobs_runner_config:
172
+ Runner configuration.
173
+ jobs_poll_interval:
174
+ `squeue` polling interval.
175
+ jobs_slurm_python_worker:
176
+ Python worker to be used in SLURM jobs.
177
+ host:
178
+ Hostname or IP address of remote SLURM cluster.
179
+ """
180
+
85
181
  type: Literal[ResourceType.SLURM_SSH]
86
182
  host: NonEmptyStr
87
183
  jobs_slurm_python_worker: AbsolutePathStr
@@ -101,14 +197,20 @@ ResourceCreate = Annotated[
101
197
  | Annotated[ValidResourceSlurmSSH, Tag(ResourceType.SLURM_SSH)],
102
198
  Discriminator(get_discriminator_value),
103
199
  ]
200
+ """
201
+ Schema for resources in API request bodies.
202
+ """
104
203
 
105
204
 
106
205
  class ResourceRead(BaseModel):
107
- id: int
108
-
109
- type: str
206
+ """
207
+ Schema for resources in API response bodies.
208
+ """
110
209
 
210
+ id: int
111
211
  name: str
212
+ type: str
213
+ prevent_new_submissions: bool
112
214
  timestamp_created: AwareDatetime
113
215
 
114
216
  host: str | None
@@ -131,6 +233,9 @@ def cast_serialize_resource(_data: ResourceCreate) -> dict[str, Any]:
131
233
  We use `@validate_call` because `ResourceCreate` is a `Union` type and it
132
234
  cannot be instantiated directly.
133
235
 
236
+ Args:
237
+ _data:
238
+
134
239
  Return:
135
240
  Serialized version of a valid resource object.
136
241
  """
@@ -0,0 +1,99 @@
1
+ from enum import StrEnum
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class ProjectPermissions(StrEnum):
7
+ """
8
+ Available permissions for accessing Project
9
+ Attributes:
10
+ READ:
11
+ WRITE:
12
+ EXECUTE:
13
+ """
14
+
15
+ READ = "r"
16
+ WRITE = "rw"
17
+ EXECUTE = "rwx"
18
+
19
+
20
+ class ProjectGuestCreate(BaseModel):
21
+ """
22
+ Request body for project-sharing invitation.
23
+
24
+ Attributes:
25
+ permissions:
26
+ """
27
+
28
+ permissions: ProjectPermissions
29
+
30
+
31
+ class ProjectGuestRead(BaseModel):
32
+ """
33
+ Information about a guest.
34
+
35
+ Attributes:
36
+ email: Guest email.
37
+ is_verified: Project/guest verification status.
38
+ permissions: Guest permissions for project.
39
+ """
40
+
41
+ email: str
42
+ is_verified: bool
43
+ permissions: str
44
+
45
+
46
+ class ProjectGuestUpdate(BaseModel):
47
+ """
48
+ Request body for updating permissions of an existing guest.
49
+
50
+ Attributes:
51
+ permissions: New permissions for guest.
52
+ """
53
+
54
+ permissions: ProjectPermissions
55
+
56
+
57
+ class ProjectAccessRead(BaseModel):
58
+ """
59
+ Project-access information for current user.
60
+
61
+ Attributes:
62
+ is_owner: Whether current user is owner.
63
+ permissions: Current user permissions.
64
+ owner_email: Email of project owner
65
+ """
66
+
67
+ is_owner: bool
68
+ permissions: str
69
+ owner_email: str
70
+
71
+
72
+ class ProjectInvitationRead(BaseModel):
73
+ """
74
+ Info about a pending invitation.
75
+
76
+ Attributes:
77
+ project_id:
78
+ project_name:
79
+ owner_email:
80
+ guest_permissions:
81
+ """
82
+
83
+ project_id: int
84
+ project_name: str
85
+ owner_email: str
86
+ guest_permissions: str
87
+
88
+
89
+ class LinkUserProjectRead(BaseModel):
90
+ # User info
91
+ user_id: int
92
+ user_email: str
93
+ # Project info
94
+ project_id: int
95
+ project_name: str
96
+ # Permissions
97
+ is_verified: bool
98
+ is_owner: bool
99
+ permissions: str
@@ -4,7 +4,7 @@ from pydantic import BaseModel
4
4
  from pydantic import Field
5
5
 
6
6
 
7
- class WorkflowTaskStatusTypeV2(StrEnum):
7
+ class WorkflowTaskStatusType(StrEnum):
8
8
  """
9
9
  Define the available values for the status of a `WorkflowTask`.
10
10
 
@@ -23,7 +23,7 @@ class WorkflowTaskStatusTypeV2(StrEnum):
23
23
  FAILED = "failed"
24
24
 
25
25
 
26
- class LegacyStatusReadV2(BaseModel):
26
+ class LegacyStatusRead(BaseModel):
27
27
  """
28
28
  Response type for the
29
29
  `/project/{project_id}/status/` endpoint
@@ -31,5 +31,5 @@ class LegacyStatusReadV2(BaseModel):
31
31
 
32
32
  status: dict[
33
33
  str,
34
- WorkflowTaskStatusTypeV2,
34
+ WorkflowTaskStatusType,
35
35
  ] = Field(default_factory=dict)
@@ -14,7 +14,6 @@ from fractal_server.types import ListUniqueNonEmptyString
14
14
  from fractal_server.types import NonEmptyStr
15
15
  from fractal_server.types import TypeFilters
16
16
 
17
-
18
17
  logger = set_logger(__name__)
19
18
 
20
19
 
@@ -30,7 +29,7 @@ class TaskType(StrEnum):
30
29
  PARALLEL = "parallel"
31
30
 
32
31
 
33
- class TaskCreateV2(BaseModel):
32
+ class TaskCreate(BaseModel):
34
33
  model_config = ConfigDict(extra="forbid")
35
34
 
36
35
  name: NonEmptyStr
@@ -91,7 +90,7 @@ class TaskCreateV2(BaseModel):
91
90
  return self
92
91
 
93
92
 
94
- class TaskReadV2(BaseModel):
93
+ class TaskRead(BaseModel):
95
94
  id: int
96
95
  name: str
97
96
  type: TaskType
@@ -118,7 +117,7 @@ class TaskReadV2(BaseModel):
118
117
  tags: list[str]
119
118
 
120
119
 
121
- class TaskUpdateV2(BaseModel):
120
+ class TaskUpdate(BaseModel):
122
121
  model_config = ConfigDict(extra="forbid")
123
122
 
124
123
  command_parallel: NonEmptyStr = None
@@ -132,7 +131,7 @@ class TaskUpdateV2(BaseModel):
132
131
  tags: ListUniqueNonEmptyString | None = None
133
132
 
134
133
 
135
- class TaskImportV2(BaseModel):
134
+ class TaskImport(BaseModel):
136
135
  model_config = ConfigDict(extra="forbid")
137
136
 
138
137
  pkg_name: NonEmptyStr
@@ -140,11 +139,11 @@ class TaskImportV2(BaseModel):
140
139
  name: NonEmptyStr
141
140
 
142
141
 
143
- class TaskImportV2Legacy(BaseModel):
142
+ class TaskImportLegacy(BaseModel):
144
143
  source: NonEmptyStr
145
144
 
146
145
 
147
- class TaskExportV2(BaseModel):
146
+ class TaskExport(BaseModel):
148
147
  pkg_name: NonEmptyStr
149
148
  version: NonEmptyStr | None = None
150
149
  name: NonEmptyStr
@@ -21,9 +21,9 @@ class FractalUploadedFile(BaseModel):
21
21
  contents: bytes
22
22
 
23
23
 
24
- class TaskCollectPipV2(BaseModel):
24
+ class TaskCollectPip(BaseModel):
25
25
  """
26
- TaskCollectPipV2 class
26
+ TaskCollectPip class
27
27
 
28
28
  This class only encodes the attributes required to trigger a
29
29
  task-collection operation. Other attributes (that are assigned *during*
@@ -86,12 +86,12 @@ class TaskCollectPipV2(BaseModel):
86
86
  def validate_pinned_package_versions(cls, value):
87
87
  if value is not None:
88
88
  for pkg, version in value.items():
89
- validate_cmd(pkg)
89
+ validate_cmd(pkg, allow_char="[]")
90
90
  validate_cmd(version)
91
91
  return value
92
92
 
93
93
 
94
- class TaskCollectCustomV2(BaseModel):
94
+ class TaskCollectCustom(BaseModel):
95
95
  """
96
96
  Attributes:
97
97
  manifest: Manifest of a Fractal task package (this is typically the
@@ -99,7 +99,7 @@ class TaskCollectCustomV2(BaseModel):
99
99
  python_interpreter: Absolute path to the Python interpreter to be used
100
100
  for running tasks.
101
101
  name: A name identifying this package, that will fill the
102
- `TaskGroupV2.pkg_name` column.
102
+ `TaskGroup.pkg_name` column.
103
103
  package_root: The folder where the package is installed.
104
104
  If not provided, it will be extracted via `pip show`
105
105
  (requires `package_name` to be set).
@@ -7,40 +7,40 @@ from pydantic import Field
7
7
  from pydantic import field_serializer
8
8
  from pydantic.types import AwareDatetime
9
9
 
10
- from fractal_server.app.schemas.v2.task import TaskReadV2
10
+ from fractal_server.app.schemas.v2.task import TaskRead
11
11
  from fractal_server.types import AbsolutePathStr
12
12
  from fractal_server.types import DictStrStr
13
13
  from fractal_server.types import NonEmptyStr
14
14
 
15
15
 
16
- class TaskGroupV2OriginEnum(StrEnum):
16
+ class TaskGroupOriginEnum(StrEnum):
17
17
  PYPI = "pypi"
18
18
  WHEELFILE = "wheel-file"
19
19
  PIXI = "pixi"
20
20
  OTHER = "other"
21
21
 
22
22
 
23
- class TaskGroupActivityStatusV2(StrEnum):
23
+ class TaskGroupActivityStatus(StrEnum):
24
24
  PENDING = "pending"
25
25
  ONGOING = "ongoing"
26
26
  FAILED = "failed"
27
27
  OK = "OK"
28
28
 
29
29
 
30
- class TaskGroupActivityActionV2(StrEnum):
30
+ class TaskGroupActivityAction(StrEnum):
31
31
  COLLECT = "collect"
32
32
  DEACTIVATE = "deactivate"
33
33
  REACTIVATE = "reactivate"
34
34
  DELETE = "delete"
35
35
 
36
36
 
37
- class TaskGroupCreateV2(BaseModel):
37
+ class TaskGroupCreate(BaseModel):
38
38
  model_config = ConfigDict(extra="forbid")
39
39
  user_id: int
40
40
  resource_id: int
41
41
  user_group_id: int | None = None
42
42
  active: bool = True
43
- origin: TaskGroupV2OriginEnum
43
+ origin: TaskGroupOriginEnum
44
44
  pkg_name: str
45
45
  version: str | None = None
46
46
  python_version: NonEmptyStr = None
@@ -54,9 +54,9 @@ class TaskGroupCreateV2(BaseModel):
54
54
  pinned_package_versions_post: DictStrStr = Field(default_factory=dict)
55
55
 
56
56
 
57
- class TaskGroupCreateV2Strict(TaskGroupCreateV2):
57
+ class TaskGroupCreateStrict(TaskGroupCreate):
58
58
  """
59
- A strict version of TaskGroupCreateV2, to be used for task collection.
59
+ A strict version of TaskGroupCreate, to be used for task collection.
60
60
  """
61
61
 
62
62
  path: AbsolutePathStr
@@ -65,14 +65,14 @@ class TaskGroupCreateV2Strict(TaskGroupCreateV2):
65
65
  python_version: NonEmptyStr
66
66
 
67
67
 
68
- class TaskGroupReadV2(BaseModel):
68
+ class TaskGroupRead(BaseModel):
69
69
  id: int
70
- task_list: list[TaskReadV2]
70
+ task_list: list[TaskRead]
71
71
 
72
72
  user_id: int
73
73
  user_group_id: int | None = None
74
74
 
75
- origin: TaskGroupV2OriginEnum
75
+ origin: TaskGroupOriginEnum
76
76
  pkg_name: str
77
77
  version: str | None = None
78
78
  python_version: str | None = None
@@ -96,16 +96,16 @@ class TaskGroupReadV2(BaseModel):
96
96
  return v.isoformat()
97
97
 
98
98
 
99
- class TaskGroupReadSuperuser(TaskGroupReadV2):
99
+ class TaskGroupReadSuperuser(TaskGroupRead):
100
100
  resource_id: int
101
101
 
102
102
 
103
- class TaskGroupUpdateV2(BaseModel):
103
+ class TaskGroupUpdate(BaseModel):
104
104
  model_config = ConfigDict(extra="forbid")
105
105
  user_group_id: int | None = None
106
106
 
107
107
 
108
- class TaskGroupActivityV2Read(BaseModel):
108
+ class TaskGroupActivityRead(BaseModel):
109
109
  id: int
110
110
  user_id: int
111
111
  taskgroupv2_id: int | None = None
@@ -113,8 +113,8 @@ class TaskGroupActivityV2Read(BaseModel):
113
113
  timestamp_ended: AwareDatetime | None = None
114
114
  pkg_name: str
115
115
  version: str
116
- status: TaskGroupActivityStatusV2
117
- action: TaskGroupActivityActionV2
116
+ status: TaskGroupActivityStatus
117
+ action: TaskGroupActivityAction
118
118
  log: str | None = None
119
119
 
120
120
  @field_serializer("timestamp_started")
@@ -5,29 +5,29 @@ from pydantic import ConfigDict
5
5
  from pydantic import field_serializer
6
6
  from pydantic.types import AwareDatetime
7
7
 
8
- from fractal_server.app.schemas.v2.project import ProjectReadV2
9
- from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskExportV2
10
- from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskImportV2
11
- from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskReadV2
8
+ from fractal_server.app.schemas.v2.project import ProjectRead
9
+ from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskExport
10
+ from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskImport
11
+ from fractal_server.app.schemas.v2.workflowtask import WorkflowTaskRead
12
12
  from fractal_server.app.schemas.v2.workflowtask import (
13
- WorkflowTaskReadV2WithWarning,
13
+ WorkflowTaskReadWithWarning,
14
14
  )
15
15
  from fractal_server.types import ListUniqueNonNegativeInt
16
16
  from fractal_server.types import NonEmptyStr
17
17
 
18
18
 
19
- class WorkflowCreateV2(BaseModel):
19
+ class WorkflowCreate(BaseModel):
20
20
  model_config = ConfigDict(extra="forbid")
21
21
 
22
22
  name: NonEmptyStr
23
23
 
24
24
 
25
- class WorkflowReadV2(BaseModel):
25
+ class WorkflowRead(BaseModel):
26
26
  id: int
27
27
  name: str
28
28
  project_id: int
29
- task_list: list[WorkflowTaskReadV2]
30
- project: ProjectReadV2
29
+ task_list: list[WorkflowTaskRead]
30
+ project: ProjectRead
31
31
  timestamp_created: AwareDatetime
32
32
 
33
33
  @field_serializer("timestamp_created")
@@ -35,18 +35,18 @@ class WorkflowReadV2(BaseModel):
35
35
  return v.isoformat()
36
36
 
37
37
 
38
- class WorkflowReadV2WithWarnings(WorkflowReadV2):
39
- task_list: list[WorkflowTaskReadV2WithWarning]
38
+ class WorkflowReadWithWarnings(WorkflowRead):
39
+ task_list: list[WorkflowTaskReadWithWarning]
40
40
 
41
41
 
42
- class WorkflowUpdateV2(BaseModel):
42
+ class WorkflowUpdate(BaseModel):
43
43
  model_config = ConfigDict(extra="forbid")
44
44
 
45
45
  name: NonEmptyStr = None
46
46
  reordered_workflowtask_ids: ListUniqueNonNegativeInt | None = None
47
47
 
48
48
 
49
- class WorkflowImportV2(BaseModel):
49
+ class WorkflowImport(BaseModel):
50
50
  """
51
51
  Class for `Workflow` import.
52
52
 
@@ -56,10 +56,10 @@ class WorkflowImportV2(BaseModel):
56
56
 
57
57
  model_config = ConfigDict(extra="forbid")
58
58
  name: NonEmptyStr
59
- task_list: list[WorkflowTaskImportV2]
59
+ task_list: list[WorkflowTaskImport]
60
60
 
61
61
 
62
- class WorkflowExportV2(BaseModel):
62
+ class WorkflowExport(BaseModel):
63
63
  """
64
64
  Class for `Workflow` export.
65
65
 
@@ -68,4 +68,4 @@ class WorkflowExportV2(BaseModel):
68
68
  """
69
69
 
70
70
  name: str
71
- task_list: list[WorkflowTaskExportV2]
71
+ task_list: list[WorkflowTaskExport]