fractal-server 2.14.0a36__tar.gz → 2.14.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 (217) hide show
  1. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/PKG-INFO +1 -1
  2. fractal_server-2.14.2/fractal_server/__init__.py +1 -0
  3. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/job.py +1 -1
  4. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/__init__.py +2 -2
  5. fractal_server-2.14.2/fractal_server/app/routes/api/v2/pre_submission_checks.py +144 -0
  6. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/status_legacy.py +2 -2
  7. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/task_collection_custom.py +22 -10
  8. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/compress_folder.py +15 -3
  9. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +0 -10
  10. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/remote.py +1 -3
  11. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_sudo/runner.py +1 -1
  12. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/extract_archive.py +21 -5
  13. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/runner.py +174 -136
  14. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/config.py +0 -5
  15. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/logger.py +8 -3
  16. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/local/collect.py +1 -1
  17. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/local/deactivate.py +1 -1
  18. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/local/reactivate.py +1 -1
  19. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/ssh/collect.py +1 -1
  20. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/ssh/deactivate.py +1 -1
  21. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/ssh/reactivate.py +1 -1
  22. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/pyproject.toml +2 -2
  23. fractal_server-2.14.0a36/fractal_server/__init__.py +0 -1
  24. fractal_server-2.14.0a36/fractal_server/app/routes/api/v2/verify_image_types.py +0 -61
  25. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/LICENSE +0 -0
  26. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/README.md +0 -0
  27. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/__main__.py +0 -0
  28. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/alembic.ini +0 -0
  29. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/__init__.py +0 -0
  30. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/db/__init__.py +0 -0
  31. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/history/__init__.py +0 -0
  32. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/__init__.py +0 -0
  33. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/linkusergroup.py +0 -0
  34. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/linkuserproject.py +0 -0
  35. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/security.py +0 -0
  36. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/user_settings.py +0 -0
  37. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/__init__.py +0 -0
  38. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/accounting.py +0 -0
  39. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/dataset.py +0 -0
  40. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/history.py +0 -0
  41. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/job.py +0 -0
  42. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/project.py +0 -0
  43. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/task.py +0 -0
  44. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/task_group.py +0 -0
  45. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/workflow.py +0 -0
  46. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/models/v2/workflowtask.py +0 -0
  47. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/__init__.py +0 -0
  48. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/__init__.py +0 -0
  49. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
  50. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
  51. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
  52. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/project.py +0 -0
  53. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/task.py +0 -0
  54. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
  55. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
  56. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/__init__.py +0 -0
  57. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
  58. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
  59. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
  60. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
  61. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/dataset.py +0 -0
  62. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/history.py +0 -0
  63. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/images.py +0 -0
  64. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/job.py +0 -0
  65. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/project.py +0 -0
  66. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/submit.py +0 -0
  67. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/task.py +0 -0
  68. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
  69. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/task_group.py +0 -0
  70. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
  71. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/workflow.py +0 -0
  72. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
  73. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
  74. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/__init__.py +0 -0
  75. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
  76. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/current_user.py +0 -0
  77. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/group.py +0 -0
  78. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/login.py +0 -0
  79. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/oauth.py +0 -0
  80. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/register.py +0 -0
  81. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/router.py +0 -0
  82. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/auth/users.py +0 -0
  83. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/aux/__init__.py +0 -0
  84. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/aux/_job.py +0 -0
  85. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/aux/_runner.py +0 -0
  86. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
  87. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/routes/pagination.py +0 -0
  88. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/__init__.py +0 -0
  89. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/components.py +0 -0
  90. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/exceptions.py +0 -0
  91. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/__init__.py +0 -0
  92. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/base_runner.py +0 -0
  93. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/local/__init__.py +0 -0
  94. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/local/get_local_config.py +0 -0
  95. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/local/runner.py +0 -0
  96. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/__init__.py +0 -0
  97. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/_batching.py +0 -0
  98. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/_job_states.py +0 -0
  99. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/_slurm_config.py +0 -0
  100. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +0 -0
  101. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
  102. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_common/utils_executors.py +0 -0
  103. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_ssh/__init__.py +0 -0
  104. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_ssh/runner.py +0 -0
  105. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
  106. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
  107. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/filenames.py +0 -0
  108. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/run_subprocess.py +0 -0
  109. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
  110. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/shutdown.py +0 -0
  111. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/task_files.py +0 -0
  112. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/__init__.py +0 -0
  113. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/_local.py +0 -0
  114. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/_slurm_ssh.py +0 -0
  115. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/_slurm_sudo.py +0 -0
  116. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/db_tools.py +0 -0
  117. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
  118. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
  119. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/runner_functions.py +0 -0
  120. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
  121. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/submit_workflow.py +0 -0
  122. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/v2/task_interface.py +0 -0
  123. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/runner/versions.py +0 -0
  124. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/__init__.py +0 -0
  125. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/_filter_validators.py +0 -0
  126. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/_validators.py +0 -0
  127. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/user.py +0 -0
  128. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/user_group.py +0 -0
  129. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/user_settings.py +0 -0
  130. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/__init__.py +0 -0
  131. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/accounting.py +0 -0
  132. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/dataset.py +0 -0
  133. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/dumps.py +0 -0
  134. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/history.py +0 -0
  135. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/job.py +0 -0
  136. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/manifest.py +0 -0
  137. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/project.py +0 -0
  138. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
  139. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/task.py +0 -0
  140. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/task_collection.py +0 -0
  141. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/task_group.py +0 -0
  142. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/workflow.py +0 -0
  143. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
  144. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/security/__init__.py +0 -0
  145. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/security/signup_email.py +0 -0
  146. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/app/user_settings.py +0 -0
  147. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/data_migrations/README.md +0 -0
  148. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/data_migrations/tools.py +0 -0
  149. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/gunicorn_fractal.py +0 -0
  150. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/images/__init__.py +0 -0
  151. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/images/models.py +0 -0
  152. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/images/tools.py +0 -0
  153. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/main.py +0 -0
  154. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/env.py +0 -0
  155. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/naming_convention.py +0 -0
  156. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
  157. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
  158. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
  159. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
  160. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
  161. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
  162. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
  163. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
  164. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
  165. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
  166. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
  167. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
  168. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
  169. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
  170. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
  171. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
  172. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
  173. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
  174. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
  175. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
  176. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
  177. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
  178. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
  179. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
  180. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
  181. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +0 -0
  182. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
  183. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
  184. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
  185. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
  186. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
  187. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
  188. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
  189. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +0 -0
  190. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
  191. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
  192. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/py.typed +0 -0
  193. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/ssh/__init__.py +0 -0
  194. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/ssh/_fabric.py +0 -0
  195. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/string_tools.py +0 -0
  196. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/syringe.py +0 -0
  197. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/__init__.py +0 -0
  198. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/utils.py +0 -0
  199. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/__init__.py +0 -0
  200. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/local/__init__.py +0 -0
  201. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/local/_utils.py +0 -0
  202. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
  203. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
  204. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
  205. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
  206. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
  207. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
  208. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
  209. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
  210. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/utils_background.py +0 -0
  211. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/utils_database.py +0 -0
  212. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/utils_package_names.py +0 -0
  213. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
  214. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/tasks/v2/utils_templates.py +0 -0
  215. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/urls.py +0 -0
  216. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/utils.py +0 -0
  217. {fractal_server-2.14.0a36 → fractal_server-2.14.2}/fractal_server/zip_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fractal-server
