fractal-server 2.10.4__tar.gz → 2.11.0a0__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 (247) hide show
  1. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/PKG-INFO +1 -1
  2. fractal_server-2.11.0a0/fractal_server/__init__.py +1 -0
  3. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/dataset.py +2 -2
  4. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/status.py +20 -20
  5. fractal_server-2.11.0a0/fractal_server/app/runner/filenames.py +4 -0
  6. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_common.py +4 -4
  7. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/handle_failed_job.py +4 -4
  8. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/__init__.py +10 -65
  9. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local/__init__.py +7 -17
  10. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local_experimental/__init__.py +6 -20
  11. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_slurm_ssh/__init__.py +7 -13
  12. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_slurm_sudo/__init__.py +7 -14
  13. fractal_server-2.11.0a0/fractal_server/app/runner/v2/handle_failed_job.py +59 -0
  14. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/runner.py +32 -40
  15. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/security/__init__.py +5 -0
  16. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/security/signup_email.py +1 -1
  17. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/pyproject.toml +7 -4
  18. fractal_server-2.10.4/fractal_server/__init__.py +0 -1
  19. fractal_server-2.10.4/fractal_server/app/runner/filenames.py +0 -6
  20. fractal_server-2.10.4/fractal_server/app/runner/v2/handle_failed_job.py +0 -158
  21. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/LICENSE +0 -0
  22. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/README.md +0 -0
  23. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/__main__.py +0 -0
  24. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/alembic.ini +0 -0
  25. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/__init__.py +0 -0
  26. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/db/__init__.py +0 -0
  27. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/__init__.py +0 -0
  28. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/linkusergroup.py +0 -0
  29. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/linkuserproject.py +0 -0
  30. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/security.py +0 -0
  31. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/user_settings.py +0 -0
  32. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v1/__init__.py +0 -0
  33. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v1/dataset.py +0 -0
  34. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v1/job.py +0 -0
  35. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v1/project.py +0 -0
  36. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v1/state.py +0 -0
  37. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v1/task.py +0 -0
  38. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v1/workflow.py +0 -0
  39. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/__init__.py +0 -0
  40. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/dataset.py +0 -0
  41. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/job.py +0 -0
  42. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/project.py +0 -0
  43. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/task.py +0 -0
  44. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/task_group.py +0 -0
  45. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/workflow.py +0 -0
  46. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/models/v2/workflowtask.py +0 -0
  47. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/__init__.py +0 -0
  48. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/__init__.py +0 -0
  49. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/v1.py +0 -0
  50. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
  51. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/v2/job.py +0 -0
  52. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/v2/project.py +0 -0
  53. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/v2/task.py +0 -0
  54. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
  55. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
  56. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/__init__.py +0 -0
  57. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/__init__.py +0 -0
  58. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/_aux_functions.py +0 -0
  59. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/job.py +0 -0
  60. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/project.py +0 -0
  61. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/task.py +0 -0
  62. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/task_collection.py +0 -0
  63. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/workflow.py +0 -0
  64. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v1/workflowtask.py +0 -0
  65. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/__init__.py +0 -0
  66. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
  67. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
  68. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
  69. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/dataset.py +0 -0
  70. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/images.py +0 -0
  71. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/job.py +0 -0
  72. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/project.py +0 -0
  73. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/submit.py +0 -0
  74. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/task.py +0 -0
  75. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
  76. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
  77. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/task_group.py +0 -0
  78. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
  79. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/workflow.py +0 -0
  80. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
  81. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
  82. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/__init__.py +0 -0
  83. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
  84. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/current_user.py +0 -0
  85. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/group.py +0 -0
  86. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/login.py +0 -0
  87. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/oauth.py +0 -0
  88. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/register.py +0 -0
  89. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/router.py +0 -0
  90. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/auth/users.py +0 -0
  91. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/aux/__init__.py +0 -0
  92. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/aux/_job.py +0 -0
  93. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/aux/_runner.py +0 -0
  94. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
  95. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/__init__.py +0 -0
  96. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/async_wrap.py +0 -0
  97. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/components.py +0 -0
  98. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/compress_folder.py +0 -0
  99. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/exceptions.py +0 -0
  100. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/__init__.py +0 -0
  101. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/__init__.py +0 -0
  102. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/_batching.py +0 -0
  103. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/_slurm_config.py +0 -0
  104. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/remote.py +0 -0
  105. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/ssh/__init__.py +0 -0
  106. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -0
  107. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -0
  108. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/ssh/executor.py +0 -0
  109. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/sudo/__init__.py +0 -0
  110. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -0
  111. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -0
  112. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/sudo/_subprocess_run_as_user.py +0 -0
  113. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -0
  114. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/executors/slurm/utils_executors.py +0 -0
  115. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/extract_archive.py +0 -0
  116. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/run_subprocess.py +0 -0
  117. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
  118. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/shutdown.py +0 -0
  119. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/task_files.py +0 -0
  120. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/__init__.py +0 -0
  121. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_local/__init__.py +0 -0
  122. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_local/_local_config.py +0 -0
  123. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_local/_submit_setup.py +0 -0
  124. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_local/executor.py +0 -0
  125. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_slurm/__init__.py +0 -0
  126. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_slurm/_submit_setup.py +0 -0
  127. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/_slurm/get_slurm_config.py +0 -0
  128. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v1/common.py +0 -0
  129. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local/_local_config.py +0 -0
  130. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local/_submit_setup.py +0 -0
  131. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local/executor.py +0 -0
  132. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local_experimental/_local_config.py +0 -0
  133. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +0 -0
  134. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_local_experimental/executor.py +0 -0
  135. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_slurm_common/__init__.py +0 -0
  136. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_slurm_common/get_slurm_config.py +0 -0
  137. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -0
  138. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -0
  139. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
  140. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
  141. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/runner_functions.py +0 -0
  142. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
  143. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/v2/task_interface.py +0 -0
  144. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/runner/versions.py +0 -0
  145. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/__init__.py +0 -0
  146. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/_validators.py +0 -0
  147. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/user.py +0 -0
  148. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/user_group.py +0 -0
  149. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/user_settings.py +0 -0
  150. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/__init__.py +0 -0
  151. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/applyworkflow.py +0 -0
  152. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/dataset.py +0 -0
  153. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/dumps.py +0 -0
  154. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/manifest.py +0 -0
  155. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/project.py +0 -0
  156. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/state.py +0 -0
  157. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/task.py +0 -0
  158. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/task_collection.py +0 -0
  159. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v1/workflow.py +0 -0
  160. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/__init__.py +0 -0
  161. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/dataset.py +0 -0
  162. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/dumps.py +0 -0
  163. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/job.py +0 -0
  164. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/manifest.py +0 -0
  165. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/project.py +0 -0
  166. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/status.py +0 -0
  167. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/task.py +0 -0
  168. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/task_collection.py +0 -0
  169. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/task_group.py +0 -0
  170. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/workflow.py +0 -0
  171. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
  172. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/app/user_settings.py +0 -0
  173. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/config.py +0 -0
  174. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/data_migrations/README.md +0 -0
  175. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/data_migrations/tools.py +0 -0
  176. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/gunicorn_fractal.py +0 -0
  177. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/images/__init__.py +0 -0
  178. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/images/models.py +0 -0
  179. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/images/tools.py +0 -0
  180. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/logger.py +0 -0
  181. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/main.py +0 -0
  182. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/env.py +0 -0
  183. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/naming_convention.py +0 -0
  184. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
  185. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
  186. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
  187. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
  188. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
  189. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
  190. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
  191. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
  192. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
  193. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
  194. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
  195. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
  196. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
  197. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
  198. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
  199. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
  200. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
  201. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
  202. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
  203. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
  204. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
  205. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
  206. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
  207. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
  208. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
  209. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
  210. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/py.typed +0 -0
  211. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/ssh/__init__.py +0 -0
  212. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/ssh/_fabric.py +0 -0
  213. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/string_tools.py +0 -0
  214. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/syringe.py +0 -0
  215. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/__init__.py +0 -0
  216. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/utils.py +0 -0
  217. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v1/_TaskCollectPip.py +0 -0
  218. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v1/__init__.py +0 -0
  219. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v1/background_operations.py +0 -0
  220. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v1/endpoint_operations.py +0 -0
  221. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v1/get_collection_data.py +0 -0
  222. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v1/utils.py +0 -0
  223. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/__init__.py +0 -0
  224. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/local/__init__.py +0 -0
  225. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/local/_utils.py +0 -0
  226. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/local/collect.py +0 -0
  227. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/local/deactivate.py +0 -0
  228. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/local/reactivate.py +0 -0
  229. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
  230. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
  231. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/ssh/collect.py +0 -0
  232. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
  233. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
  234. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
  235. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
  236. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
  237. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
  238. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
  239. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
  240. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/utils_background.py +0 -0
  241. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/utils_database.py +0 -0
  242. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/utils_package_names.py +0 -0
  243. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
  244. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/tasks/v2/utils_templates.py +0 -0
  245. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/urls.py +0 -0
  246. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/fractal_server/utils.py +0 -0
  247. {fractal_server-2.10.4 → fractal_server-2.11.0a0}/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.10.4
3
+ Version: 2.11.0a0
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  Home-page: https://github.com/fractal-analytics-platform/fractal-server
6
6
  License: BSD-3-Clause
@@ -0,0 +1 @@
1
+ __VERSION__ = "2.11.0a0"
@@ -17,7 +17,7 @@ from ....models.v1 import ApplyWorkflow
17
17
  from ....models.v1 import Dataset
18
18
  from ....models.v1 import Project
19
19
  from ....models.v1 import Resource
20
- from ....runner.filenames import HISTORY_FILENAME
20
+ from ....runner.filenames import HISTORY_FILENAME_V1
21
21
  from ....schemas.v1 import DatasetCreateV1
22
22
  from ....schemas.v1 import DatasetReadV1
23
23
  from ....schemas.v1 import DatasetStatusReadV1
@@ -511,7 +511,7 @@ async def get_workflowtask_status(
511
511
  # Highest priority: Read status updates coming from the running-job
512
512
  # temporary file. Note: this file only contains information on
513
513
  # WorkflowTask's that ran through successfully
514
- tmp_file = Path(running_job.working_dir) / HISTORY_FILENAME
514
+ tmp_file = Path(running_job.working_dir) / HISTORY_FILENAME_V1
515
515
  try:
516
516
  with tmp_file.open("r") as f:
517
517
  history = json.load(f)
@@ -1,5 +1,3 @@
1
- import json
2
- from pathlib import Path
3
1
  from typing import Optional
4
2
 
5
3
  from fastapi import APIRouter
@@ -18,7 +16,6 @@ from ._aux_functions import _get_submitted_jobs_statement
18
16
  from ._aux_functions import _get_workflow_check_owner
19
17
  from fractal_server.app.models import UserOAuth
20
18
  from fractal_server.app.routes.auth import current_active_user
21
- from fractal_server.app.runner.filenames import HISTORY_FILENAME
22
19
 
23
20
  router = APIRouter()
24
21
 
@@ -98,8 +95,8 @@ async def get_workflowtask_status(
98
95
  if running_job is None:
99
96
  # If no job is running, the chronological-last history item is also the
100
97
  # positional-last workflow task to be included in the response.
101
- if len(dataset.history) > 0:
102
- last_valid_wftask_id = dataset.history[-1]["workflowtask"]["id"]
98
+ if len(history) > 0:
99
+ last_valid_wftask_id = history[-1]["workflowtask"]["id"]
103
100
  else:
104
101
  last_valid_wftask_id = None
105
102
  else:
@@ -109,7 +106,24 @@ async def get_workflowtask_status(
109
106
  # as "submitted"
110
107
  start = running_job.first_task_index
111
108
  end = running_job.last_task_index + 1
112
- for wftask in workflow.task_list[start:end]:
109
+
110
+ running_job_wftasks = workflow.task_list[start:end]
111
+ running_job_statuses = [
112
+ workflow_tasks_status_dict.get(wft.id, None)
113
+ for wft in running_job_wftasks
114
+ ]
115
+ try:
116
+ first_submitted_index = running_job_statuses.index(
117
+ WorkflowTaskStatusTypeV2.SUBMITTED
118
+ )
119
+ except ValueError:
120
+ logger.warning(
121
+ f"Job {running_job.id} is submitted but its task list does "
122
+ f"not contain a {WorkflowTaskStatusTypeV2.SUBMITTED} task."
123
+ )
124
+ first_submitted_index = 0
125
+
126
+ for wftask in running_job_wftasks[first_submitted_index:]:
113
127
  workflow_tasks_status_dict[
114
128
  wftask.id
115
129
  ] = WorkflowTaskStatusTypeV2.SUBMITTED
@@ -133,20 +147,6 @@ async def get_workflowtask_status(
133
147
  last_valid_wftask_id = None
134
148
  logger.warning(f"Now setting {last_valid_wftask_id=}.")
135
149
 
136
- # Highest priority: Read status updates coming from the running-job
137
- # temporary file. Note: this file only contains information on
138
- # WorkflowTask's that ran through successfully.
139
- tmp_file = Path(running_job.working_dir) / HISTORY_FILENAME
140
- try:
141
- with tmp_file.open("r") as f:
142
- history = json.load(f)
143
- except FileNotFoundError:
144
- history = []
145
- for history_item in history:
146
- wftask_id = history_item["workflowtask"]["id"]
147
- wftask_status = history_item["status"]
148
- workflow_tasks_status_dict[wftask_id] = wftask_status
149
-
150
150
  # Based on previously-gathered information, clean up the response body
151
151
  clean_workflow_tasks_status_dict = {}
152
152
  for wf_task in workflow.task_list:
@@ -0,0 +1,4 @@
1
+ HISTORY_FILENAME_V1 = "history.json"
2
+ METADATA_FILENAME_V1 = "metadata.json"
3
+ SHUTDOWN_FILENAME = "shutdown"
4
+ WORKFLOW_LOG_FILENAME = "workflow.log"
@@ -28,8 +28,8 @@ from ..exceptions import JobExecutionError
28
28
  from ..exceptions import TaskExecutionError
29
29
  from .common import TaskParameters
30
30
  from .common import write_args_file
31
- from fractal_server.app.runner.filenames import HISTORY_FILENAME
32
- from fractal_server.app.runner.filenames import METADATA_FILENAME
31
+ from fractal_server.app.runner.filenames import HISTORY_FILENAME_V1
32
+ from fractal_server.app.runner.filenames import METADATA_FILENAME_V1
33
33
  from fractal_server.app.runner.task_files import get_task_file_paths
34
34
  from fractal_server.string_tools import validate_cmd
35
35
 
@@ -610,11 +610,11 @@ def execute_tasks(
610
610
  )
611
611
 
612
612
  # Write most recent metadata to METADATA_FILENAME
613
- with open(workflow_dir_local / METADATA_FILENAME, "w") as f:
613
+ with open(workflow_dir_local / METADATA_FILENAME_V1, "w") as f:
614
614
  json.dump(current_task_pars.metadata, f, indent=2)
615
615
 
616
616
  # Write most recent metadata to HISTORY_FILENAME
617
- with open(workflow_dir_local / HISTORY_FILENAME, "w") as f:
617
+ with open(workflow_dir_local / HISTORY_FILENAME_V1, "w") as f:
618
618
  json.dump(current_task_pars.history, f, indent=2)
619
619
 
620
620
  return current_task_pars
@@ -24,8 +24,8 @@ from ...models.v1 import Dataset
24
24
  from ...models.v1 import Workflow
25
25
  from ...models.v1 import WorkflowTask
26
26
  from ...schemas.v1 import WorkflowTaskStatusTypeV1
27
- from ..filenames import HISTORY_FILENAME
28
- from ..filenames import METADATA_FILENAME
27
+ from ..filenames import HISTORY_FILENAME_V1
28
+ from ..filenames import METADATA_FILENAME_V1
29
29
 
30
30
 
31
31
  def assemble_history_failed_job(
@@ -64,7 +64,7 @@ def assemble_history_failed_job(
64
64
  new_history = output_dataset.history
65
65
 
66
66
  # Part 2: Extend history based on tmp_metadata_file
67
- tmp_history_file = Path(job.working_dir) / HISTORY_FILENAME
67
+ tmp_history_file = Path(job.working_dir) / HISTORY_FILENAME_V1
68
68
  try:
69
69
  with tmp_history_file.open("r") as f:
70
70
  tmp_file_history = json.load(f)
@@ -129,7 +129,7 @@ def assemble_meta_failed_job(
129
129
  """
130
130
 
131
131
  new_meta = deepcopy(output_dataset.meta)
132
- metadata_file = Path(job.working_dir) / METADATA_FILENAME
132
+ metadata_file = Path(job.working_dir) / METADATA_FILENAME_V1
133
133
  try:
134
134
  with metadata_file.open("r") as f:
135
135
  metadata_update = json.load(f)
@@ -11,7 +11,6 @@ from pathlib import Path
11
11
  from typing import Optional
12
12
 
13
13
  from sqlalchemy.orm import Session as DBSyncSession
14
- from sqlalchemy.orm.attributes import flag_modified
15
14
 
16
15
  from ....config import get_settings
17
16
  from ....logger import get_logger
@@ -24,7 +23,6 @@ from ....zip_tools import _zip_folder_to_file_and_remove
24
23
  from ...db import DB
25
24
  from ...models.v2 import DatasetV2
26
25
  from ...models.v2 import JobV2
27
- from ...models.v2 import WorkflowTaskV2
28
26
  from ...models.v2 import WorkflowV2
29
27
  from ...schemas.v2 import JobStatusTypeV2
30
28
  from ..exceptions import JobExecutionError
@@ -38,12 +36,11 @@ from ._local_experimental import (
38
36
  )
39
37
  from ._slurm_ssh import process_workflow as slurm_ssh_process_workflow
40
38
  from ._slurm_sudo import process_workflow as slurm_sudo_process_workflow
41
- from .handle_failed_job import assemble_filters_failed_job
42
- from .handle_failed_job import assemble_history_failed_job
43
- from .handle_failed_job import assemble_images_failed_job
39
+ from .handle_failed_job import mark_last_wftask_as_failed
44
40
  from fractal_server import __VERSION__
45
41
  from fractal_server.app.models import UserSettings
46
42
 
43
+
47
44
  _backends = {}
48
45
  _backends["local"] = local_process_workflow
49
46
  _backends["slurm"] = slurm_sudo_process_workflow
@@ -115,7 +112,6 @@ async def submit_workflow(
115
112
  logger = set_logger(logger_name=logger_name)
116
113
 
117
114
  with next(DB.get_sync_db()) as db_sync:
118
-
119
115
  try:
120
116
  job: Optional[JobV2] = db_sync.get(JobV2, job_id)
121
117
  dataset: Optional[DatasetV2] = db_sync.get(DatasetV2, dataset_id)
@@ -322,7 +318,7 @@ async def submit_workflow(
322
318
  db_sync = next(DB.get_sync_db())
323
319
  db_sync.close()
324
320
 
325
- new_dataset_attributes = await process_workflow(
321
+ await process_workflow(
326
322
  workflow=workflow,
327
323
  dataset=dataset,
328
324
  workflow_dir_local=WORKFLOW_DIR_LOCAL,
@@ -340,14 +336,6 @@ async def submit_workflow(
340
336
  )
341
337
  logger.debug(f'END workflow "{workflow.name}"')
342
338
 
343
- # Update dataset attributes, in case of successful execution
344
- dataset.history.extend(new_dataset_attributes["history"])
345
- dataset.filters = new_dataset_attributes["filters"]
346
- dataset.images = new_dataset_attributes["images"]
347
- for attribute_name in ["filters", "history", "images"]:
348
- flag_modified(dataset, attribute_name)
349
- db_sync.merge(dataset)
350
-
351
339
  # Update job DB entry
352
340
  job.status = JobStatusTypeV2.DONE
353
341
  job.end_timestamp = get_timestamp()
@@ -358,28 +346,13 @@ async def submit_workflow(
358
346
  db_sync.commit()
359
347
 
360
348
  except TaskExecutionError as e:
361
-
362
349
  logger.debug(f'FAILED workflow "{workflow.name}", TaskExecutionError.')
363
350
  logger.info(f'Workflow "{workflow.name}" failed (TaskExecutionError).')
364
351
 
365
- # Read dataset attributes produced by the last successful task, and
366
- # update the DB dataset accordingly
367
- failed_wftask = db_sync.get(WorkflowTaskV2, e.workflow_task_id)
368
- dataset.history = assemble_history_failed_job(
369
- job,
370
- dataset,
371
- workflow,
352
+ mark_last_wftask_as_failed(
353
+ dataset_id=dataset_id,
372
354
  logger_name=logger_name,
373
- failed_wftask=failed_wftask,
374
355
  )
375
- latest_filters = assemble_filters_failed_job(job)
376
- if latest_filters is not None:
377
- dataset.filters = latest_filters
378
- latest_images = assemble_images_failed_job(job)
379
- if latest_images is not None:
380
- dataset.images = latest_images
381
- db_sync.merge(dataset)
382
-
383
356
  exception_args_string = "\n".join(e.args)
384
357
  log_msg = (
385
358
  f"TASK ERROR: "
@@ -390,26 +363,12 @@ async def submit_workflow(
390
363
  fail_job(db=db_sync, job=job, log_msg=log_msg, logger_name=logger_name)
391
364
 
392
365
  except JobExecutionError as e:
393
-
394
366
  logger.debug(f'FAILED workflow "{workflow.name}", JobExecutionError.')
395
367
  logger.info(f'Workflow "{workflow.name}" failed (JobExecutionError).')
396
-
397
- # Read dataset attributes produced by the last successful task, and
398
- # update the DB dataset accordingly
399
- dataset.history = assemble_history_failed_job(
400
- job,
401
- dataset,
402
- workflow,
368
+ mark_last_wftask_as_failed(
369
+ dataset_id=dataset_id,
403
370
  logger_name=logger_name,
404
371
  )
405
- latest_filters = assemble_filters_failed_job(job)
406
- if latest_filters is not None:
407
- dataset.filters = latest_filters
408
- latest_images = assemble_images_failed_job(job)
409
- if latest_images is not None:
410
- dataset.images = latest_images
411
- db_sync.merge(dataset)
412
-
413
372
  fail_job(
414
373
  db=db_sync,
415
374
  job=job,
@@ -421,27 +380,13 @@ async def submit_workflow(
421
380
  )
422
381
 
423
382
  except Exception:
424
-
425
383
  logger.debug(f'FAILED workflow "{workflow.name}", unknown error.')
426
384
  logger.info(f'Workflow "{workflow.name}" failed (unkwnon error).')
427
-
428
- current_traceback = traceback.format_exc()
429
-
430
- # Read dataset attributes produced by the last successful task, and
431
- # update the DB dataset accordingly
432
- dataset.history = assemble_history_failed_job(
433
- job,
434
- dataset,
435
- workflow,
385
+ mark_last_wftask_as_failed(
386
+ dataset_id=dataset_id,
436
387
  logger_name=logger_name,
437
388
  )
438
- latest_filters = assemble_filters_failed_job(job)
439
- if latest_filters is not None:
440
- dataset.filters = latest_filters
441
- latest_images = assemble_images_failed_job(job)
442
- if latest_images is not None:
443
- dataset.images = latest_images
444
- db_sync.merge(dataset)
389
+ current_traceback = traceback.format_exc()
445
390
  fail_job(
446
391
  db=db_sync,
447
392
  job=job,
@@ -39,18 +39,15 @@ def _process_workflow(
39
39
  workflow_dir_local: Path,
40
40
  first_task_index: int,
41
41
  last_task_index: int,
42
- ) -> dict:
42
+ ) -> None:
43
43
  """
44
- Internal processing routine
45
-
46
- Schedules the workflow using a `FractalThreadPoolExecutor`.
44
+ Run the workflow using a `FractalThreadPoolExecutor`.
47
45
  """
48
-
49
46
  with FractalThreadPoolExecutor() as executor:
50
- new_dataset_attributes = execute_tasks_v2(
47
+ execute_tasks_v2(
51
48
  wf_task_list=workflow.task_list[
52
- first_task_index : (last_task_index + 1) # noqa
53
- ], # noqa
49
+ first_task_index : (last_task_index + 1)
50
+ ],
54
51
  dataset=dataset,
55
52
  executor=executor,
56
53
  workflow_dir_local=workflow_dir_local,
@@ -58,7 +55,6 @@ def _process_workflow(
58
55
  logger_name=logger_name,
59
56
  submit_setup_call=_local_submit_setup,
60
57
  )
61
- return new_dataset_attributes
62
58
 
63
59
 
64
60
  async def process_workflow(
@@ -75,7 +71,7 @@ async def process_workflow(
75
71
  slurm_user: Optional[str] = None,
76
72
  slurm_account: Optional[str] = None,
77
73
  worker_init: Optional[str] = None,
78
- ) -> dict:
74
+ ) -> None:
79
75
  """
80
76
  Run a workflow
81
77
 
@@ -127,11 +123,6 @@ async def process_workflow(
127
123
  (positive exit codes).
128
124
  JobExecutionError: wrapper for errors raised by the tasks' executors
129
125
  (negative exit codes).
130
-
131
- Returns:
132
- output_dataset_metadata:
133
- The updated metadata for the dataset, as returned by the last task
134
- of the workflow
135
126
  """
136
127
 
137
128
  if workflow_dir_remote and (workflow_dir_remote != workflow_dir_local):
@@ -148,7 +139,7 @@ async def process_workflow(
148
139
  last_task_index=last_task_index,
149
140
  )
150
141
 
151
- new_dataset_attributes = await async_wrap(_process_workflow)(
142
+ await async_wrap(_process_workflow)(
152
143
  workflow=workflow,
153
144
  dataset=dataset,
154
145
  logger_name=logger_name,
@@ -156,4 +147,3 @@ async def process_workflow(
156
147
  first_task_index=first_task_index,
157
148
  last_task_index=last_task_index,
158
149
  )
159
- return new_dataset_attributes
@@ -21,23 +21,17 @@ def _process_workflow(
21
21
  workflow_dir_local: Path,
22
22
  first_task_index: int,
23
23
  last_task_index: int,
24
- ) -> dict:
24
+ ) -> None:
25
25
  """
26
- Internal processing routine
27
-
28
- Schedules the workflow using a `FractalProcessPoolExecutor`.
29
-
30
- Cf.
31
- [process_workflow][fractal_server.app.runner.v2._local_experimental.process_workflow]
32
- for the call signature.
26
+ Run the workflow using a `FractalProcessPoolExecutor`.
33
27
  """
34
28
  with FractalProcessPoolExecutor(
35
29
  shutdown_file=workflow_dir_local / SHUTDOWN_FILENAME
36
30
  ) as executor:
37
31
  try:
38
- new_dataset_attributes = execute_tasks_v2(
32
+ execute_tasks_v2(
39
33
  wf_task_list=workflow.task_list[
40
- first_task_index : (last_task_index + 1) # noqa
34
+ first_task_index : (last_task_index + 1)
41
35
  ],
42
36
  dataset=dataset,
43
37
  executor=executor,
@@ -54,8 +48,6 @@ def _process_workflow(
54
48
  )
55
49
  )
56
50
 
57
- return new_dataset_attributes
58
-
59
51
 
60
52
  async def process_workflow(
61
53
  *,
@@ -71,7 +63,7 @@ async def process_workflow(
71
63
  slurm_user: Optional[str] = None,
72
64
  slurm_account: Optional[str] = None,
73
65
  worker_init: Optional[str] = None,
74
- ) -> dict:
66
+ ) -> None:
75
67
  """
76
68
  Run a workflow
77
69
 
@@ -123,11 +115,6 @@ async def process_workflow(
123
115
  (positive exit codes).
124
116
  JobExecutionError: wrapper for errors raised by the tasks' executors
125
117
  (negative exit codes).
126
-
127
- Returns:
128
- output_dataset_metadata:
129
- The updated metadata for the dataset, as returned by the last task
130
- of the workflow
131
118
  """
132
119
 
133
120
  if workflow_dir_remote and (workflow_dir_remote != workflow_dir_local):
@@ -144,7 +131,7 @@ async def process_workflow(
144
131
  last_task_index=last_task_index,
145
132
  )
146
133
 
147
- new_dataset_attributes = await async_wrap(_process_workflow)(
134
+ await async_wrap(_process_workflow)(
148
135
  workflow=workflow,
149
136
  dataset=dataset,
150
137
  logger_name=logger_name,
@@ -152,4 +139,3 @@ async def process_workflow(
152
139
  first_task_index=first_task_index,
153
140
  last_task_index=last_task_index,
154
141
  )
155
- return new_dataset_attributes
@@ -17,7 +17,6 @@ This backend runs fractal workflows in a SLURM cluster using Clusterfutures
17
17
  Executor objects.
18
18
  """
19
19
  from pathlib import Path
20
- from typing import Any
21
20
  from typing import Optional
22
21
  from typing import Union
23
22
 
@@ -47,16 +46,13 @@ def _process_workflow(
47
46
  last_task_index: int,
48
47
  fractal_ssh: FractalSSH,
49
48
  worker_init: Optional[Union[str, list[str]]] = None,
50
- ) -> dict[str, Any]:
49
+ ) -> None:
51
50
  """
52
- Internal processing routine for the SLURM backend
51
+ Run the workflow using a `FractalSlurmSSHExecutor`.
53
52
 
54
53
  This function initialises the a FractalSlurmExecutor, setting logging,
55
54
  workflow working dir and user to impersonate. It then schedules the
56
55
  workflow tasks and returns the new dataset attributes
57
-
58
- Returns:
59
- new_dataset_attributes:
60
56
  """
61
57
 
62
58
  if isinstance(worker_init, str):
@@ -80,10 +76,10 @@ def _process_workflow(
80
76
  workflow_dir_remote=workflow_dir_remote,
81
77
  common_script_lines=worker_init,
82
78
  ) as executor:
83
- new_dataset_attributes = execute_tasks_v2(
79
+ execute_tasks_v2(
84
80
  wf_task_list=workflow.task_list[
85
- first_task_index : (last_task_index + 1) # noqa
86
- ], # noqa
81
+ first_task_index : (last_task_index + 1)
82
+ ],
87
83
  dataset=dataset,
88
84
  executor=executor,
89
85
  workflow_dir_local=workflow_dir_local,
@@ -91,7 +87,6 @@ def _process_workflow(
91
87
  logger_name=logger_name,
92
88
  submit_setup_call=_slurm_submit_setup,
93
89
  )
94
- return new_dataset_attributes
95
90
 
96
91
 
97
92
  async def process_workflow(
@@ -109,7 +104,7 @@ async def process_workflow(
109
104
  slurm_user: Optional[str] = None,
110
105
  slurm_account: Optional[str] = None,
111
106
  worker_init: Optional[str] = None,
112
- ) -> dict:
107
+ ) -> None:
113
108
  """
114
109
  Process workflow (SLURM backend public interface)
115
110
  """
@@ -122,7 +117,7 @@ async def process_workflow(
122
117
  last_task_index=last_task_index,
123
118
  )
124
119
 
125
- new_dataset_attributes = await async_wrap(_process_workflow)(
120
+ await async_wrap(_process_workflow)(
126
121
  workflow=workflow,
127
122
  dataset=dataset,
128
123
  logger_name=logger_name,
@@ -133,4 +128,3 @@ async def process_workflow(
133
128
  worker_init=worker_init,
134
129
  fractal_ssh=fractal_ssh,
135
130
  )
136
- return new_dataset_attributes
@@ -17,7 +17,6 @@ This backend runs fractal workflows in a SLURM cluster using Clusterfutures
17
17
  Executor objects.
18
18
  """
19
19
  from pathlib import Path
20
- from typing import Any
21
20
  from typing import Optional
22
21
  from typing import Union
23
22
 
@@ -43,16 +42,13 @@ def _process_workflow(
43
42
  slurm_account: Optional[str] = None,
44
43
  user_cache_dir: str,
45
44
  worker_init: Optional[Union[str, list[str]]] = None,
46
- ) -> dict[str, Any]:
45
+ ) -> None:
47
46
  """
48
- Internal processing routine for the SLURM backend
47
+ Run the workflow using a `FractalSlurmExecutor`.
49
48
 
50
49
  This function initialises the a FractalSlurmExecutor, setting logging,
51
50
  workflow working dir and user to impersonate. It then schedules the
52
51
  workflow tasks and returns the new dataset attributes
53
-
54
- Returns:
55
- new_dataset_attributes:
56
52
  """
57
53
 
58
54
  if not slurm_user:
@@ -73,10 +69,10 @@ def _process_workflow(
73
69
  common_script_lines=worker_init,
74
70
  slurm_account=slurm_account,
75
71
  ) as executor:
76
- new_dataset_attributes = execute_tasks_v2(
72
+ execute_tasks_v2(
77
73
  wf_task_list=workflow.task_list[
78
- first_task_index : (last_task_index + 1) # noqa
79
- ], # noqa
74
+ first_task_index : (last_task_index + 1)
75
+ ],
80
76
  dataset=dataset,
81
77
  executor=executor,
82
78
  workflow_dir_local=workflow_dir_local,
@@ -84,7 +80,6 @@ def _process_workflow(
84
80
  logger_name=logger_name,
85
81
  submit_setup_call=_slurm_submit_setup,
86
82
  )
87
- return new_dataset_attributes
88
83
 
89
84
 
90
85
  async def process_workflow(
@@ -101,7 +96,7 @@ async def process_workflow(
101
96
  slurm_user: Optional[str] = None,
102
97
  slurm_account: Optional[str] = None,
103
98
  worker_init: Optional[str] = None,
104
- ) -> dict:
99
+ ) -> None:
105
100
  """
106
101
  Process workflow (SLURM backend public interface).
107
102
  """
@@ -113,8 +108,7 @@ async def process_workflow(
113
108
  first_task_index=first_task_index,
114
109
  last_task_index=last_task_index,
115
110
  )
116
-
117
- new_dataset_attributes = await async_wrap(_process_workflow)(
111
+ await async_wrap(_process_workflow)(
118
112
  workflow=workflow,
119
113
  dataset=dataset,
120
114
  logger_name=logger_name,
@@ -127,4 +121,3 @@ async def process_workflow(
127
121
  slurm_account=slurm_account,
128
122
  worker_init=worker_init,
129
123
  )
130
- return new_dataset_attributes
@@ -0,0 +1,59 @@
1
+ # Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
2
+ # University of Zurich
3
+ #
4
+ # Original authors:
5
+ # Tommaso Comparin <tommaso.comparin@exact-lab.it>
6
+ # Marco Franzon <marco.franzon@exact-lab.it>
7
+ #
8
+ # This file is part of Fractal and was originally developed by eXact lab S.r.l.
9
+ # <exact-lab.it> under contract with Liberali Lab from the Friedrich Miescher
10
+ # Institute for Biomedical Research and Pelkmans Lab from the University of
11
+ # Zurich.
12
+ """
13
+ Helper functions to handle Dataset history.
14
+ """
15
+ import logging
16
+
17
+ from sqlalchemy.orm.attributes import flag_modified
18
+
19
+ from ...models.v2 import DatasetV2
20
+ from ...schemas.v2 import WorkflowTaskStatusTypeV2
21
+ from fractal_server.app.db import get_sync_db
22
+
23
+
24
+ def mark_last_wftask_as_failed(
25
+ dataset_id: int,
26
+ logger_name: str,
27
+ ) -> None:
28
+ """
29
+ Edit dataset history, by marking last item as failed.
30
+
31
+ Args:
32
+ dataset: The `DatasetV2` object
33
+ logger_name: A logger name.
34
+ """
35
+
36
+ logger = logging.getLogger(logger_name)
37
+ with next(get_sync_db()) as db:
38
+ db_dataset = db.get(DatasetV2, dataset_id)
39
+ if len(db_dataset.history) == 0:
40
+ logger.warning(
41
+ f"History for {dataset_id=} is empty. Likely reason: the job "
42
+ "failed before its first task was marked as SUBMITTED. "
43
+ "Continue."
44
+ )
45
+ return
46
+ workflowtask_id = db_dataset.history[-1]["workflowtask"]["id"]
47
+ last_item_status = db_dataset.history[-1]["status"]
48
+ if last_item_status != WorkflowTaskStatusTypeV2.SUBMITTED:
49
+ logger.warning(
50
+ "Unexpected branch: "
51
+ f"Last history item, for {workflowtask_id=}, "
52
+ f"has status {last_item_status}. Skip."
53
+ )
54
+ return
55
+ logger.info(f"Setting history item for {workflowtask_id=} to failed.")
56
+ db_dataset.history[-1]["status"] = WorkflowTaskStatusTypeV2.FAILED
57
+ flag_modified(db_dataset, "history")
58
+ db.merge(db_dataset)
59
+ db.commit()