fractal-server 2.17.1a0__py3-none-any.whl → 2.17.2__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 (206) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +19 -18
  3. fractal_server/app/db/__init__.py +3 -3
  4. fractal_server/app/models/__init__.py +1 -1
  5. fractal_server/app/models/linkuserproject.py +3 -1
  6. fractal_server/app/models/security.py +22 -17
  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 +4 -0
  12. fractal_server/app/models/v2/profile.py +29 -0
  13. fractal_server/app/models/v2/project.py +5 -14
  14. fractal_server/app/models/v2/resource.py +4 -0
  15. fractal_server/app/models/v2/task_group.py +5 -7
  16. fractal_server/app/models/v2/workflow.py +2 -1
  17. fractal_server/app/routes/admin/v2/__init__.py +1 -2
  18. fractal_server/app/routes/admin/v2/accounting.py +1 -1
  19. fractal_server/app/routes/admin/v2/job.py +9 -9
  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/task.py +28 -18
  23. fractal_server/app/routes/admin/v2/task_group.py +0 -1
  24. fractal_server/app/routes/admin/v2/task_group_lifecycle.py +1 -2
  25. fractal_server/app/routes/api/__init__.py +1 -0
  26. fractal_server/app/routes/api/v2/__init__.py +5 -6
  27. fractal_server/app/routes/api/v2/_aux_functions.py +70 -63
  28. fractal_server/app/routes/api/v2/_aux_functions_history.py +43 -20
  29. fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +2 -4
  30. fractal_server/app/routes/api/v2/_aux_functions_tasks.py +5 -7
  31. fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +1 -2
  32. fractal_server/app/routes/api/v2/dataset.py +13 -32
  33. fractal_server/app/routes/api/v2/history.py +35 -21
  34. fractal_server/app/routes/api/v2/images.py +3 -2
  35. fractal_server/app/routes/api/v2/job.py +17 -14
  36. fractal_server/app/routes/api/v2/pre_submission_checks.py +5 -4
  37. fractal_server/app/routes/api/v2/project.py +22 -17
  38. fractal_server/app/routes/api/v2/status_legacy.py +12 -11
  39. fractal_server/app/routes/api/v2/submit.py +11 -12
  40. fractal_server/app/routes/api/v2/task.py +4 -3
  41. fractal_server/app/routes/api/v2/task_collection.py +28 -30
  42. fractal_server/app/routes/api/v2/task_collection_custom.py +8 -7
  43. fractal_server/app/routes/api/v2/task_collection_pixi.py +1 -2
  44. fractal_server/app/routes/api/v2/task_group.py +7 -6
  45. fractal_server/app/routes/api/v2/task_group_lifecycle.py +6 -6
  46. fractal_server/app/routes/api/v2/task_version_update.py +13 -12
  47. fractal_server/app/routes/api/v2/workflow.py +14 -31
  48. fractal_server/app/routes/api/v2/workflow_import.py +17 -19
  49. fractal_server/app/routes/api/v2/workflowtask.py +10 -12
  50. fractal_server/app/routes/auth/__init__.py +1 -3
  51. fractal_server/app/routes/auth/_aux_auth.py +1 -2
  52. fractal_server/app/routes/auth/current_user.py +4 -5
  53. fractal_server/app/routes/auth/group.py +7 -5
  54. fractal_server/app/routes/auth/login.py +1 -0
  55. fractal_server/app/routes/auth/oauth.py +4 -3
  56. fractal_server/app/routes/auth/register.py +4 -2
  57. fractal_server/app/routes/auth/users.py +10 -10
  58. fractal_server/app/routes/aux/_job.py +1 -1
  59. fractal_server/app/routes/aux/_runner.py +2 -2
  60. fractal_server/app/routes/pagination.py +1 -1
  61. fractal_server/app/schemas/user.py +3 -3
  62. fractal_server/app/schemas/v2/accounting.py +11 -0
  63. fractal_server/app/schemas/v2/dataset.py +28 -4
  64. fractal_server/app/schemas/v2/dumps.py +1 -0
  65. fractal_server/app/schemas/v2/manifest.py +4 -3
  66. fractal_server/app/schemas/v2/profile.py +53 -2
  67. fractal_server/app/schemas/v2/resource.py +109 -13
  68. fractal_server/app/schemas/v2/task.py +0 -1
  69. fractal_server/app/schemas/v2/task_collection.py +1 -1
  70. fractal_server/app/schemas/v2/workflowtask.py +4 -3
  71. fractal_server/app/security/__init__.py +4 -7
  72. fractal_server/app/security/signup_email.py +4 -5
  73. fractal_server/app/shutdown.py +23 -19
  74. fractal_server/config/_data.py +36 -25
  75. fractal_server/config/_database.py +19 -20
  76. fractal_server/config/_email.py +30 -38
  77. fractal_server/config/_main.py +34 -53
  78. fractal_server/config/_oauth.py +17 -21
  79. fractal_server/exceptions.py +4 -0
  80. fractal_server/images/models.py +3 -3
  81. fractal_server/images/status_tools.py +4 -2
  82. fractal_server/logger.py +1 -1
  83. fractal_server/main.py +4 -3
  84. fractal_server/migrations/versions/034a469ec2eb_task_groups.py +4 -8
  85. fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +1 -1
  86. fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +1 -0
  87. fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +1 -1
  88. fractal_server/migrations/versions/1a83a5260664_rename.py +1 -1
  89. fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +1 -0
  90. fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +1 -1
  91. fractal_server/migrations/versions/40d6d6511b20_add_index_to_history_models.py +47 -0
  92. fractal_server/migrations/versions/45fbb391d7af_make_resource_id_fk_non_nullable.py +46 -0
  93. fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +1 -0
  94. fractal_server/migrations/versions/49d0856e9569_drop_table.py +62 -0
  95. fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +1 -1
  96. fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +1 -1
  97. fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +2 -1
  98. fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +7 -19
  99. fractal_server/migrations/versions/5bf02391cfef_v2.py +4 -10
  100. fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +1 -0
  101. fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +1 -1
  102. fractal_server/migrations/versions/7673fe18c05d_remove_project_dir_server_default.py +29 -0
  103. fractal_server/migrations/versions/791ce783d3d8_add_indices.py +1 -1
  104. fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +1 -0
  105. fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +1 -0
  106. fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +2 -4
  107. fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +1 -1
  108. fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +1 -0
  109. fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +1 -1
  110. fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +1 -1
  111. fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +1 -1
  112. fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +2 -4
  113. fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +1 -1
  114. fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +1 -1
  115. fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +1 -1
  116. fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +1 -1
  117. fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +1 -0
  118. fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +1 -0
  119. fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +1 -1
  120. fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +1 -0
  121. fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +1 -1
  122. fractal_server/migrations/versions/caba9fb1ea5e_drop_useroauth_user_settings_id.py +49 -0
  123. fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +4 -9
  124. fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +1 -0
  125. fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +1 -1
  126. fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +1 -0
  127. fractal_server/migrations/versions/e0e717ae2f26_delete_linkuserproject_ondelete_project.py +50 -0
  128. fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +1 -0
  129. fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +1 -1
  130. fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +1 -0
  131. fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +1 -1
  132. fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +1 -0
  133. fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +4 -9
  134. fractal_server/runner/config/_local.py +8 -5
  135. fractal_server/runner/config/_slurm.py +37 -33
  136. fractal_server/runner/config/slurm_mem_to_MB.py +0 -1
  137. fractal_server/runner/executors/base_runner.py +29 -4
  138. fractal_server/runner/executors/local/get_local_config.py +1 -0
  139. fractal_server/runner/executors/local/runner.py +14 -13
  140. fractal_server/runner/executors/slurm_common/_batching.py +5 -10
  141. fractal_server/runner/executors/slurm_common/base_slurm_runner.py +53 -27
  142. fractal_server/runner/executors/slurm_common/get_slurm_config.py +14 -7
  143. fractal_server/runner/executors/slurm_common/remote.py +3 -1
  144. fractal_server/runner/executors/slurm_common/slurm_config.py +1 -0
  145. fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +1 -3
  146. fractal_server/runner/executors/slurm_ssh/runner.py +16 -11
  147. fractal_server/runner/executors/slurm_ssh/tar_commands.py +1 -0
  148. fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -0
  149. fractal_server/runner/executors/slurm_sudo/runner.py +16 -11
  150. fractal_server/runner/task_files.py +9 -3
  151. fractal_server/runner/v2/_local.py +9 -4
  152. fractal_server/runner/v2/_slurm_ssh.py +11 -5
  153. fractal_server/runner/v2/_slurm_sudo.py +11 -5
  154. fractal_server/runner/v2/db_tools.py +0 -1
  155. fractal_server/runner/v2/deduplicate_list.py +2 -1
  156. fractal_server/runner/v2/runner.py +11 -14
  157. fractal_server/runner/v2/runner_functions.py +11 -14
  158. fractal_server/runner/v2/submit_workflow.py +7 -6
  159. fractal_server/ssh/_fabric.py +6 -13
  160. fractal_server/string_tools.py +0 -1
  161. fractal_server/syringe.py +1 -1
  162. fractal_server/tasks/config/_pixi.py +1 -1
  163. fractal_server/tasks/config/_python.py +16 -9
  164. fractal_server/tasks/utils.py +0 -1
  165. fractal_server/tasks/v2/local/_utils.py +1 -1
  166. fractal_server/tasks/v2/local/collect.py +10 -12
  167. fractal_server/tasks/v2/local/collect_pixi.py +9 -10
  168. fractal_server/tasks/v2/local/deactivate.py +7 -8
  169. fractal_server/tasks/v2/local/deactivate_pixi.py +4 -4
  170. fractal_server/tasks/v2/local/delete.py +1 -3
  171. fractal_server/tasks/v2/local/reactivate.py +7 -7
  172. fractal_server/tasks/v2/local/reactivate_pixi.py +7 -7
  173. fractal_server/tasks/v2/ssh/_utils.py +3 -3
  174. fractal_server/tasks/v2/ssh/collect.py +14 -19
  175. fractal_server/tasks/v2/ssh/collect_pixi.py +17 -19
  176. fractal_server/tasks/v2/ssh/deactivate.py +10 -8
  177. fractal_server/tasks/v2/ssh/deactivate_pixi.py +6 -5
  178. fractal_server/tasks/v2/ssh/delete.py +7 -5
  179. fractal_server/tasks/v2/ssh/reactivate.py +11 -11
  180. fractal_server/tasks/v2/ssh/reactivate_pixi.py +8 -9
  181. fractal_server/tasks/v2/templates/1_create_venv.sh +2 -0
  182. fractal_server/tasks/v2/templates/2_pip_install.sh +2 -0
  183. fractal_server/tasks/v2/templates/3_pip_freeze.sh +2 -0
  184. fractal_server/tasks/v2/templates/4_pip_show.sh +2 -0
  185. fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +3 -1
  186. fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +2 -0
  187. fractal_server/tasks/v2/templates/pixi_1_extract.sh +2 -0
  188. fractal_server/tasks/v2/templates/pixi_2_install.sh +2 -0
  189. fractal_server/tasks/v2/templates/pixi_3_post_install.sh +2 -0
  190. fractal_server/tasks/v2/utils_background.py +3 -3
  191. fractal_server/tasks/v2/utils_package_names.py +1 -2
  192. fractal_server/tasks/v2/utils_pixi.py +1 -3
  193. fractal_server/types/__init__.py +76 -1
  194. fractal_server/types/validators/_common_validators.py +1 -3
  195. fractal_server/types/validators/_workflow_task_arguments_validators.py +1 -2
  196. fractal_server/utils.py +1 -0
  197. fractal_server/zip_tools.py +34 -0
  198. {fractal_server-2.17.1a0.dist-info → fractal_server-2.17.2.dist-info}/METADATA +1 -1
  199. fractal_server-2.17.2.dist-info/RECORD +265 -0
  200. fractal_server/app/models/user_settings.py +0 -37
  201. fractal_server/app/routes/admin/v2/project.py +0 -41
  202. fractal_server/data_migrations/2_17_0.py +0 -339
  203. fractal_server-2.17.1a0.dist-info/RECORD +0 -262
  204. {fractal_server-2.17.1a0.dist-info → fractal_server-2.17.2.dist-info}/WHEEL +0 -0
  205. {fractal_server-2.17.1a0.dist-info → fractal_server-2.17.2.dist-info}/entry_points.txt +0 -0
  206. {fractal_server-2.17.1a0.dist-info → fractal_server-2.17.2.dist-info}/licenses/LICENSE +0 -0