3
- Version: 2.14.0a36
3
+ Version: 2.14.2
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  License: BSD-3-Clause
6
6
  Author: Tommaso Comparin
@@ -0,0 +1 @@
1
+ __VERSION__ = "2.14.2"
@@ -154,7 +154,7 @@ async def update_job(
154
154
  if job_update.status != JobStatusTypeV2.FAILED:
155
155
  raise HTTPException(
156
156
  status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
157
- detail=f"Cannot set job status to {job_update.status}",
157
+ detail=f"Cannot set job status to {job_update.status.value}",
158
158
  )
159
159
 
160
160
  setattr(job, "status", job_update.status)
@@ -7,6 +7,7 @@ from .dataset import router as dataset_router_v2
7
7
  from .history import router as history_router_v2
8
8
  from .images import router as images_routes_v2
9
9
  from .job import router as job_router_v2
10
+ from .pre_submission_checks import router as pre_submission_checks_router
10
11
  from .project import router as project_router_v2
11
12
  from .status_legacy import router as status_legacy_router_v2
12
13
  from .submit import router as submit_job_router_v2
@@ -15,7 +16,6 @@ from .task_collection import router as task_collection_router_v2
15
16
  from .task_collection_custom import router as task_collection_router_v2_custom
16
17
  from .task_group import router as task_group_router_v2
17
18
  from .task_group_lifecycle import router as task_group_lifecycle_router_v2
18
- from .verify_image_types import router as verify_image_types_router
19
19
  from .workflow import router as workflow_router_v2
20
20
  from .workflow_import import router as workflow_import_router_v2
21
21
  from .workflowtask import router as workflowtask_router_v2
@@ -26,7 +26,7 @@ from fractal_server.syringe import Inject
26
26
  router_api_v2 = APIRouter()
27
27
 
28
28
  router_api_v2.include_router(dataset_router_v2, tags=["V2 Dataset"])
29
- router_api_v2.include_router(verify_image_types_router, tags=["V2 Job"])
29
+ router_api_v2.include_router(pre_submission_checks_router, tags=["V2 Job"])
30
30
  router_api_v2.include_router(job_router_v2, tags=["V2 Job"])
31
31
  router_api_v2.include_router(images_routes_v2, tags=["V2 Images"])
32
32
  router_api_v2.include_router(project_router_v2, tags=["V2 Project"])
@@ -0,0 +1,144 @@
1
+ from typing import Optional
2
+
3
+ from fastapi import APIRouter
4
+ from fastapi import Depends
5
+ from fastapi import status
6
+ from fastapi.responses import JSONResponse
7
+ from pydantic import BaseModel
8
+ from pydantic import Field
9
+ from sqlmodel import select
10
+
11
+ from ._aux_functions import _get_dataset_check_owner
12
+ from ._aux_functions import _get_workflow_task_check_owner
13
+ from .images import ImageQuery
14
+ from fractal_server.app.db import AsyncSession
15
+ from fractal_server.app.db import get_async_db
16
+ from fractal_server.app.models import UserOAuth
17
+ from fractal_server.app.models.v2 import HistoryImageCache
18
+ from fractal_server.app.models.v2 import HistoryUnit
19
+ from fractal_server.app.routes.auth import current_active_user
20
+ from fractal_server.app.schemas.v2 import HistoryUnitStatus
21
+ from fractal_server.images.models import AttributeFiltersType
22
+ from fractal_server.images.tools import aggregate_types
23
+ from fractal_server.images.tools import filter_image_list
24
+
25
+ router = APIRouter()
26
+
27
+
28
+ @router.post(
29
+ "/project/{project_id}/dataset/{dataset_id}/images/verify-unique-types/",
30
+ status_code=status.HTTP_200_OK,
31
+ )
32
+ async def verify_unique_types(
33
+ project_id: int,
34
+ dataset_id: int,
35
+ query: Optional[ImageQuery] = None,
36
+ user: UserOAuth = Depends(current_active_user),
37
+ db: AsyncSession = Depends(get_async_db),
38
+ ) -> list[str]:
39
+ # Get dataset
40
+ output = await _get_dataset_check_owner(
41
+ project_id=project_id, dataset_id=dataset_id, user_id=user.id, db=db
42
+ )
43
+ dataset = output["dataset"]
44
+
45
+ # Filter images
46
+ if query is None:
47
+ filtered_images = dataset.images
48
+ else:
49
+ filtered_images = filter_image_list(
50
+ images=dataset.images,
51
+ attribute_filters=query.attribute_filters,
52
+ type_filters=query.type_filters,
53
+ )
54
+
55
+ # Get actual values for each available type
56
+ available_types = aggregate_types(filtered_images)
57
+ values_per_type: dict[str, set] = {
58
+ _type: set() for _type in available_types
59
+ }
60
+ for _img in filtered_images:
61
+ for _type in available_types:
62
+ values_per_type[_type].add(_img["types"].get(_type, False))
63
+
64
+ # Find types with non-unique value
65
+ non_unique_types = [
66
+ key for key, value in values_per_type.items() if len(value) > 1
67
+ ]
68
+ non_unique_types = sorted(non_unique_types)
69
+
70
+ return non_unique_types
71
+
72
+
73
+ class NonProcessedImagesPayload(BaseModel):
74
+ attribute_filters: AttributeFiltersType = Field(default_factory=dict)
75
+ type_filters: dict[str, bool] = Field(default_factory=dict)
76
+
77
+
78
+ @router.post(
79
+ "/project/{project_id}/dataset/{dataset_id}/images/non-processed/",
80
+ status_code=status.HTTP_200_OK,
81
+ )
82
+ async def check_workflowtask(
83
+ project_id: int,
84
+ dataset_id: int,
85
+ workflow_id: int,
86
+ workflowtask_id: int,
87
+ filters: NonProcessedImagesPayload,
88
+ user: UserOAuth = Depends(current_active_user),
89
+ db: AsyncSession = Depends(get_async_db),
90
+ ) -> JSONResponse:
91
+
92
+ db_workflow_task, db_workflow = await _get_workflow_task_check_owner(
93
+ project_id=project_id,
94
+ workflow_task_id=workflowtask_id,
95
+ workflow_id=workflow_id,
96
+ user_id=user.id,
97
+ db=db,
98
+ )
99
+
100
+ if db_workflow_task.order == 0:
101
+ # Skip check for first task in the workflow
102
+ return JSONResponse(status_code=200, content=[])
103
+
104
+ previous_wft = db_workflow.task_list[db_workflow_task.order - 1]
105
+
106
+ if previous_wft.task.output_types != {}:
107
+ # Skip check if previous task has non-trivial `output_types`
108
+ return JSONResponse(status_code=200, content=[])
109
+ elif previous_wft.task.type in [
110
+ "converter_compound",
111
+ "converter_non_parallel",
112
+ ]:
113
+ # Skip check if previous task is converter
114
+ return JSONResponse(status_code=200, content=[])
115
+
116
+ res = await _get_dataset_check_owner(
117
+ project_id=project_id,
118
+ dataset_id=dataset_id,
119
+ user_id=user.id,
120
+ db=db,
121
+ )
122
+ dataset = res["dataset"]
123
+ filtered_images = filter_image_list(
124
+ images=dataset.images,
125
+ type_filters=filters.type_filters,
126
+ attribute_filters=filters.attribute_filters,
127
+ )
128
+
129
+ filtered_zarr_urls = [image["zarr_url"] for image in filtered_images]
130
+
131
+ res = await db.execute(
132
+ select(HistoryImageCache.zarr_url)
133
+ .join(HistoryUnit)
134
+ .where(HistoryImageCache.zarr_url.in_(filtered_zarr_urls))
135
+ .where(HistoryImageCache.dataset_id == dataset_id)
136
+ .where(HistoryImageCache.workflowtask_id == previous_wft.id)
137
+ .where(HistoryImageCache.latest_history_unit_id == HistoryUnit.id)
138
+ .where(HistoryUnit.status == HistoryUnitStatus.DONE)
139
+ )
140
+ done_zarr_urls = res.scalars().all()
141
+
142
+ missing_zarr_urls = list(set(filtered_zarr_urls) - set(done_zarr_urls))
143
+
144
+ return JSONResponse(status_code=200, content=missing_zarr_urls)
@@ -118,8 +118,8 @@ async def get_workflowtask_status(
118
118
  )
119
119
  except ValueError:
120
120
  logger.warning(
121
- f"Job {running_job.id} is submitted but its task list does "
122
- f"not contain a {WorkflowTaskStatusTypeV2.SUBMITTED} task."
121
+ f"Job {running_job.id} is submitted but its task list does not"
122
+ f" contain a {WorkflowTaskStatusTypeV2.SUBMITTED.value} task."
123
123
  )
124
124
  first_submitted_index = 0
125
125
 
@@ -1,3 +1,4 @@
1
+ import os
1
2
  import shlex
2
3
  import subprocess # nosec
3
4
  from pathlib import Path
@@ -65,25 +66,36 @@ async def collect_task_custom(
65
66
  detail="Cannot infer 'package_root' with 'slurm_ssh' backend.",
66
67
  )
67
68
  else:
68
- if not Path(task_collect.python_interpreter).is_file():
69
+ if not os.access(
70
+ task_collect.python_interpreter, os.X_OK
71
+ ) or not os.access(task_collect.python_interpreter, os.R_OK):
69
72
  raise HTTPException(
70
73
  status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
71
74
  detail=(
72
75
  f"{task_collect.python_interpreter=} "
73
- "doesn't exist or is not a file."
76
+ "is not accessible to the Fractal user "
77
+ "or it is not executable."
74
78
  ),
75
79
  )
76
- if (
77
- task_collect.package_root is not None
78
- and not Path(task_collect.package_root).is_dir()
79
- ):
80
+ if not Path(task_collect.python_interpreter).is_file():
80
81
  raise HTTPException(
81
82
  status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
82
- detail=(
83
- f"{task_collect.package_root=} "
84
- "doesn't exist or is not a directory."
85
- ),
83
+ detail=f"{task_collect.python_interpreter=} is not a file.",
86
84
  )
85
+ if task_collect.package_root is not None:
86
+ if not os.access(task_collect.package_root, os.R_OK):
87
+ raise HTTPException(
88
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
89
+ detail=(
90
+ f"{task_collect.package_root=} "
91
+ "is not accessible to the Fractal user."
92
+ ),
93
+ )
94
+ if not Path(task_collect.package_root).is_dir():
95
+ raise HTTPException(
96
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
97
+ detail=f"{task_collect.package_root=} is not a directory.",
98
+ )
87
99
 
88
100
  if task_collect.package_root is None:
89
101
 
@@ -80,6 +80,7 @@ def _remove_temp_subfolder(subfolder_path_tmp_copy: Path, logger_name: str):
80
80
  def compress_folder(
81
81
  subfolder_path: Path,
82
82
  filelist_path: str | None,
83
+ default_logging_level: int | None = None,
83
84
  ) -> str:
84
85
  """
85
86
  Compress e.g. `/path/archive` into `/path/archive.tar.gz`
@@ -90,13 +91,17 @@ def compress_folder(
90
91
  Args:
91
92
  subfolder_path: Absolute path to the folder to compress.
92
93
  remote_to_local: If `True`, exclude some files from the tar.gz archive.
94
+ default_logging_level:
93
95
 
94
96
  Returns:
95
97
  Absolute path to the tar.gz archive.
96
98
  """
97
99
 
98
100
  logger_name = "compress_folder"
99
- logger = set_logger(logger_name)
101
+ logger = set_logger(
102
+ logger_name,
103
+ default_logging_level=default_logging_level,
104
+ )
100
105
 
101
106
  logger.debug("START")
102
107
  logger.debug(f"{subfolder_path=}")
@@ -132,7 +137,10 @@ def compress_folder(
132
137
  )
133
138
 
134
139
 
135
- def main(sys_argv: list[str]):
140
+ def main(
141
+ sys_argv: list[str],
142
+ default_logging_level: int | None = None,
143
+ ):
136
144
 
137
145
  help_msg = (
138
146
  "Expected use:\n"
@@ -146,15 +154,19 @@ def main(sys_argv: list[str]):
146
154
  compress_folder(
147
155
  subfolder_path=Path(sys_argv[1]),
148
156
  filelist_path=None,
157
+ default_logging_level=default_logging_level,
149
158
  )
150
159
  elif num_args == 3 and sys_argv[2] == "--filelist":
151
160
  compress_folder(
152
161
  subfolder_path=Path(sys_argv[1]),
153
162
  filelist_path=sys_argv[3],
163
+ default_logging_level=default_logging_level,
154
164
  )
155
165
  else:
156
166
  sys.exit(f"Invalid argument.\n{help_msg}\nProvided: {sys_argv[1:]=}")
157
167
 
158
168
 
159
169
  if __name__ == "__main__":
160
- main(sys.argv)
170
+ import logging
171
+
172
+ main(sys.argv, default_logging_level=logging.DEBUG)
@@ -524,12 +524,6 @@ class BaseSlurmRunner(BaseRunner):
524
524
  slurm_job_ids=self.job_ids,
525
525
  )
526
526
 
527
- # NOTE: see issue 2444
528
- settings = Inject(get_settings)
529
- sleep_time = settings.FRACTAL_SLURM_INTERVAL_BEFORE_RETRIEVAL
530
- logger.warning(f"[submit] Now sleep {sleep_time} seconds.")
531
- time.sleep(sleep_time)
532
-
533
527
  # Retrieval phase
534
528
  logger.debug("[submit] START retrieval phase")
535
529
  scancelled_job_ids = []
@@ -705,10 +699,6 @@ class BaseSlurmRunner(BaseRunner):
705
699
  slurm_job_ids=self.job_ids,
706
700
  )
