fractal-server 2.17.1a1__tar.gz → 2.17.2__tar.gz

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 (271) hide show
  1. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/PKG-INFO +1 -1
  2. fractal_server-2.17.2/fractal_server/__init__.py +1 -0
  3. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/__main__.py +19 -18
  4. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/db/__init__.py +3 -3
  5. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/__init__.py +1 -0
  6. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/linkuserproject.py +3 -1
  7. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/security.py +21 -3
  8. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/__init__.py +3 -1
  9. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/accounting.py +9 -1
  10. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/dataset.py +5 -1
  11. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/history.py +15 -1
  12. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/job.py +4 -0
  13. fractal_server-2.17.2/fractal_server/app/models/v2/profile.py +45 -0
  14. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/project.py +4 -10
  15. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/resource.py +4 -0
  16. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/task_group.py +4 -3
  17. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/workflow.py +2 -1
  18. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/__init__.py +1 -2
  19. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/job.py +9 -9
  20. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/profile.py +3 -2
  21. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/resource.py +5 -5
  22. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/task.py +28 -18
  23. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/task_group.py +0 -1
  24. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +1 -2
  25. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/__init__.py +1 -0
  26. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/__init__.py +5 -6
  27. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/_aux_functions.py +70 -63
  28. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/_aux_functions_history.py +43 -20
  29. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +2 -4
  30. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +5 -7
  31. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +1 -2
  32. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/dataset.py +13 -32
  33. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/history.py +35 -21
  34. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/images.py +3 -2
  35. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/job.py +17 -14
  36. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/pre_submission_checks.py +5 -4
  37. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/project.py +22 -17
  38. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/status_legacy.py +12 -11
  39. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/submit.py +11 -12
  40. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/task.py +4 -3
  41. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/task_collection.py +28 -30
  42. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/task_collection_custom.py +8 -7
  43. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/task_collection_pixi.py +1 -2
  44. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/task_group.py +7 -6
  45. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +6 -6
  46. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/task_version_update.py +13 -12
  47. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/workflow.py +14 -31
  48. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/workflow_import.py +17 -19
  49. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/workflowtask.py +10 -12
  50. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/__init__.py +1 -3
  51. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/_aux_auth.py +1 -2
  52. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/current_user.py +4 -5
  53. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/group.py +7 -5
  54. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/login.py +1 -0
  55. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/oauth.py +4 -3
  56. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/register.py +4 -2
  57. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/users.py +10 -10
  58. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/aux/_job.py +1 -1
  59. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/aux/_runner.py +2 -2
  60. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/user.py +3 -3
  61. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/accounting.py +11 -0
  62. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/dataset.py +28 -4
  63. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/dumps.py +1 -0
  64. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/manifest.py +4 -3
  65. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/profile.py +53 -2
  66. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/resource.py +109 -13
  67. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/task.py +0 -1
  68. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/task_collection.py +1 -1
  69. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/workflowtask.py +4 -3
  70. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/security/__init__.py +4 -7
  71. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/security/signup_email.py +4 -5
  72. fractal_server-2.17.2/fractal_server/config/_data.py +79 -0
  73. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/config/_database.py +19 -20
  74. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/config/_email.py +30 -38
  75. fractal_server-2.17.2/fractal_server/config/_main.py +59 -0
  76. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/config/_oauth.py +17 -21
  77. fractal_server-2.17.2/fractal_server/exceptions.py +6 -0
  78. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/images/models.py +3 -3
  79. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/images/status_tools.py +4 -2
  80. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/main.py +4 -3
  81. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +4 -8
  82. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +1 -0
  83. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +1 -0
  84. fractal_server-2.17.2/fractal_server/migrations/versions/40d6d6511b20_add_index_to_history_models.py +47 -0
  85. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +1 -0
  86. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/49d0856e9569_drop_table.py +2 -3
  87. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +2 -1
  88. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +7 -19
  89. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/5bf02391cfef_v2.py +4 -10
  90. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +1 -0
  91. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +1 -0
  92. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +1 -0
  93. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +2 -4
  94. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +1 -0
  95. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +2 -4
  96. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +1 -0
  97. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +1 -0
  98. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +1 -0
  99. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +4 -9
  100. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +1 -0
  101. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +1 -0
  102. fractal_server-2.17.2/fractal_server/migrations/versions/e0e717ae2f26_delete_linkuserproject_ondelete_project.py +50 -0
  103. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +1 -0
  104. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +1 -0
  105. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +1 -0
  106. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +4 -9
  107. fractal_server-2.17.2/fractal_server/runner/config/_local.py +24 -0
  108. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/config/_slurm.py +37 -33
  109. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/config/slurm_mem_to_MB.py +0 -1
  110. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/base_runner.py +29 -4
  111. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/local/get_local_config.py +1 -0
  112. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/local/runner.py +14 -13
  113. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/_batching.py +5 -10
  114. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/base_slurm_runner.py +53 -27
  115. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/get_slurm_config.py +14 -7
  116. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/remote.py +3 -1
  117. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/slurm_config.py +1 -0
  118. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +1 -3
  119. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_ssh/runner.py +16 -11
  120. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_ssh/tar_commands.py +1 -0
  121. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -0
  122. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_sudo/runner.py +16 -11
  123. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/task_files.py +9 -3
  124. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/_local.py +9 -4
  125. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/_slurm_ssh.py +11 -5
  126. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/_slurm_sudo.py +11 -5
  127. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/db_tools.py +0 -1
  128. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/deduplicate_list.py +2 -1
  129. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/runner.py +11 -14
  130. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/runner_functions.py +11 -14
  131. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/submit_workflow.py +7 -6
  132. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/ssh/_fabric.py +6 -13
  133. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/string_tools.py +0 -1
  134. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/config/_python.py +16 -9
  135. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/utils.py +0 -1
  136. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/_utils.py +1 -1
  137. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/collect.py +10 -12
  138. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/collect_pixi.py +9 -10
  139. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/deactivate.py +7 -8
  140. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/deactivate_pixi.py +4 -4
  141. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/delete.py +1 -3
  142. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/reactivate.py +7 -7
  143. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/reactivate_pixi.py +7 -7
  144. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/_utils.py +3 -3
  145. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/collect.py +14 -19
  146. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/collect_pixi.py +17 -19
  147. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/deactivate.py +10 -8
  148. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/deactivate_pixi.py +6 -5
  149. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/delete.py +7 -5
  150. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/reactivate.py +11 -11
  151. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/reactivate_pixi.py +8 -9
  152. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/1_create_venv.sh +2 -0
  153. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/2_pip_install.sh +2 -0
  154. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +2 -0
  155. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/4_pip_show.sh +2 -0
  156. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +3 -1
  157. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +2 -0
  158. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/pixi_1_extract.sh +2 -0
  159. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/pixi_2_install.sh +2 -0
  160. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/templates/pixi_3_post_install.sh +2 -0
  161. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/utils_background.py +3 -3
  162. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/utils_package_names.py +1 -2
  163. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/utils_pixi.py +1 -3
  164. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/types/__init__.py +76 -1
  165. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/types/validators/_common_validators.py +1 -3
  166. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/types/validators/_workflow_task_arguments_validators.py +1 -2
  167. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/utils.py +1 -0
  168. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/zip_tools.py +34 -0
  169. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/pyproject.toml +18 -4
  170. fractal_server-2.17.1a1/fractal_server/__init__.py +0 -1
  171. fractal_server-2.17.1a1/fractal_server/app/models/v2/profile.py +0 -16
  172. fractal_server-2.17.1a1/fractal_server/app/routes/admin/v2/project.py +0 -41
  173. fractal_server-2.17.1a1/fractal_server/config/_data.py +0 -68
  174. fractal_server-2.17.1a1/fractal_server/config/_main.py +0 -78
  175. fractal_server-2.17.1a1/fractal_server/exceptions.py +0 -2
  176. fractal_server-2.17.1a1/fractal_server/runner/config/_local.py +0 -21
  177. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/LICENSE +0 -0
  178. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/README.md +0 -0
  179. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/alembic.ini +0 -0
  180. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/__init__.py +0 -0
  181. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/linkusergroup.py +0 -0
  182. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/task.py +0 -0
  183. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/models/v2/workflowtask.py +0 -0
  184. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/__init__.py +0 -0
  185. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/__init__.py +0 -0
  186. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/_aux_functions.py +0 -0
  187. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/accounting.py +1 -1
  188. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
  189. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py +0 -0
  190. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/auth/router.py +0 -0
  191. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/aux/__init__.py +0 -0
  192. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/aux/validate_user_profile.py +0 -0
  193. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/routes/pagination.py +1 -1
  194. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/__init__.py +0 -0
  195. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/user_group.py +0 -0
  196. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/__init__.py +0 -0
  197. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/history.py +0 -0
  198. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/job.py +0 -0
  199. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/project.py +0 -0
  200. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
  201. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/task_group.py +0 -0
  202. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/schemas/v2/workflow.py +0 -0
  203. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/app/shutdown.py +0 -0
  204. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/config/__init__.py +0 -0
  205. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/config/_settings_config.py +0 -0
  206. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/data_migrations/README.md +0 -0
  207. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/data_migrations/tools.py +0 -0
  208. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/gunicorn_fractal.py +0 -0
  209. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/images/__init__.py +0 -0
  210. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/images/tools.py +0 -0
  211. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/logger.py +1 -1
  212. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/env.py +0 -0
  213. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/naming_convention.py +0 -0
  214. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +1 -1
  215. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +1 -1
  216. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/1a83a5260664_rename.py +1 -1
  217. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +1 -1
  218. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/45fbb391d7af_make_resource_id_fk_non_nullable.py +1 -1
  219. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +1 -1
  220. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +1 -1
  221. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +1 -1
  222. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/7673fe18c05d_remove_project_dir_server_default.py +1 -1
  223. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/791ce783d3d8_add_indices.py +1 -1
  224. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +1 -1
  225. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +1 -1
  226. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +1 -1
  227. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +1 -1
  228. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +1 -1
  229. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +1 -1
  230. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +1 -1
  231. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +1 -1
  232. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +1 -1
  233. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +1 -1
  234. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/caba9fb1ea5e_drop_useroauth_user_settings_id.py +1 -1
  235. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +1 -1
  236. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +1 -1
  237. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +1 -1
  238. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/py.typed +0 -0
  239. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/__init__.py +0 -0
  240. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/components.py +0 -0
  241. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/config/__init__.py +0 -0
  242. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/exceptions.py +0 -0
  243. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/__init__.py +0 -0
  244. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/call_command_wrapper.py +0 -0
  245. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/local/__init__.py +0 -0
  246. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/__init__.py +0 -0
  247. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_common/_job_states.py +0 -0
  248. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_ssh/__init__.py +0 -0
  249. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_ssh/run_subprocess.py +0 -0
  250. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/executors/slurm_sudo/__init__.py +0 -0
  251. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/filenames.py +0 -0
  252. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/set_start_and_last_task_index.py +0 -0
  253. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/__init__.py +0 -0
  254. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/merge_outputs.py +0 -0
  255. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/v2/task_interface.py +0 -0
  256. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/runner/versions.py +0 -0
  257. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/ssh/__init__.py +0 -0
  258. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/syringe.py +1 -1
  259. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/__init__.py +0 -0
  260. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/config/__init__.py +0 -0
  261. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/config/_pixi.py +1 -1
  262. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/__init__.py +0 -0
  263. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/local/__init__.py +0 -0
  264. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
  265. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +0 -0
  266. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/utils_database.py +0 -0
  267. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
  268. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/tasks/v2/utils_templates.py +0 -0
  269. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/types/validators/__init__.py +0 -0
  270. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/types/validators/_filter_validators.py +0 -0
  271. {fractal_server-2.17.1a1 → fractal_server-2.17.2}/fractal_server/urls.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fractal-server
3
- Version: 2.17.1a1
3
+ Version: 2.17.2
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  License-Expression: BSD-3-Clause
6
6
  License-File: LICENSE
@@ -0,0 +1 @@
1
+ __VERSION__ = "2.17.2"
@@ -7,7 +7,6 @@ from pathlib import Path
7
7
  import uvicorn
8
8
  from pydantic import ValidationError
9
9
 
10
-
11
10
  parser = ap.ArgumentParser(description="fractal-server commands")
12
11
 
13
12
  subparsers = parser.add_subparsers(title="Commands", dest="cmd", required=True)
@@ -48,9 +47,7 @@ openapi_parser.add_argument(
48
47
  # fractalctl set-db
49
48
  set_db_parser = subparsers.add_parser(
50
49
  "set-db",
51
- description=(
52
- "Initialise/upgrade database schemas and create first group&user."
53
- ),
50
+ description="Initialise/upgrade database schemas.",
54
51
  )
55
52
 
56
53
  # fractalctl init-db-data
@@ -114,12 +111,13 @@ def set_db():
114
111
  Call alembic to upgrade to the latest migration.
115
112
  Ref: https://stackoverflow.com/a/56683030/283972
116
113
  """
117
- from fractal_server.syringe import Inject
118
- from fractal_server.config import get_db_settings
114
+ from pathlib import Path
119
115
 
120
116
  import alembic.config
121
- from pathlib import Path
117
+
122
118
  import fractal_server
119
+ from fractal_server.config import get_db_settings
120
+ from fractal_server.syringe import Inject
123
121
 
124
122
  # Validate DB settings
125
123
  Inject(get_db_settings)
@@ -140,15 +138,18 @@ def init_db_data(
140
138
  admin_password: str | None = None,
141
139
  admin_project_dir: str | None = None,
142
140
  ) -> None:
143
- from fractal_server.app.security import _create_first_user
144
- from fractal_server.app.security import _create_first_group
141
+ from sqlalchemy import func
142
+ from sqlalchemy import select
143
+
145
144
  from fractal_server.app.db import get_sync_db
146
- from sqlalchemy import select, func
145
+ from fractal_server.app.models import Profile
146
+ from fractal_server.app.models import Resource
147
147
  from fractal_server.app.models.security import UserOAuth
148
- from fractal_server.app.models import Resource, Profile
149
- from fractal_server.app.schemas.v2.resource import cast_serialize_resource
150
- from fractal_server.app.schemas.v2.profile import cast_serialize_profile
151
148
  from fractal_server.app.schemas.v2 import ResourceType
149
+ from fractal_server.app.schemas.v2.profile import cast_serialize_profile
150
+ from fractal_server.app.schemas.v2.resource import cast_serialize_resource
151
+ from fractal_server.app.security import _create_first_group
152
+ from fractal_server.app.security import _create_first_user
152
153
 
153
154
  # Create default group and user
154
155
  print()
@@ -185,9 +186,7 @@ def init_db_data(
185
186
  if resource and profile:
186
187
  with next(get_sync_db()) as db:
187
188
  # Preliminary check
188
- num_resources = db.execute(
189
- select(func.count(Resource.id))
190
- ).scalar()
189
+ num_resources = db.execute(select(func.count(Resource.id))).scalar()
191
190
  if num_resources != 0:
192
191
  print(f"There exist already {num_resources=} resources. Exit.")
193
192
  sys.exit(1)
@@ -270,10 +269,12 @@ def update_db_data():
270
269
  Apply data migrations.
271
270
  """
272
271
 
273
- import fractal_server
272
+ import os
274
273
  from importlib import import_module
274
+
275
275
  from packaging.version import parse
276
- import os
276
+
277
+ import fractal_server
277
278
 
278
279
  def _slugify_version(raw_version: str) -> str:
279
280
  v = parse(raw_version)
@@ -2,6 +2,7 @@
2
2
  `db` module, loosely adapted from
3
3
  https://testdriven.io/blog/fastapi-sqlmodel/#async-sqlmodel
4
4
  """
5
+
5
6
  from collections.abc import AsyncGenerator
6
7
  from collections.abc import Generator
7
8
 
@@ -15,7 +16,6 @@ from fractal_server.config import get_db_settings
15
16
  from fractal_server.logger import set_logger
16
17
  from fractal_server.syringe import Inject
17
18
 
18
-
19
19
  logger = set_logger(__name__)
20
20
 
21
21
 
@@ -46,7 +46,7 @@ class DB:
46
46
 
47
47
  cls._engine_async = create_async_engine(
48
48
  db_settings.DATABASE_URL,
49
- echo=db_settings.DB_ECHO,
49
+ echo=(db_settings.DB_ECHO == "true"),
50
50
  future=True,
51
51
  pool_pre_ping=True,
52
52
  )
@@ -63,7 +63,7 @@ class DB:
63
63
 
64
64
  cls._engine_sync = create_engine(
65
65
  db_settings.DATABASE_URL,
66
- echo=db_settings.DB_ECHO,
66
+ echo=(db_settings.DB_ECHO == "true"),
67
67
  future=True,
68
68
  pool_pre_ping=True,
69
69
  )
@@ -3,6 +3,7 @@ Note that this module is imported from `fractal_server/migrations/env.py`,
3
3
  thus we should always export all relevant database models from here or they
4
4
  will not be picked up by alembic.
5
5
  """
6
+
6
7
  from .linkusergroup import LinkUserGroup # noqa: F401
7
8
  from .linkuserproject import LinkUserProjectV2 # noqa: F401
8
9
  from .security import * # noqa
@@ -7,5 +7,7 @@ class LinkUserProjectV2(SQLModel, table=True):
7
7
  Crossing table between User and ProjectV2
8
8
  """
9
9
 
10
- project_id: int = Field(foreign_key="projectv2.id", primary_key=True)
10
+ project_id: int = Field(
11
+ foreign_key="projectv2.id", primary_key=True, ondelete="CASCADE"
12
+ )
11
13
  user_id: int = Field(foreign_key="user_oauth.id", primary_key=True)
@@ -52,21 +52,39 @@ class UserOAuth(SQLModel, table=True):
52
52
  """
53
53
  ORM model for the `user_oauth` database table.
54
54
 
55
- This class is a modification of SQLModelBaseUserDB from from
56
- fastapi_users_db_sqlmodel. Original Copyright: 2022 François Voron,
57
- released under MIT licence.
55
+ This class is a modification of
56
+ [`SQLModelBaseUserDB`](https://github.com/fastapi-users/fastapi-users-db-sqlmodel/blob/83980d7f20886120f4636a102ab1822b4c366f63/fastapi_users_db_sqlmodel/__init__.py#L15-L32)
57
+ from `fastapi_users_db_sqlmodel`.
58
+ Original Copyright: 2022 François Voron, released under MIT licence.
59
+
60
+ Note that several class attributes are
61
+ [the default ones from `fastapi-users`
62
+ ](https://fastapi-users.github.io/fastapi-users/latest/configuration/schemas/).
58
63
 
59
64
  Attributes:
60
65
  id:
61
66
  email:
62
67
  hashed_password:
63
68
  is_active:
69
+ If this is `False`, the user has no access to the `/api/v2/`
70
+ endpoints.
64
71
  is_superuser:
65
72
  is_verified:
73
+ If this is `False`, the user has no access to the `/api/v2/`
74
+ endpoints.
66
75
  oauth_accounts:
67
76
  profile_id:
77
+ Foreign key linking the user to a `Profile`. If this is unset,
78
+ the user has no access to the `/api/v2/` endpoints.
68
79
  project_dir:
80
+ Absolute path of the user's project directory. This is used (A) as
81
+ a default base folder for the `zarr_dir` of new datasets (where
82
+ the output Zarr are located), and (B) as a folder which is included
83
+ by default in the paths that a user is allowed to stream (if the
84
+ `fractal-data` integration is set up).
85
+ two goals:
69
86
  slurm_accounts:
87
+ List of SLURM accounts that the user can select upon running a job.
70
88
  """
71
89
 
72
90
  model_config = ConfigDict(from_attributes=True)
@@ -1,7 +1,9 @@
1
1
  """
2
2
  v2 `models` module
3
3
  """
4
- from ..linkuserproject import LinkUserProjectV2
4
+
5
+ from fractal_server.app.models.linkuserproject import LinkUserProjectV2
6
+
5
7
  from .accounting import AccountingRecord
6
8
  from .accounting import AccountingRecordSlurm
7
9
  from .dataset import DatasetV2
@@ -7,10 +7,14 @@ from sqlalchemy.types import DateTime
7
7
  from sqlmodel import Field
8
8
  from sqlmodel import SQLModel
9
9
 
10
- from ....utils import get_timestamp
10
+ from fractal_server.utils import get_timestamp
11
11
 
12
12
 
13
13
  class AccountingRecord(SQLModel, table=True):
14
+ """
15
+ AccountingRecord table.
16
+ """
17
+
14
18
  id: int | None = Field(default=None, primary_key=True)
15
19
  user_id: int = Field(foreign_key="user_oauth.id", nullable=False)
16
20
  timestamp: datetime = Field(
@@ -22,6 +26,10 @@ class AccountingRecord(SQLModel, table=True):
22
26
 
23
27
 
24
28
  class AccountingRecordSlurm(SQLModel, table=True):
29
+ """
30
+ AccountingRecordSlurm table.
31
+ """
32
+
25
33
  id: int | None = Field(default=None, primary_key=True)
26
34
  user_id: int = Field(foreign_key="user_oauth.id", nullable=False)
27
35
  timestamp: datetime = Field(
@@ -9,10 +9,14 @@ from sqlmodel import Field
9
9
  from sqlmodel import Relationship
10
10
  from sqlmodel import SQLModel
11
11
 
12
- from ....utils import get_timestamp
12
+ from fractal_server.utils import get_timestamp
13
13
 
14
14
 
15
15
  class DatasetV2(SQLModel, table=True):
16
+ """
17
+ Dataset table.
18
+ """
19
+
16
20
  model_config = ConfigDict(arbitrary_types_allowed=True)
17
21
 
18
22
  id: int | None = Field(default=None, primary_key=True)
@@ -10,10 +10,14 @@ from sqlalchemy.types import DateTime
10
10
  from sqlmodel import Field
11
11
  from sqlmodel import SQLModel
12
12
 
13
- from ....utils import get_timestamp
13
+ from fractal_server.utils import get_timestamp
14
14
 
15
15
 
16
16
  class HistoryRun(SQLModel, table=True):
17
+ """
18
+ HistoryRun table.
19
+ """
20
+
17
21
  model_config = ConfigDict(arbitrary_types_allowed=True)
18
22
 
19
23
  id: int | None = Field(default=None, primary_key=True)
@@ -45,10 +49,15 @@ class HistoryRun(SQLModel, table=True):
45
49
 
46
50
 
47
51
  class HistoryUnit(SQLModel, table=True):
52
+ """
53
+ HistoryUnit table.
54
+ """
55
+
48
56
  id: int | None = Field(default=None, primary_key=True)
49
57
  history_run_id: int = Field(
50
58
  foreign_key="historyrun.id",
51
59
  ondelete="CASCADE",
60
+ index=True,
52
61
  )
53
62
 
54
63
  logfile: str
@@ -60,6 +69,10 @@ class HistoryUnit(SQLModel, table=True):
60
69
 
61
70
 
62
71
  class HistoryImageCache(SQLModel, table=True):
72
+ """
73
+ HistoryImageCache table.
74
+ """
75
+
63
76
  zarr_url: str = Field(primary_key=True)
64
77
  dataset_id: int = Field(
65
78
  primary_key=True,
@@ -77,4 +90,5 @@ class HistoryImageCache(SQLModel, table=True):
77
90
  latest_history_unit_id: int = Field(
78
91
  foreign_key="historyunit.id",
79
92
  ondelete="CASCADE",
93
+ index=True,
80
94
  )
@@ -13,6 +13,10 @@ from fractal_server.utils import get_timestamp
13
13
 
14
14
 
15
15
  class JobV2(SQLModel, table=True):
16
+ """
17
+ Job table.
18
+ """
19
+
16
20
  model_config = ConfigDict(arbitrary_types_allowed=True)
17
21
 
18
22
  id: int | None = Field(default=None, primary_key=True)
@@ -0,0 +1,45 @@
1
+ from sqlmodel import Field
2
+ from sqlmodel import SQLModel
3
+
4
+
5
+ class Profile(SQLModel, table=True):
6
+ """
7
+ Profile table.
8
+ """
9
+
10
+ id: int | None = Field(default=None, primary_key=True)
11
+
12
+ resource_id: int = Field(foreign_key="resource.id", ondelete="RESTRICT")
13
+
14
+ resource_type: str
15
+ """
16
+ Type of resource (either `local`, `slurm_sudo` or `slurm_ssh`).
17
+ """
18
+
19
+ name: str = Field(unique=True)
20
+ """
21
+ Profile name.
22
+ """
23
+
24
+ username: str | None = None
25
+ """
26
+ Username to be impersonated, either via `sudo -u` or via `ssh`.
27
+ """
28
+
29
+ ssh_key_path: str | None = None
30
+ """
31
+ Path to the private SSH key of user `username` (only relevant if
32
+ `resource_type="slurm_ssh"`).
33
+ """
34
+
35
+ jobs_remote_dir: str | None = None
36
+ """
37
+ Remote path of the job folder (only relevant if
38
+ `resource_type="slurm_ssh"`).
39
+ """
40
+
41
+ tasks_remote_dir: str | None = None
42
+ """
43
+ Remote path of the task folder (only relevant if
44
+ `resource_type="slurm_ssh"`).
45
+ """
@@ -3,15 +3,16 @@ from datetime import datetime
3
3
  from sqlalchemy import Column
4
4
  from sqlalchemy.types import DateTime
5
5
  from sqlmodel import Field
6
- from sqlmodel import Relationship
7
6
  from sqlmodel import SQLModel
8
7
 
9
- from .. import LinkUserProjectV2
10
- from fractal_server.app.models import UserOAuth
11
8
  from fractal_server.utils import get_timestamp
12
9
 
13
10
 
14
11
  class ProjectV2(SQLModel, table=True):
12
+ """
13
+ Project table.
14
+ """
15
+
15
16
  id: int | None = Field(default=None, primary_key=True)
16
17
  name: str
17
18
 
@@ -20,10 +21,3 @@ class ProjectV2(SQLModel, table=True):
20
21
  default_factory=get_timestamp,
21
22
  sa_column=Column(DateTime(timezone=True), nullable=False),
22
23
  )
23
-
24
- user_list: list[UserOAuth] = Relationship(
25
- link_model=LinkUserProjectV2,
26
- sa_relationship_kwargs={
27
- "lazy": "selectin",
28
- },
29
- )
@@ -13,6 +13,10 @@ from fractal_server.utils import get_timestamp
13
13
 
14
14
 
15
15
  class Resource(SQLModel, table=True):
16
+ """
17
+ Resource table.
18
+ """
19
+
16
20
  id: int | None = Field(default=None, primary_key=True)
17
21
 
18
22
  type: str
@@ -8,9 +8,10 @@ from sqlmodel import Field
8
8
  from sqlmodel import Relationship
9
9
  from sqlmodel import SQLModel
10
10
 
11
- from .task import TaskV2
12
11
  from fractal_server.utils import get_timestamp
13
12
 
13
+ from .task import TaskV2
14
+
14
15
 
15
16
  def _check_origin_not_pixi(origin: str):
16
17
  """
@@ -22,10 +23,10 @@ def _check_origin_not_pixi(origin: str):
22
23
 
23
24
  def _create_dependency_string(pinned_versions: dict[str, str]) -> str:
24
25
  """
25
- Expand e.g. `{"a": "1.2", "b": "3"}` into `"a==1.2 b==3"`.
26
+ Expand e.g. `{"a": "1.2", "b": "3"}` into `'"a==1.2" "b==3"'`.
26
27
  """
27
28
  output = " ".join(
28
- [f"{key}=={value}" for key, value in pinned_versions.items()]
29
+ [f'"{key}=={value}"' for key, value in pinned_versions.items()]
29
30
  )
30
31
  return output
31
32
 
@@ -7,7 +7,8 @@ from sqlmodel import Field
7
7
  from sqlmodel import Relationship
8
8
  from sqlmodel import SQLModel
9
9
 
10
- from ....utils import get_timestamp
10
+ from fractal_server.utils import get_timestamp
11
+
11
12
  from .workflowtask import WorkflowTaskV2
12
13
 
13
14
 
@@ -1,13 +1,13 @@
1
1
  """
2
2
  `admin/v2` module
3
3
  """
4
+
4
5
  from fastapi import APIRouter
5
6
 
6
7
  from .accounting import router as accounting_router
7
8
  from .impersonate import router as impersonate_router
8
9
  from .job import router as job_router
9
10
  from .profile import router as profile_router
10
- from .project import router as project_router
11
11
  from .resource import router as resource_router
12
12
  from .task import router as task_router
13
13
  from .task_group import router as task_group_router
@@ -17,7 +17,6 @@ router_admin_v2 = APIRouter()
17
17
 
18
18
  router_admin_v2.include_router(accounting_router, prefix="/accounting")
19
19
  router_admin_v2.include_router(job_router, prefix="/job")
20
- router_admin_v2.include_router(project_router, prefix="/project")
21
20
  router_admin_v2.include_router(task_router, prefix="/task")
22
21
  router_admin_v2.include_router(task_group_router, prefix="/task-group")
23
22
  router_admin_v2.include_router(
@@ -12,17 +12,17 @@ from sqlmodel import select
12
12
 
13
13
  from fractal_server.app.db import AsyncSession
14
14
  from fractal_server.app.db import get_async_db
15
+ from fractal_server.app.models import LinkUserProjectV2
15
16
  from fractal_server.app.models import UserOAuth
16
17
  from fractal_server.app.models.v2 import HistoryRun
17
18
  from fractal_server.app.models.v2 import HistoryUnit
18
19
  from fractal_server.app.models.v2 import JobV2
19
- from fractal_server.app.models.v2 import ProjectV2
20
20
  from fractal_server.app.routes.auth import current_superuser_act
21
21
  from fractal_server.app.routes.aux._job import _write_shutdown_file
22
22
  from fractal_server.app.routes.aux._runner import _check_shutdown_is_supported
23
- from fractal_server.app.routes.pagination import get_pagination_params
24
23
  from fractal_server.app.routes.pagination import PaginationRequest
25
24
  from fractal_server.app.routes.pagination import PaginationResponse
25
+ from fractal_server.app.routes.pagination import get_pagination_params
26
26
  from fractal_server.app.schemas.v2 import HistoryUnitStatus
27
27
  from fractal_server.app.schemas.v2 import JobReadV2
28
28
  from fractal_server.app.schemas.v2 import JobStatusTypeV2
@@ -52,7 +52,7 @@ async def view_job(
52
52
  db: AsyncSession = Depends(get_async_db),
53
53
  ) -> PaginationResponse[JobReadV2]:
54
54
  """
55
- Query `ApplyWorkflow` table.
55
+ Query `JobV2` table.
56
56
 
57
57
  Args:
58
58
  id: If not `None`, select a given `applyworkflow.id`.
@@ -84,12 +84,12 @@ async def view_job(
84
84
  stm = stm.where(JobV2.id == id)
85
85
  stm_count = stm_count.where(JobV2.id == id)
86
86
  if user_id is not None:
87
- stm = stm.join(ProjectV2).where(
88
- ProjectV2.user_list.any(UserOAuth.id == user_id)
89
- )
90
- stm_count = stm_count.join(ProjectV2).where(
91
- ProjectV2.user_list.any(UserOAuth.id == user_id)
92
- )
87
+ stm = stm.join(
88
+ LinkUserProjectV2, LinkUserProjectV2.project_id == JobV2.project_id
89
+ ).where(LinkUserProjectV2.user_id == user_id)
90
+ stm_count = stm_count.join(
91
+ LinkUserProjectV2, LinkUserProjectV2.project_id == JobV2.project_id
92
+ ).where(LinkUserProjectV2.user_id == user_id)
93
93
  if project_id is not None:
94
94
  stm = stm.where(JobV2.project_id == project_id)
95
95
  stm_count = stm_count.where(JobV2.project_id == project_id)
@@ -6,8 +6,6 @@ from fastapi import status
6
6
  from sqlmodel import func
7
7
  from sqlmodel import select
8
8
 
9
- from ._aux_functions import _check_profile_name
10
- from ._aux_functions import _get_profile_or_404
11
9
  from fractal_server.app.db import AsyncSession
12
10
  from fractal_server.app.db import get_async_db
13
11
  from fractal_server.app.models import Profile
@@ -16,6 +14,9 @@ from fractal_server.app.routes.auth import current_superuser_act
16
14
  from fractal_server.app.schemas.v2 import ProfileCreate
17
15
  from fractal_server.app.schemas.v2 import ProfileRead
18
16
 
17
+ from ._aux_functions import _check_profile_name
18
+ from ._aux_functions import _get_profile_or_404
19
+
19
20
  router = APIRouter()
20
21
 
21
22
 
@@ -6,9 +6,6 @@ from fastapi import status
6
6
  from sqlalchemy.exc import IntegrityError
7
7
  from sqlmodel import select
8
8
 
9
- from ._aux_functions import _check_resource_name
10
- from ._aux_functions import _get_resource_or_404
11
- from .profile import _check_profile_name
12
9
  from fractal_server.app.db import AsyncSession
13
10
  from fractal_server.app.db import get_async_db
14
11
  from fractal_server.app.models import UserOAuth
@@ -22,6 +19,10 @@ from fractal_server.app.schemas.v2 import ResourceRead
22
19
  from fractal_server.config import get_settings
23
20
  from fractal_server.syringe import Inject
24
21
 
22
+ from ._aux_functions import _check_resource_name
23
+ from ._aux_functions import _get_resource_or_404
24
+ from .profile import _check_profile_name
25
+
25
26
  router = APIRouter()
26
27
 
27
28
 
@@ -47,8 +48,7 @@ def _check_type_match_or_422(new_resource: ResourceCreate) -> None:
47
48
  raise HTTPException(
48
49
  status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
49
50
  detail=(
50
- f"{settings.FRACTAL_RUNNER_BACKEND=} != "
51
- f"{new_resource.type=}"
51
+ f"{settings.FRACTAL_RUNNER_BACKEND=} != {new_resource.type=}"
52
52
  ),
53
53
  )
54
54
 
@@ -8,15 +8,16 @@ from sqlmodel import select
8
8
 
9
9
  from fractal_server.app.db import AsyncSession
10
10
  from fractal_server.app.db import get_async_db
11
+ from fractal_server.app.models import LinkUserProjectV2
11
12
  from fractal_server.app.models import TaskGroupV2
12
13
  from fractal_server.app.models import UserOAuth
13
14
  from fractal_server.app.models.v2 import TaskV2
14
15
  from fractal_server.app.models.v2 import WorkflowTaskV2
15
16
  from fractal_server.app.models.v2 import WorkflowV2
16
17
  from fractal_server.app.routes.auth import current_superuser_act
17
- from fractal_server.app.routes.pagination import get_pagination_params
18
18
  from fractal_server.app.routes.pagination import PaginationRequest
19
19
  from fractal_server.app.routes.pagination import PaginationResponse
20
+ from fractal_server.app.routes.pagination import get_pagination_params
20
21
  from fractal_server.app.schemas.v2.task import TaskType
21
22
 
22
23
  router = APIRouter()
@@ -106,16 +107,12 @@ async def query_tasks(
106
107
  stm = stm.where(TaskV2.authors.icontains(author))
107
108
  stm_count = stm_count.where(TaskV2.authors.icontains(author))
108
109
  if resource_id is not None:
109
- stm = (
110
- stm.join(TaskGroupV2)
111
- .where(TaskGroupV2.id == TaskV2.taskgroupv2_id)
112
- .where(TaskGroupV2.resource_id == resource_id)
113
- )
114
- stm_count = (
115
- stm_count.join(TaskGroupV2)
116
- .where(TaskGroupV2.id == TaskV2.taskgroupv2_id)
117
- .where(TaskGroupV2.resource_id == resource_id)
118
- )
110
+ stm = stm.join(
111
+ TaskGroupV2, TaskGroupV2.id == TaskV2.taskgroupv2_id
112
+ ).where(TaskGroupV2.resource_id == resource_id)
113
+ stm_count = stm_count.join(
114
+ TaskGroupV2, TaskGroupV2.id == TaskV2.taskgroupv2_id
115
+ ).where(TaskGroupV2.resource_id == resource_id)
119
116
 
120
117
  # Find total number of elements
121
118
  res_total_count = await db.execute(stm_count)
@@ -133,13 +130,30 @@ async def query_tasks(
133
130
  for task in task_list:
134
131
  stm = (
135
132
  select(WorkflowV2)
136
- .join(WorkflowTaskV2)
137
- .where(WorkflowTaskV2.workflow_id == WorkflowV2.id)
133
+ .join(
134
+ WorkflowTaskV2,
135
+ WorkflowTaskV2.workflow_id == WorkflowV2.id,
136
+ )
138
137
  .where(WorkflowTaskV2.task_id == task.id)
139
138
  )
140
139
  res = await db.execute(stm)
141
140
  wf_list = res.scalars().all()
142
141
 
142
+ project_users = {}
143
+ for project_id in set([workflow.project_id for workflow in wf_list]):
144
+ res = await db.execute(
145
+ select(UserOAuth.id, UserOAuth.email)
146
+ .join(
147
+ LinkUserProjectV2,
148
+ LinkUserProjectV2.user_id == UserOAuth.id,
149
+ )
150
+ .where(LinkUserProjectV2.project_id == project_id)
151
+ )
152
+ project_users[project_id] = [
153
+ ProjectUser(id=p_user[0], email=p_user[1])
154
+ for p_user in res.all()
155
+ ]
156
+
143
157
  task_info_list.append(
144
158
  dict(
145
159
  task=task.model_dump(),
@@ -149,16 +163,12 @@ async def query_tasks(
149
163
  workflow_name=workflow.name,
150
164
  project_id=workflow.project.id,
151
165
  project_name=workflow.project.name,
152
- project_users=[
153
- dict(id=user.id, email=user.email)
154
- for user in workflow.project.user_list
155
- ],
166
+ project_users=project_users[workflow.project_id],
156
167
  )
157
168
  for workflow in wf_list
158
169
  ],
159
170
  )
160
171
  )
161
-
162
172
  return PaginationResponse[TaskV2Info](
163
173
  total_count=total_count,
164
174
  page_size=page_size,
@@ -24,7 +24,6 @@ from fractal_server.app.schemas.v2 import TaskGroupUpdateV2
24
24
  from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
25
25
  from fractal_server.logger import set_logger
26
26
 
27
-
28
27
  router = APIRouter()
29
28
 
30
29
  logger = set_logger(__name__)
@@ -199,8 +199,7 @@ async def reactivate_task_group(
199
199
  raise HTTPException(
200
200
  status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
201
201
  detail=(
202
- "Cannot reactivate a task group with "
203
- f"{task_group.env_info=}."
202
+ f"Cannot reactivate a task group with {task_group.env_info=}."
204
203
  ),
205
204
  )
206
205