@@ -8,26 +8,26 @@ from fastapi import status
8
8
  from pydantic import BaseModel
9
9
  from sqlmodel import select
10
10
 
11
- from ....db import AsyncSession
12
- from ....db import get_async_db
13
- from ....models.v2 import JobV2
14
- from ....models.v2 import ProjectV2
15
- from ....models.v2 import WorkflowV2
16
- from ....schemas.v2 import WorkflowCreateV2
17
- from ....schemas.v2 import WorkflowExportV2
18
- from ....schemas.v2 import WorkflowReadV2
19
- from ....schemas.v2 import WorkflowReadV2WithWarnings
20
- from ....schemas.v2 import WorkflowUpdateV2
11
+ from fractal_server.app.db import AsyncSession
12
+ from fractal_server.app.db import get_async_db
13
+ from fractal_server.app.models import UserOAuth
14
+ from fractal_server.app.models.v2 import JobV2
15
+ from fractal_server.app.models.v2 import TaskGroupV2
16
+ from fractal_server.app.models.v2 import WorkflowV2
17
+ from fractal_server.app.routes.auth import current_user_act_ver_prof
18
+ from fractal_server.app.schemas.v2 import WorkflowCreateV2
19
+ from fractal_server.app.schemas.v2 import WorkflowExportV2
20
+ from fractal_server.app.schemas.v2 import WorkflowReadV2
21
+ from fractal_server.app.schemas.v2 import WorkflowReadV2WithWarnings
22
+ from fractal_server.app.schemas.v2 import WorkflowUpdateV2
23
+ from fractal_server.images.tools import merge_type_filters
24
+
21
25
  from ._aux_functions import _check_workflow_exists