707
701
 
708
- settings = Inject(get_settings)
709
- sleep_time = settings.FRACTAL_SLURM_INTERVAL_BEFORE_RETRIEVAL
710
- logger.warning(f"[multisubmit] Now sleep {sleep_time} seconds.")
711
- time.sleep(sleep_time)
712
702
  except Exception as e:
713
703
  logger.error(
714
704
  "[multisubmit] Unexpected exception during submission."
@@ -148,10 +148,8 @@ def worker(
148
148
  out = cloudpickle.dumps(result)
149
149
 
150
150
  # Write the output pickle file
151
- tempfile = out_fname + ".tmp"
152
- with open(tempfile, "wb") as f:
151
+ with open(out_fname, "wb") as f:
153
152
  f.write(out)
154
- os.rename(tempfile, out_fname)
155
153
 
156
154
 
157
155
  if __name__ == "__main__":
@@ -151,7 +151,7 @@ class SudoSlurmRunner(BaseSlurmRunner):
151
151
  """
152
152
  Fetch artifacts for a list of SLURM jobs.
153
153
  """
154
- MAX_NUM_THREADS = 4
154
+ MAX_NUM_THREADS = 12
155
155
  THREAD_NAME_PREFIX = "fetch_artifacts"
156
156
  logger.debug(
157
157
  "[_fetch_artifacts] START "
@@ -25,7 +25,10 @@ def _remove_suffix(*, string: str, suffix: str) -> str:
25
25
  raise ValueError(f"Cannot remove {suffix=} from {string=}.")
26
26
 
27
27
 
28
- def extract_archive(archive_path: Path):
28
+ def extract_archive(
29
+ archive_path: Path,
30
+ default_logging_level: int | None = None,
31
+ ):
29
32
  """
30
33
  Extract e.g. `/path/archive.tar.gz` archive into `/path/archive` folder
31
34
 
@@ -34,10 +37,14 @@ def extract_archive(archive_path: Path):
34
37
 
35
38
  Arguments:
36
39
  archive_path: Absolute path to the archive file.
40
+ default_logging_level
37
41
  """
38
42
 
39
43
  logger_name = "extract_archive"
40
- logger = set_logger(logger_name)
44
+ logger = set_logger(
45
+ logger_name,
46
+ default_logging_level=default_logging_level,
47
+ )
41
48
 
42
49
  logger.debug("START")
43
50
  logger.debug(f"{archive_path.as_posix()=}")
@@ -65,7 +72,10 @@ def extract_archive(archive_path: Path):
65
72
  logger.debug("END")
66
73
 
67
74
 
68
- def main(sys_argv: list[str]):
75
+ def main(
76
+ sys_argv: list[str],
77
+ default_logging_level: int | None = None,
78
+ ):
69
79
  help_msg = (
70
80
  "Expected use:\n"
71
81
  "python -m fractal_server.app.runner.extract_archive "
@@ -76,8 +86,14 @@ def main(sys_argv: list[str]):
76
86
  sys.exit(f"Invalid argument.\n{help_msg}\nProvided: {sys_argv[1:]=}")
77
87
  else:
78
88
  tarfile_path = Path(sys_argv[1])
79
- extract_archive(tarfile_path)
89
+ extract_archive(
90
+ tarfile_path,
91
+ default_logging_level=default_logging_level,
92
+ )
80
93
 
81
94
 
82
95
  if __name__ == "__main__":
83
- main(sys.argv)
96
+
97
+ import logging
98
+
99
+ main(sys.argv, default_logging_level=logging.DEBUG)