fractal-server 2.7.0a11__tar.gz → 2.8.0__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 (237) hide show
  1. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/PKG-INFO +14 -17
  2. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/README.md +10 -7
  3. fractal_server-2.8.0/fractal_server/__init__.py +1 -0
  4. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/user_settings.py +1 -0
  5. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/task.py +16 -2
  6. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/admin/v2/task_group.py +7 -0
  7. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/dataset.py +39 -6
  8. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/task.py +4 -6
  9. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/task_collection.py +17 -44
  10. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/task_collection_custom.py +5 -4
  11. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/user_settings.py +18 -0
  12. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/__init__.py +1 -0
  13. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/dataset.py +5 -3
  14. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/task_collection.py +20 -4
  15. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/task_group.py +8 -1
  16. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/security/__init__.py +8 -1
  17. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/config.py +8 -28
  18. fractal_server-2.8.0/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +39 -0
  19. fractal_server-2.8.0/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +42 -0
  20. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/utils.py +0 -31
  21. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v1/background_operations.py +11 -11
  22. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v1/endpoint_operations.py +5 -5
  23. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v1/utils.py +2 -2
  24. fractal_server-2.8.0/fractal_server/tasks/v2/collection_local.py +357 -0
  25. fractal_server-2.7.0a11/fractal_server/tasks/v2/background_operations_ssh.py → fractal_server-2.8.0/fractal_server/tasks/v2/collection_ssh.py +108 -102
  26. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v2/templates/_1_create_venv.sh +0 -8
  27. fractal_server-2.7.0a11/fractal_server/tasks/v2/templates/_2_upgrade_pip.sh → fractal_server-2.8.0/fractal_server/tasks/v2/templates/_2_preliminary_pip_operations.sh +2 -1
  28. fractal_server-2.8.0/fractal_server/tasks/v2/templates/_3_pip_install.sh +49 -0
  29. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v2/templates/_5_pip_show.sh +5 -5
  30. fractal_server-2.8.0/fractal_server/tasks/v2/utils_background.py +209 -0
  31. fractal_server-2.8.0/fractal_server/tasks/v2/utils_package_names.py +77 -0
  32. fractal_server-2.7.0a11/fractal_server/tasks/v2/utils.py → fractal_server-2.8.0/fractal_server/tasks/v2/utils_python_interpreter.py +0 -26
  33. fractal_server-2.8.0/fractal_server/tasks/v2/utils_templates.py +59 -0
  34. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/utils.py +48 -3
  35. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/pyproject.toml +5 -10
  36. fractal_server-2.7.0a11/fractal_server/__init__.py +0 -1
  37. fractal_server-2.7.0a11/fractal_server/data_migrations/2_7_0.py +0 -323
  38. fractal_server-2.7.0a11/fractal_server/tasks/v2/_venv_pip.py +0 -193
  39. fractal_server-2.7.0a11/fractal_server/tasks/v2/background_operations.py +0 -456
  40. fractal_server-2.7.0a11/fractal_server/tasks/v2/templates/_3_pip_install.sh +0 -28
  41. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/LICENSE +0 -0
  42. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/__main__.py +0 -0
  43. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/alembic.ini +0 -0
  44. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/__init__.py +0 -0
  45. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/db/__init__.py +0 -0
  46. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/__init__.py +0 -0
  47. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/linkusergroup.py +0 -0
  48. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/linkuserproject.py +0 -0
  49. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/security.py +0 -0
  50. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v1/__init__.py +0 -0
  51. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v1/dataset.py +0 -0
  52. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v1/job.py +0 -0
  53. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v1/project.py +0 -0
  54. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v1/state.py +0 -0
  55. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v1/task.py +0 -0
  56. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v1/workflow.py +0 -0
  57. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/__init__.py +0 -0
  58. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/collection_state.py +0 -0
  59. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/dataset.py +0 -0
  60. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/job.py +0 -0
  61. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/project.py +0 -0
  62. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/workflow.py +0 -0
  63. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/models/v2/workflowtask.py +0 -0
  64. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/__init__.py +0 -0
  65. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/admin/__init__.py +0 -0
  66. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/admin/v1.py +0 -0
  67. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
  68. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/admin/v2/job.py +0 -0
  69. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/admin/v2/project.py +0 -0
  70. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/admin/v2/task.py +0 -0
  71. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/__init__.py +0 -0
  72. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/__init__.py +0 -0
  73. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/_aux_functions.py +0 -0
  74. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/dataset.py +0 -0
  75. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/job.py +0 -0
  76. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/project.py +0 -0
  77. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/task.py +0 -0
  78. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/task_collection.py +0 -0
  79. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/workflow.py +0 -0
  80. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v1/workflowtask.py +0 -0
  81. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/__init__.py +0 -0
  82. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
  83. /fractal_server-2.7.0a11/fractal_server/tasks/v2/endpoint_operations.py → /fractal_server-2.8.0/fractal_server/app/routes/api/v2/_aux_functions_task_collection.py +0 -0
  84. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
  85. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/images.py +0 -0
  86. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/job.py +0 -0
  87. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/project.py +0 -0
  88. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/status.py +0 -0
  89. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/submit.py +0 -0
  90. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/task_group.py +0 -0
  91. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/workflow.py +0 -0
  92. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
  93. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
  94. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/__init__.py +0 -0
  95. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
  96. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/current_user.py +0 -0
  97. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/group.py +0 -0
  98. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/login.py +0 -0
  99. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/oauth.py +0 -0
  100. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/register.py +0 -0
  101. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/router.py +0 -0
  102. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/auth/users.py +0 -0
  103. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/aux/__init__.py +0 -0
  104. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/aux/_job.py +0 -0
  105. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/aux/_runner.py +0 -0
  106. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
  107. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/.gitignore +0 -0
  108. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/__init__.py +0 -0
  109. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/async_wrap.py +0 -0
  110. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/components.py +0 -0
  111. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/compress_folder.py +0 -0
  112. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/exceptions.py +0 -0
  113. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/__init__.py +0 -0
  114. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/__init__.py +0 -0
  115. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/_batching.py +0 -0
  116. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/_slurm_config.py +0 -0
  117. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/remote.py +0 -0
  118. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/ssh/__init__.py +0 -0
  119. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -0
  120. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -0
  121. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/ssh/executor.py +0 -0
  122. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/sudo/__init__.py +0 -0
  123. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -0
  124. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -0
  125. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/sudo/_subprocess_run_as_user.py +0 -0
  126. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -0
  127. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/extract_archive.py +0 -0
  128. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/filenames.py +0 -0
  129. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/run_subprocess.py +0 -0
  130. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
  131. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/shutdown.py +0 -0
  132. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/task_files.py +0 -0
  133. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/__init__.py +0 -0
  134. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_common.py +0 -0
  135. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_local/__init__.py +0 -0
  136. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_local/_local_config.py +0 -0
  137. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_local/_submit_setup.py +0 -0
  138. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_local/executor.py +0 -0
  139. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_slurm/__init__.py +0 -0
  140. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_slurm/_submit_setup.py +0 -0
  141. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/_slurm/get_slurm_config.py +0 -0
  142. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/common.py +0 -0
  143. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v1/handle_failed_job.py +0 -0
  144. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/__init__.py +0 -0
  145. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local/__init__.py +0 -0
  146. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local/_local_config.py +0 -0
  147. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local/_submit_setup.py +0 -0
  148. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local/executor.py +0 -0
  149. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local_experimental/__init__.py +0 -0
  150. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local_experimental/_local_config.py +0 -0
  151. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +0 -0
  152. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_local_experimental/executor.py +0 -0
  153. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_slurm_common/__init__.py +0 -0
  154. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_slurm_common/get_slurm_config.py +0 -0
  155. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_slurm_ssh/__init__.py +0 -0
  156. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -0
  157. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_slurm_sudo/__init__.py +0 -0
  158. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -0
  159. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
  160. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/handle_failed_job.py +0 -0
  161. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
  162. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/runner.py +0 -0
  163. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/runner_functions.py +0 -0
  164. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
  165. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/v2/task_interface.py +0 -0
  166. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/runner/versions.py +0 -0
  167. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/__init__.py +0 -0
  168. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/_validators.py +0 -0
  169. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/user.py +0 -0
  170. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/user_group.py +0 -0
  171. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/__init__.py +0 -0
  172. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/applyworkflow.py +0 -0
  173. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/dataset.py +0 -0
  174. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/dumps.py +0 -0
  175. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/manifest.py +0 -0
  176. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/project.py +0 -0
  177. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/state.py +0 -0
  178. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/task.py +0 -0
  179. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/task_collection.py +0 -0
  180. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v1/workflow.py +0 -0
  181. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/dumps.py +0 -0
  182. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/job.py +0 -0
  183. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/manifest.py +0 -0
  184. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/project.py +0 -0
  185. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/status.py +0 -0
  186. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/task.py +0 -0
  187. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/workflow.py +0 -0
  188. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
  189. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/app/user_settings.py +0 -0
  190. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/data_migrations/README.md +0 -0
  191. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/data_migrations/tools.py +0 -0
  192. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/gunicorn_fractal.py +0 -0
  193. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/images/__init__.py +0 -0
  194. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/images/models.py +0 -0
  195. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/images/tools.py +0 -0
  196. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/logger.py +0 -0
  197. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/main.py +0 -0
  198. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/README +0 -0
  199. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/env.py +0 -0
  200. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/naming_convention.py +0 -0
  201. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/script.py.mako +0 -0
  202. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
  203. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
  204. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
  205. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
  206. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
  207. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
  208. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
  209. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
  210. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
  211. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
  212. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
  213. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
  214. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
  215. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
  216. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
  217. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
  218. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
  219. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
  220. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
  221. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
  222. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
  223. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
  224. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/py.typed +0 -0
  225. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/ssh/__init__.py +0 -0
  226. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/ssh/_fabric.py +0 -0
  227. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/string_tools.py +0 -0
  228. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/syringe.py +0 -0
  229. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/__init__.py +0 -0
  230. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v1/_TaskCollectPip.py +0 -0
  231. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v1/__init__.py +0 -0
  232. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v1/get_collection_data.py +0 -0
  233. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v2/__init__.py +0 -0
  234. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v2/database_operations.py +0 -0
  235. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/tasks/v2/templates/_4_pip_freeze.sh +0 -0
  236. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/urls.py +0 -0
  237. {fractal_server-2.7.0a11 → fractal_server-2.8.0}/fractal_server/zip_tools.py +0 -0
@@ -1,35 +1,29 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fractal-server
3
- Version: 2.7.0a11
3
+ Version: 2.8.0
4
4
  Summary: Server component of the Fractal analytics platform
5
5
  Home-page: https://github.com/fractal-analytics-platform/fractal-server
6
6
  License: BSD-3-Clause
7
7
  Author: Tommaso Comparin
8
8
  Author-email: tommaso.comparin@exact-lab.it
9
- Requires-Python: >=3.9,<4.0
9
+ Requires-Python: >=3.10,<4.0
10
10
  Classifier: License :: OSI Approved :: BSD License
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
15
14
  Classifier: Programming Language :: Python :: 3.12
16
- Provides-Extra: gunicorn
17
- Provides-Extra: postgres
18
- Provides-Extra: postgres-psycopg-binary
19
15
  Requires-Dist: aiosqlite (>=0.19.0,<0.20.0)
20
16
  Requires-Dist: alembic (>=1.13.1,<2.0.0)
21
- Requires-Dist: asyncpg (>=0.29.0,<0.30.0) ; extra == "postgres"
22
17
  Requires-Dist: bcrypt (==4.0.1)
23
18
  Requires-Dist: cloudpickle (>=3.0.0,<3.1.0)
24
19
  Requires-Dist: clusterfutures (>=0.5,<0.6)
25
20
  Requires-Dist: fabric (>=3.2.2,<4.0.0)
26
21
  Requires-Dist: fastapi (>=0.115.0,<0.116.0)
27
22
  Requires-Dist: fastapi-users[oauth] (>=12.1.0,<13.0.0)
28
- Requires-Dist: gunicorn (>=21.2,<23.0) ; extra == "gunicorn"
23
+ Requires-Dist: gunicorn (>=21.2,<23.0)
29
24
  Requires-Dist: packaging (>=23.2,<24.0)
30
25
  Requires-Dist: psutil (>=5.9.8,<6.0.0)
31
- Requires-Dist: psycopg2 (>=2.9.5,<3.0.0) ; extra == "postgres"
32
- Requires-Dist: psycopg[binary] (>=3.1.0,<4.0.0) ; extra == "postgres-psycopg-binary"
26
+ Requires-Dist: psycopg[binary] (>=3.1.0,<4.0.0)
33
27
  Requires-Dist: pydantic (>=1.10.8,<2)
34
28
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
35
29
  Requires-Dist: sqlalchemy[asyncio] (>=2.0.23,<2.1)
@@ -43,15 +37,20 @@ Description-Content-Type: text/markdown
43
37
 
44
38
  # Fractal Server
45
39
 
40
+ <p align="center">
41
+ <img src="https://github.com/user-attachments/assets/16e9cf11-d47d-4db8-a9b1-f5349e4175b7" alt="Fractal server" width="400">
42
+ </p>
43
+
46
44
  [![PyPI version](https://img.shields.io/pypi/v/fractal-server?color=gree)](https://pypi.org/project/fractal-server/)
45
+ [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
47
46
  [![CI Status](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/ci.yml/badge.svg)](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/ci.yml?query=branch%3Amain)
48
47
  [![Coverage](https://raw.githubusercontent.com/fractal-analytics-platform/fractal-server/python-coverage-comment-action-data/badge.svg)](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/python-coverage-comment-action-data/htmlcov/index.html)
49
- [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
48
+ [![Documentation Status](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/documentation.yaml/badge.svg)](https://fractal-analytics-platform.github.io/fractal-server)
50
49
  [![Benchmarks](https://img.shields.io/badge/Benchmarks-Done-blue)](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/benchmark-api/benchmarks/bench.html)
51
50
 
52
51
  [Fractal](https://fractal-analytics-platform.github.io/) is a framework developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) to process bioimaging data at scale in the OME-Zarr format and prepare the images for interactive visualization.
53
52
 
54
- ![Fractal_overview](https://github.com/user-attachments/assets/286122d9-08cf-48e8-996d-3cf53e0a81c6)
53
+ ![Fractal_overview](https://github.com/user-attachments/assets/666c8797-2594-4b8e-b1d2-b43fca66d1df)
55
54
 
56
55
  This is the server component of the fractal analytics platform.
57
56
  Find more information about Fractal in general and the other repositories at
@@ -64,14 +63,12 @@ See https://fractal-analytics-platform.github.io/fractal-server.
64
63
 
65
64
  # Contributors and license
66
65
 
67
- Unless otherwise stated in each individual module, all Fractal components are
68
- released according to a BSD 3-Clause License, and Copyright is with Friedrich
69
- Miescher Institute for Biomedical Research and University of Zurich.
66
+ Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it).
67
+
68
+ Unless otherwise specified, Fractal components are released under the BSD 3-Clause License, and copyright is with the BioVisionCenter at the University of Zurich.
70
69
 
71
70
  The SLURM compatibility layer is based on
72
71
  [`clusterfutures`](https://github.com/sampsyo/clusterfutures), by
73
72
  [@sampsyo](https://github.com/sampsyo) and collaborators, and it is released
74
73
  under the terms of the MIT license.
75
74
 
76
- Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it/).
77
-
@@ -1,14 +1,19 @@
1
1
  # Fractal Server
2
2
 
3
+ <p align="center">
4
+ <img src="https://github.com/user-attachments/assets/16e9cf11-d47d-4db8-a9b1-f5349e4175b7" alt="Fractal server" width="400">
5
+ </p>
6
+
3
7
  [![PyPI version](https://img.shields.io/pypi/v/fractal-server?color=gree)](https://pypi.org/project/fractal-server/)
8
+ [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
4
9
  [![CI Status](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/ci.yml/badge.svg)](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/ci.yml?query=branch%3Amain)
5
10
  [![Coverage](https://raw.githubusercontent.com/fractal-analytics-platform/fractal-server/python-coverage-comment-action-data/badge.svg)](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/python-coverage-comment-action-data/htmlcov/index.html)
6
- [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
11
+ [![Documentation Status](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/documentation.yaml/badge.svg)](https://fractal-analytics-platform.github.io/fractal-server)
7
12
  [![Benchmarks](https://img.shields.io/badge/Benchmarks-Done-blue)](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/benchmark-api/benchmarks/bench.html)
8
13
 
9
14
  [Fractal](https://fractal-analytics-platform.github.io/) is a framework developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) to process bioimaging data at scale in the OME-Zarr format and prepare the images for interactive visualization.
10
15
 
11
- ![Fractal_overview](https://github.com/user-attachments/assets/286122d9-08cf-48e8-996d-3cf53e0a81c6)
16
+ ![Fractal_overview](https://github.com/user-attachments/assets/666c8797-2594-4b8e-b1d2-b43fca66d1df)
12
17
 
13
18
  This is the server component of the fractal analytics platform.
14
19
  Find more information about Fractal in general and the other repositories at
@@ -21,13 +26,11 @@ See https://fractal-analytics-platform.github.io/fractal-server.
21
26
 
22
27
  # Contributors and license
23
28
 
24
- Unless otherwise stated in each individual module, all Fractal components are
25
- released according to a BSD 3-Clause License, and Copyright is with Friedrich
26
- Miescher Institute for Biomedical Research and University of Zurich.
29
+ Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it).
30
+
31
+ Unless otherwise specified, Fractal components are released under the BSD 3-Clause License, and copyright is with the BioVisionCenter at the University of Zurich.
27
32
 
28
33
  The SLURM compatibility layer is based on
29
34
  [`clusterfutures`](https://github.com/sampsyo/clusterfutures), by
30
35
  [@sampsyo](https://github.com/sampsyo) and collaborators, and it is released
31
36
  under the terms of the MIT license.
32
-
33
- Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it/).
@@ -0,0 +1 @@
1
+ __VERSION__ = "2.8.0"
@@ -36,3 +36,4 @@ class UserSettings(SQLModel, table=True):
36
36
  ssh_jobs_dir: Optional[str] = None
37
37
  slurm_user: Optional[str] = None
38
38
  cache_dir: Optional[str] = None
39
+ project_dir: Optional[str] = None
@@ -29,7 +29,6 @@ class TaskV2(SQLModel, table=True):
29
29
  sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
30
30
  )
31
31
 
32
- owner: Optional[str] = None
33
32
  version: Optional[str] = None
34
33
  args_schema_non_parallel: Optional[dict[str, Any]] = Field(
35
34
  sa_column=Column(JSON), default=None
@@ -44,7 +43,7 @@ class TaskV2(SQLModel, table=True):
44
43
  input_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
45
44
  output_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
46
45
 
47
- taskgroupv2_id: Optional[int] = Field(foreign_key="taskgroupv2.id")
46
+ taskgroupv2_id: int = Field(foreign_key="taskgroupv2.id")
48
47
 
49
48
  category: Optional[str] = None
50
49
  modality: Optional[str] = None
@@ -104,3 +103,18 @@ class TaskGroupV2(SQLModel, table=True):
104
103
  f"{self.pkg_name=}, {self.wheel_path=}, {self.version=}."
105
104
  )
106
105
  return f"{self.pkg_name}{extras}=={self.version}"
106
+
107
+ @property
108
+ def pinned_package_versions_string(self) -> str:
109
+ """
110
+ Prepare string to be used in `python -m pip install`.
111
+ """
112
+ if self.pinned_package_versions is None:
113
+ return ""
114
+ output = " ".join(
115
+ [
116
+ f"{key}=={value}"
117
+ for key, value in self.pinned_package_versions.items()
118
+ ]
119
+ )
120
+ return output
@@ -21,6 +21,7 @@ from fractal_server.app.routes.auth._aux_auth import (
21
21
  )
22
22
  from fractal_server.app.schemas.v2 import TaskGroupReadV2
23
23
  from fractal_server.app.schemas.v2 import TaskGroupUpdateV2
24
+ from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
24
25
  from fractal_server.logger import set_logger
25
26
 
26
27
  router = APIRouter()
@@ -50,6 +51,8 @@ async def query_task_group_list(
50
51
  user_group_id: Optional[int] = None,
51
52
  private: Optional[bool] = None,
52
53
  active: Optional[bool] = None,
54
+ pkg_name: Optional[str] = None,
55
+ origin: Optional[TaskGroupV2OriginEnum] = None,
53
56
  user: UserOAuth = Depends(current_active_superuser),
54
57
  db: AsyncSession = Depends(get_async_db),
55
58
  ) -> list[TaskGroupReadV2]:
@@ -75,6 +78,10 @@ async def query_task_group_list(
75
78
  stm = stm.where(is_(TaskGroupV2.active, True))
76
79
  else:
77
80
  stm = stm.where(is_(TaskGroupV2.active, False))
81
+ if origin is not None:
82
+ stm = stm.where(TaskGroupV2.origin == origin)
83
+ if pkg_name is not None:
84
+ stm = stm.where(TaskGroupV2.pkg_name.icontains(pkg_name))
78
85
 
79
86
  res = await db.execute(stm)
80
87
  task_groups_list = res.scalars().all()
@@ -22,6 +22,8 @@ from ._aux_functions import _get_project_check_owner
22
22
  from ._aux_functions import _get_submitted_jobs_statement
23
23
  from fractal_server.app.models import UserOAuth
24
24
  from fractal_server.app.routes.auth import current_active_user
25
+ from fractal_server.string_tools import sanitize_string
26
+ from fractal_server.urls import normalize_url
25
27
 
26
28
  router = APIRouter()
27
29
 
@@ -40,14 +42,45 @@ async def create_dataset(
40
42
  """
41
43
  Add new dataset to current project
42
44
  """
43
- await _get_project_check_owner(
45
+ project = await _get_project_check_owner(
44
46
  project_id=project_id, user_id=user.id, db=db
45
47
  )
46
- db_dataset = DatasetV2(project_id=project_id, **dataset.dict())
47
- db.add(db_dataset)
48
- await db.commit()
49
- await db.refresh(db_dataset)
50
- await db.close()
48
+
49
+ if dataset.zarr_dir is None:
50
+
51
+ if user.settings.project_dir is None:
52
+ raise HTTPException(
53
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
54
+ detail=(
55
+ "Both 'dataset.zarr_dir' and 'user.settings.project_dir' "
56
+ "are null"
57
+ ),
58
+ )
59
+
60
+ db_dataset = DatasetV2(
61
+ project_id=project_id,
62
+ zarr_dir="__PLACEHOLDER__",
63
+ **dataset.dict(exclude={"zarr_dir"}),
64
+ )
65
+ db.add(db_dataset)
66
+ await db.commit()
67
+ await db.refresh(db_dataset)
68
+ path = (
69
+ f"{user.settings.project_dir}/fractal/"
70
+ f"{project_id}_{sanitize_string(project.name)}/"
71
+ f"{db_dataset.id}_{sanitize_string(db_dataset.name)}"
72
+ )
73
+ normalized_path = normalize_url(path)
74
+ db_dataset.zarr_dir = normalized_path
75
+
76
+ db.add(db_dataset)
77
+ await db.commit()
78
+ await db.refresh(db_dataset)
79
+ else:
80
+ db_dataset = DatasetV2(project_id=project_id, **dataset.dict())
81
+ db.add(db_dataset)
82
+ await db.commit()
83
+ await db.refresh(db_dataset)
51
84
 
52
85
  return db_dataset
53
86
 
@@ -24,6 +24,7 @@ from fractal_server.app.models.v2 import TaskV2
24
24
  from fractal_server.app.routes.auth import current_active_user
25
25
  from fractal_server.app.routes.auth import current_active_verified_user
26
26
  from fractal_server.app.schemas.v2 import TaskCreateV2
27
+ from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
27
28
  from fractal_server.app.schemas.v2 import TaskReadV2
28
29
  from fractal_server.app.schemas.v2 import TaskUpdateV2
29
30
  from fractal_server.logger import set_logger
@@ -35,8 +36,7 @@ logger = set_logger(__name__)
35
36
 
36
37
  @router.get("/", response_model=list[TaskReadV2])
37
38
  async def get_list_task(
38
- args_schema_parallel: bool = True,
39
- args_schema_non_parallel: bool = True,
39
+ args_schema: bool = True,
40
40
  category: Optional[str] = None,
41
41
  modality: Optional[str] = None,
42
42
  author: Optional[str] = None,
@@ -71,11 +71,9 @@ async def get_list_task(
71
71
  res = await db.execute(stm)
72
72
  task_list = res.scalars().all()
73
73
  await db.close()
74
- if args_schema_parallel is False:
74
+ if args_schema is False:
75
75
  for task in task_list:
76
76
  setattr(task, "args_schema_parallel", None)
77
- if args_schema_non_parallel is False:
78
- for task in task_list:
79
77
  setattr(task, "args_schema_non_parallel", None)
80
78
 
81
79
  return task_list
@@ -200,7 +198,7 @@ async def create_task(
200
198
  user_group_id=user_group_id,
201
199
  active=True,
202
200
  task_list=[db_task],
203
- origin="other",
201
+ origin=TaskGroupV2OriginEnum.OTHER,
204
202
  version=db_task.version,
205
203
  pkg_name=pkg_name,
206
204
  )
@@ -24,22 +24,22 @@ from ....schemas.v2 import CollectionStatusV2
24
24
  from ....schemas.v2 import TaskCollectPipV2
25
25
  from ....schemas.v2 import TaskGroupCreateV2
26
26
  from ...aux.validate_user_settings import validate_user_settings
27
+ from ._aux_functions_task_collection import get_package_version_from_pypi
27
28
  from ._aux_functions_tasks import _get_valid_user_group_id
28
29
  from ._aux_functions_tasks import _verify_non_duplication_group_constraint
29
30
  from ._aux_functions_tasks import _verify_non_duplication_user_constraint
30
31
  from fractal_server.app.models import UserOAuth
31
32
  from fractal_server.app.routes.auth import current_active_user
32
33
  from fractal_server.app.routes.auth import current_active_verified_user
33
- from fractal_server.tasks.utils import _normalize_package_name
34
- from fractal_server.tasks.utils import get_collection_log_v2
35
- from fractal_server.tasks.v2.background_operations import (
36
- background_collect_pip,
34
+ from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
35
+ from fractal_server.tasks.v2.collection_local import (
36
+ collect_package_local,
37
37
  )
38
- from fractal_server.tasks.v2.endpoint_operations import (
39
- get_package_version_from_pypi,
38
+ from fractal_server.tasks.v2.utils_package_names import _parse_wheel_filename
39
+ from fractal_server.tasks.v2.utils_package_names import normalize_package_name
40
+ from fractal_server.tasks.v2.utils_python_interpreter import (
41
+ get_python_interpreter_v2,
40
42
  )
41
- from fractal_server.tasks.v2.utils import _parse_wheel_filename
42
- from fractal_server.tasks.v2.utils import get_python_interpreter_v2
43
43
 
44
44
  router = APIRouter()
45
45
 
@@ -117,15 +117,15 @@ async def collect_tasks_pip(
117
117
  f"Original error: {str(e)}",
118
118
  ),
119
119
  )
120
- task_group_attrs["pkg_name"] = _normalize_package_name(
120
+ task_group_attrs["pkg_name"] = normalize_package_name(
121
121
  wheel_info["distribution"]
122
122
  )
123
123
  task_group_attrs["version"] = wheel_info["version"]
124
- task_group_attrs["origin"] = "wheel-file"
124
+ task_group_attrs["origin"] = TaskGroupV2OriginEnum.WHEELFILE
125
125
  else:
126
126
  pkg_name = task_collect.package
127
- task_group_attrs["pkg_name"] = _normalize_package_name(pkg_name)
128
- task_group_attrs["origin"] = "pypi"
127
+ task_group_attrs["pkg_name"] = normalize_package_name(pkg_name)
128
+ task_group_attrs["origin"] = TaskGroupV2OriginEnum.PYPI
129
129
  latest_version = await get_package_version_from_pypi(
130
130
  task_collect.package,
131
131
  task_collect.package_version,
@@ -248,8 +248,8 @@ async def collect_tasks_pip(
248
248
  if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
249
249
  # SSH task collection
250
250
 
251
- from fractal_server.tasks.v2.background_operations_ssh import (
252
- background_collect_pip_ssh,
251
+ from fractal_server.tasks.v2.collection_ssh import (
252
+ collect_package_ssh,
253
253
  )
254
254
 
255
255
  # User appropriate FractalSSH object
@@ -262,7 +262,7 @@ async def collect_tasks_pip(
262
262
  fractal_ssh = fractal_ssh_list.get(**ssh_credentials)
263
263
 
264
264
  background_tasks.add_task(
265
- background_collect_pip_ssh,
265
+ collect_package_ssh,
266
266
  state_id=state.id,
267
267
  task_group=task_group,
268
268
  fractal_ssh=fractal_ssh,
@@ -272,7 +272,7 @@ async def collect_tasks_pip(
272
272
  else:
273
273
  # Local task collection
274
274
  background_tasks.add_task(
275
- background_collect_pip,
275
+ collect_package_local,
276
276
  state_id=state.id,
277
277
  task_group=task_group,
278
278
  )
@@ -295,42 +295,15 @@ async def collect_tasks_pip(
295
295
  async def check_collection_status(
296
296
  state_id: int,
297
297
  user: UserOAuth = Depends(current_active_user),
298
- verbose: bool = False,
299
298
  db: AsyncSession = Depends(get_async_db),
300
299
  ) -> CollectionStateReadV2: # State[TaskCollectStatus]
301
300
  """
302
301
  Check status of background task collection
303
302
  """
304
-
305
- logger = set_logger(logger_name="check_collection_status")
306
- logger.debug(f"Querying state for state.id={state_id}")
307
303
  state = await db.get(CollectionStateV2, state_id)
308
- if not state:
309
- await db.close()
304
+ if state is None:
310
305
  raise HTTPException(
311
306
  status_code=status.HTTP_404_NOT_FOUND,
312
307
  detail=f"No task collection info with id={state_id}",
313
308
  )
314
-
315
- settings = Inject(get_settings)
316
- if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
317
- # FIXME SSH: add logic for when data.state["log"] is empty
318
- pass
319
- else:
320
- # Non-SSH mode
321
- # In some cases (i.e. a successful or ongoing task collection),
322
- # state.data["log"] is not set; if so, we collect the current logs.
323
- if verbose and not state.data.get("log"):
324
- if "path" not in state.data.keys():
325
- await db.close()
326
- raise HTTPException(
327
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
328
- detail=(
329
- f"No 'path' in CollectionStateV2[{state_id}].data"
330
- ),
331
- )
332
- state.data["log"] = get_collection_log_v2(Path(state.data["path"]))
333
-
334
- reset_logger_handlers(logger)
335
- await db.close()
336
309
  return state
@@ -21,17 +21,18 @@ from fractal_server.app.routes.auth import current_active_verified_user
21
21
  from fractal_server.app.schemas.v2 import TaskCollectCustomV2
22
22
  from fractal_server.app.schemas.v2 import TaskCreateV2
23
23
  from fractal_server.app.schemas.v2 import TaskGroupCreateV2
24
+ from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
24
25
  from fractal_server.app.schemas.v2 import TaskReadV2
25
26
  from fractal_server.config import get_settings
26
27
  from fractal_server.logger import set_logger
27
28
  from fractal_server.string_tools import validate_cmd
28
29
  from fractal_server.syringe import Inject
29
- from fractal_server.tasks.v2.background_operations import (
30
- _prepare_tasks_metadata,
31
- )
32
30
  from fractal_server.tasks.v2.database_operations import (
33
31
  create_db_tasks_and_update_task_group,
34
32
  )
33
+ from fractal_server.tasks.v2.utils_background import (
34
+ _prepare_tasks_metadata,
35
+ )
35
36
 
36
37
  router = APIRouter()
37
38
 
@@ -140,7 +141,7 @@ async def collect_task_custom(
140
141
 
141
142
  # Prepare task-group attributes
142
143
  task_group_attrs = dict(
143
- origin="other",
144
+ origin=TaskGroupV2OriginEnum.OTHER,
144
145
  pkg_name=task_collect.label,
145
146
  user_id=user.id,
146
147
  user_group_id=user_group_id,
@@ -19,6 +19,10 @@ __all__ = (
19
19
 
20
20
 
21
21
  class UserSettingsRead(BaseModel):
22
+ """
23
+ Schema reserved for superusers
24
+ """
25
+
22
26
  id: int
23
27
  ssh_host: Optional[str] = None
24
28
  ssh_username: Optional[str] = None
@@ -28,6 +32,7 @@ class UserSettingsRead(BaseModel):
28
32
  slurm_user: Optional[str] = None
29
33
  slurm_accounts: list[str]
30
34
  cache_dir: Optional[str] = None
35
+ project_dir: Optional[str] = None
31
36
 
32
37
 
33
38
  class UserSettingsReadStrict(BaseModel):
@@ -35,9 +40,14 @@ class UserSettingsReadStrict(BaseModel):
35
40
  slurm_accounts: list[str]
36
41
  cache_dir: Optional[str] = None
37
42
  ssh_username: Optional[str] = None
43
+ project_dir: Optional[str] = None
38
44
 
39
45
 
40
46
  class UserSettingsUpdate(BaseModel, extra=Extra.forbid):
47
+ """
48
+ Schema reserved for superusers
49
+ """
50
+
41
51
  ssh_host: Optional[str] = None
42
52
  ssh_username: Optional[str] = None
43
53
  ssh_private_key_path: Optional[str] = None
@@ -46,6 +56,7 @@ class UserSettingsUpdate(BaseModel, extra=Extra.forbid):
46
56
  slurm_user: Optional[str] = None
47
57
  slurm_accounts: Optional[list[StrictStr]] = None
48
58
  cache_dir: Optional[str] = None
59
+ project_dir: Optional[str] = None
49
60
 
50
61
  _ssh_host = validator("ssh_host", allow_reuse=True)(
51
62
  valstr("ssh_host", accept_none=True)
@@ -83,6 +94,13 @@ class UserSettingsUpdate(BaseModel, extra=Extra.forbid):
83
94
  validate_cmd(value)
84
95
  return val_absolute_path("cache_dir")(value)
85
96
 
97
+ @validator("project_dir")
98
+ def project_dir_validator(cls, value):
99
+ if value is None:
100
+ return None
101
+ validate_cmd(value)
102
+ return val_absolute_path("project_dir")(value)
103
+
86
104
 
87
105
  class UserSettingsUpdateStrict(BaseModel, extra=Extra.forbid):
88
106
  slurm_accounts: Optional[list[StrictStr]] = None
@@ -30,6 +30,7 @@ from .task_collection import TaskCollectPipV2 # noqa F401
30
30
  from .task_group import TaskGroupCreateV2 # noqa F401
31
31
  from .task_group import TaskGroupReadV2 # noqa F401
32
32
  from .task_group import TaskGroupUpdateV2 # noqa F401
33
+ from .task_group import TaskGroupV2OriginEnum # noqa F401
33
34
  from .workflow import WorkflowCreateV2 # noqa F401
34
35
  from .workflow import WorkflowExportV2 # noqa F401
35
36
  from .workflow import WorkflowImportV2 # noqa F401
@@ -33,14 +33,16 @@ class DatasetCreateV2(BaseModel, extra=Extra.forbid):
33
33
 
34
34
  name: str
35
35
 
36
- zarr_dir: str
36
+ zarr_dir: Optional[str] = None
37
37
 
38
38
  filters: Filters = Field(default_factory=Filters)
39
39
 
40
40
  # Validators
41
41
  @validator("zarr_dir")
42
42
  def normalize_zarr_dir(cls, v: str) -> str:
43
- return normalize_url(v)
43
+ if v is not None:
44
+ return normalize_url(v)
45
+ return v
44
46
 
45
47
  _name = validator("name", allow_reuse=True)(valstr("name"))
46
48
 
@@ -95,7 +97,7 @@ class DatasetImportV2(BaseModel, extra=Extra.forbid):
95
97
 
96
98
  name: str
97
99
  zarr_dir: str
98
- images: list[SingleImage] = Field(default_factory=[])
100
+ images: list[SingleImage] = Field(default_factory=list)
99
101
  filters: Filters = Field(default_factory=Filters)
100
102
 
101
103
  # Validators
@@ -10,7 +10,6 @@ from pydantic import Extra
10
10
  from pydantic import root_validator
11
11
  from pydantic import validator
12
12
 
13
- from .._validators import valdictkeys
14
13
  from .._validators import valstr
15
14
  from fractal_server.app.schemas._validators import valutc
16
15
  from fractal_server.app.schemas.v2 import ManifestV2
@@ -62,13 +61,30 @@ class TaskCollectPipV2(BaseModel, extra=Extra.forbid):
62
61
  _package_version = validator("package_version", allow_reuse=True)(
63
62
  valstr("package_version")
64
63
  )
65
- _pinned_package_versions = validator(
66
- "pinned_package_versions", allow_reuse=True
67
- )(valdictkeys("pinned_package_versions"))
68
64
  _package_extras = validator("package_extras", allow_reuse=True)(
69
65
  valstr("package_extras")
70
66
  )
71
67
 
68
+ @validator("pinned_package_versions")
69
+ def pinned_package_validator(cls, value):
70
+ if value is None:
71
+ return value
72
+ old_keys = list(value.keys())
73
+ new_keys = [
74
+ valstr(f"pinned_package_versions[{key}]")(key) for key in old_keys
75
+ ]
76
+ if len(new_keys) != len(set(new_keys)):
77
+ raise ValueError(
78
+ f"Dictionary contains multiple identical keys: {value}."
79
+ )
80
+ for old_key, new_key in zip(old_keys, new_keys):
81
+ if new_key != old_key:
82
+ value[new_key] = value.pop(old_key)
83
+ for pkg, version in value.items():
84
+ validate_cmd(pkg)
85
+ validate_cmd(version)
86
+ return value
87
+
72
88
  @validator("package")
73
89
  def package_validator(cls, value):
74
90
  if "/" in value or value.endswith(".whl"):
@@ -1,4 +1,5 @@
1
1
  from datetime import datetime
2
+ from enum import Enum
2
3
  from typing import Literal
3
4
  from typing import Optional
4
5
 
@@ -13,11 +14,17 @@ from .._validators import valstr
13
14
  from .task import TaskReadV2
14
15
 
15
16
 
17
+ class TaskGroupV2OriginEnum(str, Enum):
18
+ PYPI = "pypi"
19
+ WHEELFILE = "wheel-file"
20
+ OTHER = "other"
21
+
22
+
16
23
  class TaskGroupCreateV2(BaseModel, extra=Extra.forbid):
17
24
  user_id: int
18
25
  user_group_id: Optional[int] = None
19
26
  active: bool = True
20
- origin: Literal["pypi", "wheel-file", "other"]
27
+ origin: TaskGroupV2OriginEnum
21
28
  pkg_name: str
22
29
  version: Optional[str] = None
23
30
  python_version: Optional[str] = None
@@ -315,13 +315,20 @@ async def _create_first_user(
315
315
 
316
316
 
317
317
  def _create_first_group():
318
+ """
319
+ Create a `UserGroup` with `name=FRACTAL_DEFAULT_GROUP_NAME`, if missing.
320
+ """
318
321
  function_logger = set_logger("fractal_server.create_first_group")
319
322
 
320
323
  function_logger.info(
321
324
  f"START _create_first_group, with name '{FRACTAL_DEFAULT_GROUP_NAME}'"
322
325
  )
323
326
  with next(get_sync_db()) as db:
324
- group_all = db.execute(select(UserGroup))
327
+ group_all = db.execute(
328
+ select(UserGroup).where(
329
+ UserGroup.name == FRACTAL_DEFAULT_GROUP_NAME
330
+ )
331
+ )
325
332
  if group_all.scalars().one_or_none() is None:
326
333
  first_group = UserGroup(name=FRACTAL_DEFAULT_GROUP_NAME)
327
334
  db.add(first_group)