22
26
  from ._aux_functions import _get_project_check_owner
23
27
  from ._aux_functions import _get_submitted_jobs_statement
24
28
  from ._aux_functions import _get_workflow_check_owner
25
29
  from ._aux_functions import _workflow_has_submitted_job
26
30
  from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
27
- from fractal_server.app.models import UserOAuth
28
- from fractal_server.app.models.v2 import TaskGroupV2
29
- from fractal_server.app.routes.auth import current_user_act_ver_prof
30
- from fractal_server.images.tools import merge_type_filters
31
31
 
32
32
  router = APIRouter()
33
33
 
@@ -275,23 +275,6 @@ async def export_workflow(
275
275
  return wf
276
276
 
277
277
 
278
- @router.get("/workflow/", response_model=list[WorkflowReadV2])
279
- async def get_user_workflows(
280
- user: UserOAuth = Depends(current_user_act_ver_prof),
281
- db: AsyncSession = Depends(get_async_db),
282
- ) -> list[WorkflowReadV2]:
283
- """
284
- Returns all the workflows of the current user
285
- """
286
- stm = select(WorkflowV2)
287
- stm = stm.join(ProjectV2).where(
288
- ProjectV2.user_list.any(UserOAuth.id == user.id)
289
- )
290
- res = await db.execute(stm)
291
- workflow_list = res.scalars().all()
292
- return workflow_list
293
-
294
-
295
278
  class WorkflowTaskTypeFiltersInfo(BaseModel):
296
279
  workflowtask_id: int
297
280
  current_type_filters: dict[str, bool]
@@ -5,23 +5,13 @@ from fastapi import status
5
5
  from sqlmodel import or_
6
6
  from sqlmodel import select
7
7
 
8
- from ....db import AsyncSession
9
- from ....db import get_async_db
10
- from ....models.v2 import TaskV2
11
- from ....models.v2 import WorkflowV2
12
- from ....schemas.v2 import TaskImportV2Legacy
13
- from ....schemas.v2 import WorkflowImportV2
14
- from ....schemas.v2 import WorkflowReadV2WithWarnings
15
- from ....schemas.v2 import WorkflowTaskCreateV2
16
- from ._aux_functions import _check_workflow_exists
17
- from ._aux_functions import _get_project_check_owner
18
- from ._aux_functions import _get_user_resource_id
19
- from ._aux_functions import _workflow_insert_task
20
- from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
21
- from ._aux_functions_tasks import _check_type_filters_compatibility
8
+ from fractal_server.app.db import AsyncSession
9
+ from fractal_server.app.db import get_async_db
22
10
  from fractal_server.app.models import LinkUserGroup
23
11
  from fractal_server.app.models import UserOAuth
24
12
  from fractal_server.app.models.v2 import TaskGroupV2
13
+ from fractal_server.app.models.v2 import TaskV2
14
+ from fractal_server.app.models.v2 import WorkflowV2
25
15
  from fractal_server.app.routes.api.v2._aux_task_group_disambiguation import (
26
16
  _disambiguate_task_groups,
27
17
  )
@@ -30,8 +20,19 @@ from fractal_server.app.routes.auth._aux_auth import (
30
20
  _get_default_usergroup_id_or_none,
31
21
  )
32
22
  from fractal_server.app.schemas.v2 import TaskImportV2
23
+ from fractal_server.app.schemas.v2 import TaskImportV2Legacy
24
+ from fractal_server.app.schemas.v2 import WorkflowImportV2
25
+ from fractal_server.app.schemas.v2 import WorkflowReadV2WithWarnings
26
+ from fractal_server.app.schemas.v2 import WorkflowTaskCreateV2
33
27
  from fractal_server.logger import set_logger
34
28
 
29
+ from ._aux_functions import _check_workflow_exists
30
+ from ._aux_functions import _get_project_check_owner
31
+ from ._aux_functions import _get_user_resource_id
32
+ from ._aux_functions import _workflow_insert_task
33
+ from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
34
+ from ._aux_functions_tasks import _check_type_filters_compatibility
35
+
35
36
  router = APIRouter()
36
37
 
37
38
 
@@ -127,8 +128,7 @@ async def _get_task_by_taskimport(
127
128
  for task_group in task_groups_list
128
129
  if (
129
130
  task_group.pkg_name == task_import.pkg_name
130
- and task_import.name
131
- in [task.name for task in task_group.task_list]
131
+ and task_import.name in [task.name for task in task_group.task_list]
132
132
  )
133
133
  ]
134
134
  if len(matching_task_groups) < 1:
@@ -146,9 +146,7 @@ async def _get_task_by_taskimport(
146
146
  "[_get_task_by_taskimport] "
147
147
  "No version requested, looking for latest."
148
148
  )
149
- latest_task = max(
150
- matching_task_groups, key=lambda tg: tg.version or ""
151
- )
149
+ latest_task = max(matching_task_groups, key=lambda tg: tg.version or "")
152
150
  version = latest_task.version
153
151
  logger.info(
154
152
  f"[_get_task_by_taskimport] Latest version set to {version}."
@@ -6,14 +6,8 @@ from fastapi import HTTPException
6
6
  from fastapi import Response
7
7
  from fastapi import status
8
8
 
9
- from ....db import AsyncSession
10
- from ....db import get_async_db
11
- from ._aux_functions import _get_workflow_check_owner
12
- from ._aux_functions import _get_workflow_task_check_owner
13
- from ._aux_functions import _workflow_has_submitted_job
14
- from ._aux_functions import _workflow_insert_task
15
- from ._aux_functions_tasks import _check_type_filters_compatibility
16
- from ._aux_functions_tasks import _get_task_read_access
9
+ from fractal_server.app.db import AsyncSession
10
+ from fractal_server.app.db import get_async_db
17
11
  from fractal_server.app.models import UserOAuth
18
12
  from fractal_server.app.routes.auth import current_user_act_ver_prof
19
13
  from fractal_server.app.schemas.v2 import TaskType
@@ -21,6 +15,13 @@ from fractal_server.app.schemas.v2 import WorkflowTaskCreateV2
21
15
  from fractal_server.app.schemas.v2 import WorkflowTaskReadV2
22
16
  from fractal_server.app.schemas.v2 import WorkflowTaskUpdateV2
23
17
 
18
+ from ._aux_functions import _get_workflow_check_owner
19
+ from ._aux_functions import _get_workflow_task_check_owner
20
+ from ._aux_functions import _workflow_has_submitted_job
21
+ from ._aux_functions import _workflow_insert_task
22
+ from ._aux_functions_tasks import _check_type_filters_compatibility
23
+ from ._aux_functions_tasks import _get_task_read_access
24
+
24
25
  router = APIRouter()
25
26
 
26
27
 
@@ -63,10 +64,7 @@ async def create_workflowtask(
63
64
  ),
64
65
  )
65
66
  elif task.type == TaskType.NON_PARALLEL:
66
- if (
67
- wftask.meta_parallel is not None
68
- or wftask.args_parallel is not None
69
- ):
67
+ if wftask.meta_parallel is not None or wftask.args_parallel is not None:
70
68
  raise HTTPException(
71
69
  status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
72
70
  detail=(
@@ -12,7 +12,6 @@ from fractal_server.app.security import get_user_manager
12
12
  from fractal_server.config import get_settings
13
13
  from fractal_server.syringe import Inject
14
14
 
15
-
16
15
  bearer_transport = BearerTransport(tokenUrl="/auth/token/login")
17
16
  cookie_transport = CookieTransport(cookie_samesite="none")
18
17
 
@@ -71,8 +70,7 @@ async def current_user_act_ver_prof(
71
70
  raise HTTPException(
72
71
  status_code=status.HTTP_403_FORBIDDEN,
73
72
  detail=(
74
- f"Forbidden access "
75
- f"({user.is_verified=} {user.profile_id=})."
73
+ f"Forbidden access ({user.is_verified=} {user.profile_id=})."
76
74
  ),
77
75
  )
78
76
  return user
@@ -13,7 +13,6 @@ from fractal_server.config import get_settings
13
13
  from fractal_server.logger import set_logger
14
14
  from fractal_server.syringe import Inject
15
15
 
16
-
17
16
  logger = set_logger(__name__)
18
17
 
19
18
 
@@ -36,7 +35,7 @@ async def _get_single_user_with_groups(
36
35
 
37
36
  stm_groups = (
38
37
  select(UserGroup)
39
- .join(LinkUserGroup)
38
+ .join(LinkUserGroup, LinkUserGroup.group_id == UserGroup.id)
40
39
  .where(LinkUserGroup.user_id == user.id)
41
40
  .order_by(asc(LinkUserGroup.timestamp_created))
42
41
  )
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Definition of `/auth/current-user/` endpoints
3
3
  """
4
+
4
5
  import os
5
6
 
6
7
  from fastapi import APIRouter
@@ -23,8 +24,8 @@ from fractal_server.app.schemas import UserProfileInfo
23
24
  from fractal_server.app.schemas.user import UserRead
24
25
  from fractal_server.app.schemas.user import UserUpdate
25
26
  from fractal_server.app.schemas.user import UserUpdateStrict
26
- from fractal_server.app.security import get_user_manager
27
27
  from fractal_server.app.security import UserManager
28
+ from fractal_server.app.security import get_user_manager
28
29
  from fractal_server.config import DataAuthScheme
29
30
  from fractal_server.config import get_data_settings
30
31
  from fractal_server.syringe import Inject
@@ -87,9 +88,8 @@ async def get_current_user_profile_info(
87
88
  ) -> UserProfileInfo:
88
89
  stm = (
89
90
  select(Resource, Profile)
90
- .join(UserOAuth)
91
+ .join(UserOAuth, Profile.id == UserOAuth.profile_id)
91
92
  .where(Resource.id == Profile.resource_id)
92
- .where(Profile.id == UserOAuth.profile_id)
93
93
  .where(UserOAuth.id == current_user.id)
94
94
  )
95
95
  res = await db.execute(stm)
@@ -146,8 +146,7 @@ async def get_current_user_allowed_viewer_paths(
146
146
  # Returns the union of `viewer_paths` for all user's groups
147
147
  cmd = (
148
148
  select(UserGroup.viewer_paths)
149
- .join(LinkUserGroup)
150
- .where(LinkUserGroup.group_id == UserGroup.id)
149
+ .join(LinkUserGroup, LinkUserGroup.group_id == UserGroup.id)
151
150
  .where(LinkUserGroup.user_id == current_user.id)
152
151
  )
153
152
  res = await db.execute(cmd)
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Definition of `/auth/group/` routes
3
3
  """
4
+
4
5
  from fastapi import APIRouter
5
6
  from fastapi import Depends
6
7
  from fastapi import HTTPException
@@ -9,11 +10,6 @@ from fastapi import status
9
10
  from sqlalchemy.ext.asyncio import AsyncSession
10
11
  from sqlmodel import select
11
12
 
12
- from . import current_superuser_act
13
- from ._aux_auth import _get_default_usergroup_id_or_none
14
- from ._aux_auth import _get_single_usergroup_with_user_ids
15
- from ._aux_auth import _user_or_404
16
- from ._aux_auth import _usergroup_or_404
17
13
  from fractal_server.app.db import get_async_db
18
14
  from fractal_server.app.models import LinkUserGroup
19
15
  from fractal_server.app.models import UserGroup
@@ -25,6 +21,12 @@ from fractal_server.config import get_settings
25
21
  from fractal_server.logger import set_logger
26
22
  from fractal_server.syringe import Inject
27
23
 
24
+ from . import current_superuser_act
25
+ from ._aux_auth import _get_default_usergroup_id_or_none
26
+ from ._aux_auth import _get_single_usergroup_with_user_ids
27
+ from ._aux_auth import _user_or_404
28
+ from ._aux_auth import _usergroup_or_404
29
+
28
30
  logger = set_logger(__name__)
29
31
 
30
32
 
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Definition of `/auth/{login,logout}/`, `/auth/token/{login/logout}` routes.
3
3
  """
4
+
4
5
  from fastapi import APIRouter
5
6
 
6
7
  from . import cookie_backend
@@ -4,13 +4,14 @@ from httpx_oauth.clients.google import GoogleOAuth2
4
4
  from httpx_oauth.clients.openid import OpenID
5
5
  from httpx_oauth.clients.openid import OpenIDConfigurationError
6
6
 
7
- from . import cookie_backend
8
- from . import fastapi_users
7
+ from fractal_server.config import OAuthSettings
9
8
  from fractal_server.config import get_oauth_settings
10
9
  from fractal_server.config import get_settings
11
- from fractal_server.config import OAuthSettings
12
10
  from fractal_server.syringe import Inject
13
11
 
12
+ from . import cookie_backend
13
+ from . import fastapi_users
14
+
14
15
 
15
16
  def _create_client_github(cfg: OAuthSettings) -> GitHubOAuth2:
16
17
  return GitHubOAuth2(
@@ -1,13 +1,15 @@
1
1
  """
2
2
  Definition of `/auth/register/` routes.
3
3
  """
4
+
4
5
  from fastapi import APIRouter
5
6
  from fastapi import Depends
6
7
 
8
+ from fractal_server.app.schemas.user import UserCreate
9
+ from fractal_server.app.schemas.user import UserRead
10
+
7
11
  from . import current_superuser_act
8
12
  from . import fastapi_users
9
- from ...schemas.user import UserCreate
10
- from ...schemas.user import UserRead
11
13
 
12
14
  router_register = APIRouter()
13
15
 
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Definition of `/auth/users/` routes
3
3
  """
4
+
4
5
  from fastapi import APIRouter
5
6
  from fastapi import Depends
6
7
  from fastapi import HTTPException
@@ -11,24 +12,24 @@ from sqlalchemy.ext.asyncio import AsyncSession
11
12
  from sqlmodel import func
12
13
  from sqlmodel import select
13
14
 
14
- from . import current_superuser_act
15
- from ...db import get_async_db
16
- from ...schemas.user import UserRead
17
- from ...schemas.user import UserUpdate
18
- from ._aux_auth import _get_default_usergroup_id_or_none
19
- from ._aux_auth import _get_single_user_with_groups
15
+ from fractal_server.app.db import get_async_db
20
16
  from fractal_server.app.models import LinkUserGroup
21
17
  from fractal_server.app.models import UserGroup
22
18
  from fractal_server.app.models import UserOAuth
23
19
  from fractal_server.app.models.v2 import Profile
24
20
  from fractal_server.app.routes.auth._aux_auth import _user_or_404
21
+ from fractal_server.app.schemas.user import UserRead
22
+ from fractal_server.app.schemas.user import UserUpdate
25
23
  from fractal_server.app.schemas.user import UserUpdateGroups
26
- from fractal_server.app.security import get_user_manager
27
24
  from fractal_server.app.security import UserManager
25
+ from fractal_server.app.security import get_user_manager
28
26
  from fractal_server.config import get_settings
29
27
  from fractal_server.logger import set_logger
30
28
  from fractal_server.syringe import Inject
31
29
 
30
+ from . import current_superuser_act
31
+ from ._aux_auth import _get_default_usergroup_id_or_none
32
+ from ._aux_auth import _get_single_user_with_groups
32
33
 
33
34
  router_users = APIRouter()
34
35
 
@@ -197,13 +198,12 @@ async def set_user_groups(
197
198
  # Remove/create links as needed
198
199
  for link in links_to_remove:
199
200
  logger.info(
200
- f"Removing LinkUserGroup with {link.user_id=} "
201
- f"and {link.group_id=}."
201
+ f"Removing LinkUserGroup with {link.user_id=} and {link.group_id=}."
202
202
  )
203
203
  await db.delete(link)
204
204
  for group_id in ids_links_to_add:
205
205
  logger.info(
206
- f"Creating new LinkUserGroup with {user_id=} " f"and {group_id=}."
206
+ f"Creating new LinkUserGroup with {user_id=} and {group_id=}."
207
207
  )
208
208
  db.add(LinkUserGroup(user_id=user_id, group_id=group_id))
209
209
  await db.commit()
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- from ...models.v2 import JobV2
3
+ from fractal_server.app.models.v2 import JobV2
4
4
  from fractal_server.runner.filenames import SHUTDOWN_FILENAME
5
5
 
6
6
 
@@ -1,9 +1,9 @@
1
1
  from fastapi import HTTPException
2
2
  from fastapi import status
3
3
 
4
- from ....config import get_settings
5
- from ....syringe import Inject
6
4
  from fractal_server.app.schemas.v2 import ResourceType
5
+ from fractal_server.config import get_settings
6
+ from fractal_server.syringe import Inject
7
7
 
8
8
 
9
9
  def _backend_supports_shutdown(backend: str) -> bool:
@@ -4,8 +4,8 @@ from typing import TypeVar
4
4
  from fastapi import HTTPException
5
5
  from pydantic import BaseModel
6
6
  from pydantic import Field
7
- from pydantic import model_validator
8
7
  from pydantic import ValidationError
8
+ from pydantic import model_validator
9
9
 
10
10
  T = TypeVar("T")
11
11
 
@@ -74,9 +74,9 @@ class UserUpdate(schemas.BaseUserUpdate):
74
74
  is_superuser: bool = None
75
75
  is_verified: bool = None
76
76
  profile_id: int | None = None
77
- project_dir: Annotated[
78
- AbsolutePathStr, AfterValidator(_validate_cmd)
79
- ] = None
77
+ project_dir: Annotated[AbsolutePathStr, AfterValidator(_validate_cmd)] = (
78
+ None
79
+ )
80
80
  slurm_accounts: ListUniqueNonEmptyString = None
81
81
 
82
82
 
@@ -6,6 +6,17 @@ from pydantic.types import AwareDatetime
6
6
 
7
7
 
8
8
  class AccountingRecordRead(BaseModel):
9
+ """
10
+ AccountingRecordRead
11
+
12
+ Attributes:
13
+ id:
14
+ user_id:
15
+ timestamp:
16
+ num_tasks:
17
+ num_new_images:
18
+ """
19
+
9
20
  id: int
10
21
  user_id: int
11
22
  timestamp: AwareDatetime
@@ -8,22 +8,38 @@ from pydantic.types import AwareDatetime
8
8
 
9
9
  from fractal_server.app.schemas.v2.project import ProjectReadV2
10
10
  from fractal_server.images import SingleImage
11
- from fractal_server.types import AttributeFilters
12
11
  from fractal_server.types import NonEmptyStr
13
12
  from fractal_server.types import ZarrDirStr
14
13
 
15
14
 
16
15
  class DatasetCreateV2(BaseModel):
16
+ """
17
+ DatasetCreateV2
18
+
19
+ Attributes:
20
+ name:
21
+ zarr_dir:
22
+ """
23
+
17
24
  model_config = ConfigDict(extra="forbid")
18
25
 
19
26
  name: NonEmptyStr
20
-
21
27
  zarr_dir: ZarrDirStr | None = None
22
28
 
23
- attribute_filters: AttributeFilters = Field(default_factory=dict)
24
-
25
29
 
26
30
  class DatasetReadV2(BaseModel):
31
+ """
32
+ DatasetReadV2
33
+
34
+ Attributes:
35
+ id:
36
+ name:
37
+ project_id:
38
+ project:
39
+ timestamp_created:
40
+ zarr_dir:
41
+ """
42
+
27
43
  id: int
28
44
  name: str
29
45
 
@@ -40,6 +56,14 @@ class DatasetReadV2(BaseModel):
40
56
 
41
57
 
42
58
  class DatasetUpdateV2(BaseModel):
59
+ """
60
+ DatasetUpdateV2
61
+
62
+ Attributes:
63
+ name:
64
+ zarr_dir:
65
+ """
66
+
43
67
  model_config = ConfigDict(extra="forbid")
44
68
 
45
69
  name: NonEmptyStr = None
@@ -7,6 +7,7 @@ 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
+
10
11
  from pydantic import BaseModel
11
12
  from pydantic import ConfigDict
12
13
  from pydantic import Field
@@ -4,11 +4,12 @@ from pydantic import BaseModel
4
4
  from pydantic import Field
5
5
  from pydantic import model_validator
6
6
 
7
- from .task import TaskType
8
7
  from fractal_server.types import DictStrAny
9
8
  from fractal_server.types import HttpUrlStr
10
9
  from fractal_server.types import NonEmptyStr
11
10
 
11
+ from .task import TaskType
12
+
12
13
 
13
14
  class TaskManifestV2(BaseModel):
14
15
  """
@@ -119,9 +120,9 @@ class ManifestV2(BaseModel):
119
120
  manifests as the schema evolves. This is for instance used by
120
121
  Fractal to determine which subclass of the present base class needs
121
122
  be used to read and validate the input.
122
- task_list : list[TaskManifestType]
123
+ task_list:
123
124
  The list of tasks, represented as specified by subclasses of the
124
- _TaskManifestBase (a.k.a. TaskManifestType)
125
+ `_TaskManifestBase` (a.k.a. `TaskManifestType`)
125
126
  has_args_schemas:
126
127
  `True` if the manifest includes JSON Schemas for the arguments of
127
128
  each task.
@@ -6,12 +6,21 @@ from pydantic import Discriminator
6
6
  from pydantic import Tag
7
7
  from pydantic import validate_call
8
8
 
9
- from .resource import ResourceType
10
9
  from fractal_server.types import AbsolutePathStr
11
10
  from fractal_server.types import NonEmptyStr
12
11
 
12
+ from .resource import ResourceType
13
+
13
14
 
14
15
  class ValidProfileLocal(BaseModel):
16
+ """
17
+ Valid local profile.
18
+
19
+ Attributes:
20
+ name: Profile name.
21
+ resource_type: Type of the corresponding resource.
22
+ """
23
+
15
24
  name: NonEmptyStr
16
25
  resource_type: ResourceType
17
26
  username: None = None
@@ -21,6 +30,17 @@ class ValidProfileLocal(BaseModel):
21
30
 
22
31
 
23
32
  class ValidProfileSlurmSudo(BaseModel):
33
+ """
34
+ Valid SLURM/sudo profile.
35
+
36
+ Attributes:
37
+ name: Profile name.
38
+ resource_type: Type of the corresponding resource.
39
+ username:
40
+ SLURM user to impersonate (e.g. as in
41
+ `sudo -u username sbatch /some/script.sh`).
42
+ """
43
+
24
44
  name: NonEmptyStr
25
45
  resource_type: ResourceType
26
46
  username: NonEmptyStr
@@ -30,6 +50,23 @@ class ValidProfileSlurmSudo(BaseModel):
30
50
 
31
51
 
32
52
  class ValidProfileSlurmSSH(BaseModel):
53
+ """
54
+ Valid SLURM/sudo profile.
55
+
56
+ Attributes:
57
+ name: Profile name.
58
+ resource_type: Type of the corresponding resource.
59
+ username:
60
+ SLURM user to impersonate (e.g. as in
61
+ `ssh username@cluster sbatch /some/script.sh`).
62
+ ssh_key_path:
63
+ Local path of SSH private key for user `username`.
64
+ tasks_remote_dir:
65
+ Base folder for task environments on the remote SLURM cluster.
66
+ jobs_remote_dir:
67
+ Base folder for job directories on the remote SLURM cluster.
68
+ """
69
+
33
70
  name: NonEmptyStr
34
71
  resource_type: ResourceType
35
72
  username: NonEmptyStr
@@ -54,6 +91,20 @@ ProfileCreate = Annotated[
54
91
 
55
92
 
56
93
  class ProfileRead(BaseModel):
94
+ """
95
+ Profile schema for GET endpoints.
96
+
97
+ Attributes:
98
+ id:
99
+ name:
100
+ resource_id:
101
+ resource_type:
102
+ username:
103
+ ssh_key_path:
104
+ jobs_remote_dir:
105
+ tasks_remote_dir:
106
+ """
107
+
57
108
  id: int
58
109
  name: str
59
110
  resource_id: int
@@ -69,7 +120,7 @@ def cast_serialize_profile(_data: ProfileCreate) -> dict[str, Any]:
69
120
  """
70
121
  Cast/serialize round-trip for `Profile` data.
71
122
 
72
- We use `@validate_call` because `ProfileeCreate` is a `Union` type and it
123
+ We use `@validate_call` because `ProfileCreate` is a `Union` type and it
73
124
  cannot be instantiated directly.
74
125
 
75
126
  Return: