fractal-server 2.14.0a27__tar.gz → 2.14.0a29__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 (216) hide show
  1. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/PKG-INFO +1 -1
  2. fractal_server-2.14.0a29/fractal_server/__init__.py +1 -0
  3. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/history.py +1 -0
  4. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/history.py +5 -0
  5. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/verify_image_types.py +1 -1
  6. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/local/runner.py +1 -6
  7. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/_slurm_config.py +1 -3
  8. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +4 -13
  9. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/remote.py +1 -1
  10. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_ssh/runner.py +1 -2
  11. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_sudo/runner.py +4 -1
  12. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/_local.py +2 -0
  13. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/_slurm_ssh.py +2 -0
  14. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/_slurm_sudo.py +2 -0
  15. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/db_tools.py +17 -4
  16. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/runner.py +6 -0
  17. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/runner_functions.py +36 -8
  18. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/runner_functions_low_level.py +2 -3
  19. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/submit_workflow.py +1 -0
  20. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/history.py +1 -0
  21. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/config.py +1 -1
  22. fractal_server-2.14.0a29/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +41 -0
  23. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/pyproject.toml +2 -2
  24. fractal_server-2.14.0a27/fractal_server/__init__.py +0 -1
  25. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/LICENSE +0 -0
  26. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/README.md +0 -0
  27. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/__main__.py +0 -0
  28. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/alembic.ini +0 -0
  29. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/__init__.py +0 -0
  30. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/db/__init__.py +0 -0
  31. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/history/__init__.py +0 -0
  32. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/__init__.py +0 -0
  33. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/linkusergroup.py +0 -0
  34. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/linkuserproject.py +0 -0
  35. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/security.py +0 -0
  36. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/user_settings.py +0 -0
  37. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/__init__.py +0 -0
  38. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/accounting.py +0 -0
  39. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/dataset.py +0 -0
  40. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/job.py +0 -0
  41. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/project.py +0 -0
  42. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/task.py +0 -0
  43. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/task_group.py +0 -0
  44. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/workflow.py +0 -0
  45. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/models/v2/workflowtask.py +0 -0
  46. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/__init__.py +0 -0
  47. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/__init__.py +0 -0
  48. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
  49. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
  50. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
  51. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/job.py +0 -0
  52. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/project.py +0 -0
  53. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/task.py +0 -0
  54. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
  55. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
  56. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/__init__.py +0 -0
  57. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/__init__.py +0 -0
  58. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
  59. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
  60. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
  61. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
  62. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/dataset.py +0 -0
  63. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/images.py +0 -0
  64. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/job.py +0 -0
  65. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/project.py +0 -0
  66. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/status_legacy.py +0 -0
  67. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/submit.py +0 -0
  68. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/task.py +0 -0
  69. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
  70. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
  71. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/task_group.py +0 -0
  72. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
  73. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/workflow.py +0 -0
  74. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
  75. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
  76. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/__init__.py +0 -0
  77. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
  78. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/current_user.py +0 -0
  79. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/group.py +0 -0
  80. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/login.py +0 -0
  81. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/oauth.py +0 -0
  82. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/register.py +0 -0
  83. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/router.py +0 -0
  84. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/auth/users.py +0 -0
  85. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/aux/__init__.py +0 -0
  86. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/aux/_job.py +0 -0
  87. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/aux/_runner.py +0 -0
  88. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
  89. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/routes/pagination.py +0 -0
  90. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/__init__.py +0 -0
  91. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/components.py +0 -0
  92. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/compress_folder.py +0 -0
  93. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/exceptions.py +0 -0
  94. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/__init__.py +0 -0
  95. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/base_runner.py +0 -0
  96. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/local/__init__.py +0 -0
  97. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/local/get_local_config.py +0 -0
  98. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/__init__.py +0 -0
  99. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/_batching.py +0 -0
  100. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/_job_states.py +0 -0
  101. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +0 -0
  102. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
  103. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_common/utils_executors.py +0 -0
  104. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_ssh/__init__.py +0 -0
  105. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
  106. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
  107. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/extract_archive.py +0 -0
  108. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/filenames.py +0 -0
  109. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/run_subprocess.py +0 -0
  110. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
  111. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/shutdown.py +0 -0
  112. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/task_files.py +0 -0
  113. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/__init__.py +0 -0
  114. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
  115. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
  116. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/v2/task_interface.py +0 -0
  117. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/runner/versions.py +0 -0
  118. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/__init__.py +0 -0
  119. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/_filter_validators.py +0 -0
  120. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/_validators.py +0 -0
  121. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/user.py +0 -0
  122. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/user_group.py +0 -0
  123. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/user_settings.py +0 -0
  124. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/__init__.py +0 -0
  125. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/accounting.py +0 -0
  126. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/dataset.py +0 -0
  127. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/dumps.py +0 -0
  128. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/job.py +0 -0
  129. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/manifest.py +0 -0
  130. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/project.py +0 -0
  131. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
  132. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/task.py +0 -0
  133. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/task_collection.py +0 -0
  134. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/task_group.py +0 -0
  135. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/workflow.py +0 -0
  136. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
  137. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/security/__init__.py +0 -0
  138. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/security/signup_email.py +0 -0
  139. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/app/user_settings.py +0 -0
  140. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/data_migrations/README.md +0 -0
  141. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/data_migrations/tools.py +0 -0
  142. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/gunicorn_fractal.py +0 -0
  143. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/images/__init__.py +0 -0
  144. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/images/models.py +0 -0
  145. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/images/tools.py +0 -0
  146. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/logger.py +0 -0
  147. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/main.py +0 -0
  148. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/env.py +0 -0
  149. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/naming_convention.py +0 -0
  150. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
  151. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
  152. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
  153. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
  154. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
  155. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
  156. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
  157. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
  158. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
  159. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
  160. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
  161. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
  162. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
  163. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
  164. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
  165. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
  166. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
  167. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
  168. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
  169. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
  170. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
  171. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
  172. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
  173. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
  174. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
  175. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
  176. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
  177. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
  178. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
  179. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
  180. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
  181. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
  182. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +0 -0
  183. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
  184. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
  185. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/py.typed +0 -0
  186. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/ssh/__init__.py +0 -0
  187. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/ssh/_fabric.py +0 -0
  188. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/string_tools.py +0 -0
  189. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/syringe.py +0 -0
  190. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/__init__.py +0 -0
  191. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/utils.py +0 -0
  192. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/__init__.py +0 -0
  193. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/local/__init__.py +0 -0
  194. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/local/_utils.py +0 -0
  195. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/local/collect.py +0 -0
  196. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/local/deactivate.py +0 -0
  197. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/local/reactivate.py +0 -0
  198. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
  199. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
  200. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/ssh/collect.py +0 -0
  201. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
  202. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
  203. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
  204. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
  205. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
  206. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
  207. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
  208. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
  209. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/utils_background.py +0 -0
  210. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/utils_database.py +0 -0
  211. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/utils_package_names.py +0 -0
  212. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
  213. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/tasks/v2/utils_templates.py +0 -0
  214. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/urls.py +0 -0
  215. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/fractal_server/utils.py +0 -0
  216. {fractal_server-2.14.0a27 → fractal_server-2.14.0a29}/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.0a27
3
+ Version: 2.14.0a29
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.0a29"
@@ -27,6 +27,7 @@ class HistoryRun(SQLModel, table=True):
27
27
  default=None,
28
28
  ondelete="SET NULL",
29
29
  )
30
+ job_id: int = Field(foreign_key="jobv2.id")
30
31
 
31
32
  workflowtask_dump: dict[str, Any] = Field(
32
33
  sa_column=Column(JSONB, nullable=False),
@@ -142,6 +142,11 @@ async def get_workflow_tasks_statuses(
142
142
  value["num_available_images"] = None
143
143
  new_response[key] = value
144
144
 
145
+ for wftask in workflow.task_list:
146
+ logger.debug(
147
+ f"({dataset_id=}, {wftask.id=}): {new_response[wftask.id]}"
148
+ )
149
+
145
150
  return JSONResponse(content=new_response, status_code=200)
146
151
 
147
152
 
@@ -42,7 +42,7 @@ async def verify_unique_types(
42
42
  type_filters=query.type_filters,
43
43
  )
44
44
 
45
- # Get all available types (#FIXME use aux function)
45
+ # NOTE: see issue 2486
46
46
  available_types = set(
47
47
  _type for _img in filtered_images for _type in _img["types"].keys()
48
48
  )
@@ -25,7 +25,6 @@ class LocalRunner(BaseRunner):
25
25
  self,
26
26
  root_dir_local: Path,
27
27
  ):
28
-
29
28
  self.root_dir_local = root_dir_local
30
29
  self.root_dir_local.mkdir(parents=True, exist_ok=True)
31
30
  self.executor = ThreadPoolExecutor()
@@ -182,10 +181,6 @@ class LocalRunner(BaseRunner):
182
181
  db_sync=db,
183
182
  )
184
183
 
185
- # FIXME: what should happen here? Option 1: stop
186
- # all existing tasks and shutdown runner (for the
187
- # compound-task case)
188
-
189
- logger.debug(f"[multisubmit] END, {results=}, {exceptions=}")
184
+ logger.debug(f"[multisubmit] END, {len(results)=}, {len(exceptions)=}")
190
185
 
191
186
  return results, exceptions
@@ -368,9 +368,7 @@ class SlurmConfig(BaseModel):
368
368
  if value is not None:
369
369
  # Handle the `time` parameter
370
370
  if key == "time" and self.parallel_tasks_per_job > 1:
371
- # FIXME SSH: time setting must be handled better. Right now
372
- # we simply propagate `time`, but this is not enough when
373
- # several `srun` are combined in a single script.
371
+ # NOTE: see issue #1632
374
372
  logger.warning(
375
373
  f"`time` SLURM parameter is set to {self.time}, "
376
374
  "but this does not take into account the number of "
@@ -34,7 +34,7 @@ SHUTDOWN_EXCEPTION = JobExecutionError(SHUTDOWN_ERROR_MESSAGE)
34
34
 
35
35
  logger = set_logger(__name__)
36
36
 
37
- # FIXME: Transform several logger.info into logger.debug.
37
+ # NOTE: see issue 2481.
38
38
 
39
39
 
40
40
  class BaseSlurmRunner(BaseRunner):
@@ -107,8 +107,7 @@ class BaseSlurmRunner(BaseRunner):
107
107
  raise NotImplementedError("Implement in child class.")
108
108
 
109
109
  def run_squeue(self, job_ids: list[str]) -> tuple[bool, str]:
110
-
111
- # FIXME: review different cases (exception vs no job found)
110
+ # NOTE: see issue 2482
112
111
 
113
112
  if len(job_ids) == 0:
114
113
  return (False, "")
@@ -457,7 +456,6 @@ class BaseSlurmRunner(BaseRunner):
457
456
  "converter_compound",
458
457
  ],
459
458
  ) -> tuple[Any, Exception]:
460
-
461
459
  logger.info("[submit] START")
462
460
 
463
461
  workdir_local = task_files.wftask_subfolder_local
@@ -514,7 +512,7 @@ class BaseSlurmRunner(BaseRunner):
514
512
  )
515
513
  logger.info(f"[submit] END submission phase, {self.job_ids=}")
516
514
 
517
- # FIXME: replace this sleep with a more precise check
515
+ # NOTE: see issue 2444
518
516
  settings = Inject(get_settings)
519
517
  sleep_time = settings.FRACTAL_SLURM_INTERVAL_BEFORE_RETRIEVAL
520
518
  logger.warning(f"[submit] Now sleep {sleep_time} seconds.")
@@ -524,7 +522,6 @@ class BaseSlurmRunner(BaseRunner):
524
522
  logger.info("[submit] START retrieval phase")
525
523
  scancelled_job_ids = []
526
524
  while len(self.jobs) > 0:
527
-
528
525
  # Look for finished jobs
529
526
  finished_job_ids = self._get_finished_jobs(job_ids=self.job_ids)
530
527
  logger.debug(f"[submit] {finished_job_ids=}")
@@ -664,9 +661,7 @@ class BaseSlurmRunner(BaseRunner):
664
661
  )
665
662
  )
666
663
 
667
- # FIXME: split parts 2 and 3
668
- # Part 2/3. Transfer all relevant input files (for SSH)
669
- # Part 3/3. Run all `sbatch`es and update `self.jobs`
664
+ # NOTE: see issue 2431
670
665
  logger.info("[multisubmit] Transfer files and submit jobs.")
671
666
  for slurm_job in jobs_to_submit:
672
667
  self._submit_single_sbatch(
@@ -677,19 +672,15 @@ class BaseSlurmRunner(BaseRunner):
677
672
 
678
673
  logger.info(f"END submission phase, {self.job_ids=}")
679
674
 
680
- # FIXME: replace this sleep with a more precise check
681
675
  settings = Inject(get_settings)
682
676
  sleep_time = settings.FRACTAL_SLURM_INTERVAL_BEFORE_RETRIEVAL
683
677
  logger.warning(f"[submit] Now sleep {sleep_time} seconds.")
684
678
  time.sleep(sleep_time)
685
679
 
686
- # FIXME: Could we merge the submit/multisubmit retrieval phases?
687
-
688
680
  # Retrieval phase
689
681
  logger.info("[multisubmit] START retrieval phase")
690
682
  scancelled_job_ids = []
691
683
  while len(self.jobs) > 0:
692
-
693
684
  # Look for finished jobs
694
685
  finished_job_ids = self._get_finished_jobs(job_ids=self.job_ids)
695
686
  logger.debug(f"[multisubmit] {finished_job_ids=}")
@@ -59,7 +59,7 @@ def _check_versions_mismatch(
59
59
  if worker_python_version != server_python_version:
60
60
  # FIXME: turn this into an error, after fixing a broader CI issue, see
61
61
  # https://github.com/fractal-analytics-platform/fractal-server/issues/375
62
- logging.critical(
62
+ logging.warning(
63
63
  f"{server_python_version=} but {worker_python_version=}. "
64
64
  "cloudpickle is not guaranteed to correctly load "
65
65
  "pickle files created with different python versions. "
@@ -90,7 +90,7 @@ class SlurmSSHRunner(BaseSlurmRunner):
90
90
  ).as_posix()
91
91
 
92
92
  # Create file list
93
- # # FIXME can we make this more efficient with iterators?
93
+ # NOTE: see issue 2483
94
94
  filelist = []
95
95
  for _slurm_job in finished_slurm_jobs:
96
96
  _single_job_filelist = [
@@ -168,7 +168,6 @@ class SlurmSSHRunner(BaseSlurmRunner):
168
168
  Transfer the jobs subfolder to the remote host.
169
169
  """
170
170
  for job in jobs:
171
-
172
171
  # Create local archive
173
172
  tarfile_path_local = compress_folder(
174
173
  job.workdir_local,
@@ -133,7 +133,10 @@ class SudoSlurmRunner(BaseSlurmRunner):
133
133
  # Write local file
134
134
  with open(target, "wb") as f:
135
135
  f.write(res.stdout)
136
- logger.critical(f"Copied {source} into {target}")
136
+ logger.debug(
137
+ f"[_fetch_artifacts_single_job] Copied {source} into "
138
+ f"{target}"
139
+ )
137
140
  except RuntimeError as e:
138
141
  logger.warning(
139
142
  f"SKIP copy {source} into {target}. "
@@ -15,6 +15,7 @@ def process_workflow(
15
15
  workflow: WorkflowV2,
16
16
  dataset: DatasetV2,
17
17
  workflow_dir_local: Path,
18
+ job_id: int,
18
19
  workflow_dir_remote: Optional[Path] = None,
19
20
  first_task_index: Optional[int] = None,
20
21
  last_task_index: Optional[int] = None,
@@ -75,6 +76,7 @@ def process_workflow(
75
76
  first_task_index : (last_task_index + 1)
76
77
  ],
77
78
  dataset=dataset,
79
+ job_id=job_id,
78
80
  runner=runner,
79
81
  workflow_dir_local=workflow_dir_local,
80
82
  workflow_dir_remote=workflow_dir_local,
@@ -38,6 +38,7 @@ def process_workflow(
38
38
  workflow: WorkflowV2,
39
39
  dataset: DatasetV2,
40
40
  workflow_dir_local: Path,
41
+ job_id: int,
41
42
  workflow_dir_remote: Optional[Path] = None,
42
43
  first_task_index: Optional[int] = None,
43
44
  last_task_index: Optional[int] = None,
@@ -87,6 +88,7 @@ def process_workflow(
87
88
  first_task_index : (last_task_index + 1)
88
89
  ],
89
90
  dataset=dataset,
91
+ job_id=job_id,
90
92
  runner=runner,
91
93
  workflow_dir_local=workflow_dir_local,
92
94
  workflow_dir_remote=workflow_dir_remote,
@@ -33,6 +33,7 @@ def process_workflow(
33
33
  workflow: WorkflowV2,
34
34
  dataset: DatasetV2,
35
35
  workflow_dir_local: Path,
36
+ job_id: int,
36
37
  workflow_dir_remote: Optional[Path] = None,
37
38
  first_task_index: Optional[int] = None,
38
39
  last_task_index: Optional[int] = None,
@@ -79,6 +80,7 @@ def process_workflow(
79
80
  first_task_index : (last_task_index + 1)
80
81
  ],
81
82
  dataset=dataset,
83
+ job_id=job_id,
82
84
  runner=runner,
83
85
  workflow_dir_local=workflow_dir_local,
84
86
  workflow_dir_remote=workflow_dir_remote,
@@ -8,9 +8,13 @@ from fractal_server.app.models.v2 import HistoryImageCache
8
8
  from fractal_server.app.models.v2 import HistoryRun
9
9
  from fractal_server.app.models.v2 import HistoryUnit
10
10
  from fractal_server.app.schemas.v2 import HistoryUnitStatus
11
+ from fractal_server.logger import set_logger
12
+
11
13
 
12
14
  _CHUNK_SIZE = 2_000
13
15
 
16
+ logger = set_logger(__name__)
17
+
14
18
 
15
19
  def update_status_of_history_run(
16
20
  *,
@@ -46,7 +50,12 @@ def bulk_update_status_of_history_unit(
46
50
  status: HistoryUnitStatus,
47
51
  db_sync: Session,
48
52
  ) -> None:
49
- for ind in range(0, len(history_unit_ids), _CHUNK_SIZE):
53
+
54
+ len_history_unit_ids = len(history_unit_ids)
55
+ logger.debug(
56
+ f"[bulk_update_status_of_history_unit] {len_history_unit_ids=}."
57
+ )
58
+ for ind in range(0, len_history_unit_ids, _CHUNK_SIZE):
50
59
  db_sync.execute(
51
60
  update(HistoryUnit)
52
61
  .where(
@@ -77,7 +86,7 @@ def bulk_upsert_image_cache_fast(
77
86
  See docs at
78
87
  https://docs.sqlalchemy.org/en/20/dialects/postgresql.html#insert-on-conflict-upsert
79
88
 
80
- FIXME: we tried to replace `index_elements` with
89
+ NOTE: we tried to replace `index_elements` with
81
90
  `constraint="pk_historyimagecache"`, but it did not work as expected.
82
91
 
83
92
  Arguments:
@@ -85,10 +94,14 @@ def bulk_upsert_image_cache_fast(
85
94
  List of dictionaries for objects to be upsert-ed.
86
95
  db: A sync database session
87
96
  """
88
- if len(list_upsert_objects) == 0:
97
+ len_list_upsert_objects = len(list_upsert_objects)
98
+
99
+ logger.debug(f"[bulk_upsert_image_cache_fast] {len_list_upsert_objects=}.")
100
+
101
+ if len_list_upsert_objects == 0:
89
102
  return None
90
103
 
91
- for ind in range(0, len(list_upsert_objects), _CHUNK_SIZE):
104
+ for ind in range(0, len_list_upsert_objects, _CHUNK_SIZE):
92
105
  stmt = pg_insert(HistoryImageCache).values(
93
106
  list_upsert_objects[ind : ind + _CHUNK_SIZE]
94
107
  )
@@ -42,6 +42,7 @@ def execute_tasks_v2(
42
42
  runner: BaseRunner,
43
43
  user_id: int,
44
44
  workflow_dir_local: Path,
45
+ job_id: int,
45
46
  workflow_dir_remote: Optional[Path] = None,
46
47
  logger_name: Optional[str] = None,
47
48
  get_runner_config: Callable[
@@ -119,6 +120,7 @@ def execute_tasks_v2(
119
120
  history_run = HistoryRun(
120
121
  dataset_id=dataset.id,
121
122
  workflowtask_id=wftask.id,
123
+ job_id=job_id,
122
124
  workflowtask_dump=workflowtask_dump,
123
125
  task_group_dump=task_group_dump,
124
126
  num_available_images=num_available_images,
@@ -128,6 +130,10 @@ def execute_tasks_v2(
128
130
  db.commit()
129
131
  db.refresh(history_run)
130
132
  history_run_id = history_run.id
133
+ logger.debug(
134
+ "[execute_tasks_v2] Created `HistoryRun` with "
135
+ f"{history_run_id=}."
136
+ )
131
137
 
132
138
  # TASK EXECUTION (V2)
133
139
  if task.type in ["non_parallel", "converter_non_parallel"]:
@@ -50,6 +50,7 @@ class SubmissionOutcome(BaseModel):
50
50
  model_config = ConfigDict(arbitrary_types_allowed=True)
51
51
  task_output: TaskOutput | None = None
52
52
  exception: BaseException | None = None
53
+ invalid_output: bool = False
53
54
 
54
55
 
55
56
  class InitSubmissionOutcome(BaseModel):
@@ -66,6 +67,7 @@ def _process_task_output(
66
67
  result: dict[str, Any] | None = None,
67
68
  exception: BaseException | None = None,
68
69
  ) -> SubmissionOutcome:
70
+ invalid_output = False
69
71
  if exception is not None:
70
72
  task_output = None
71
73
  else:
@@ -75,13 +77,13 @@ def _process_task_output(
75
77
  try:
76
78
  task_output = _cast_and_validate_TaskOutput(result)
77
79
  except TaskOutputValidationError as e:
78
- # FIXME: This should correspond to some status="failed",
79
- # but it does not
80
80
  task_output = None
81
81
  exception = e
82
+ invalid_output = True
82
83
  return SubmissionOutcome(
83
84
  task_output=task_output,
84
85
  exception=exception,
86
+ invalid_output=invalid_output,
85
87
  )
86
88
 
87
89
 
@@ -99,8 +101,6 @@ def _process_init_task_output(
99
101
  try:
100
102
  task_output = _cast_and_validate_InitTaskOutput(result)
101
103
  except TaskOutputValidationError as e:
102
- # FIXME: This should correspond to some status="failed",
103
- # but it does not
104
104
  task_output = None
105
105
  exception = e
106
106
  return InitSubmissionOutcome(
@@ -187,6 +187,10 @@ def run_v2_task_non_parallel(
187
187
  db.add(history_unit)
188
188
  db.commit()
189
189
  db.refresh(history_unit)
190
+ logger.debug(
191
+ "[run_v2_task_non_parallel] Created `HistoryUnit` with "
192
+ f"{history_run_id=}."
193
+ )
190
194
  history_unit_id = history_unit.id
191
195
  bulk_upsert_image_cache_fast(
192
196
  db=db,
@@ -225,6 +229,13 @@ def run_v2_task_non_parallel(
225
229
  exception=exception,
226
230
  )
227
231
  }
232
+ if outcome[0].invalid_output:
233
+ with next(get_sync_db()) as db:
234
+ update_status_of_history_unit(
235
+ history_unit_id=history_unit_id,
236
+ status=HistoryUnitStatus.FAILED,
237
+ db_sync=db,
238
+ )
228
239
  return outcome, num_tasks
229
240
 
230
241
 
@@ -294,6 +305,10 @@ def run_v2_task_parallel(
294
305
  with next(get_sync_db()) as db:
295
306
  db.add_all(history_units)
296
307
  db.commit()
308
+ logger.debug(
309
+ f"[run_v2_task_non_parallel] Created {len(history_units)} "
310
+ "`HistoryUnit`s."
311
+ )
297
312
 
298
313
  for history_unit in history_units:
299
314
  db.refresh(history_unit)
@@ -331,7 +346,6 @@ def run_v2_task_parallel(
331
346
  outcome = {}
332
347
  for ind in range(len(list_function_kwargs)):
333
348
  if ind not in results.keys() and ind not in exceptions.keys():
334
- # FIXME: Could we avoid this branch?
335
349
  error_msg = (
336
350
  f"Invalid branch: {ind=} is not in `results.keys()` "
337
351
  "nor in `exceptions.keys()`."
@@ -342,7 +356,13 @@ def run_v2_task_parallel(
342
356
  result=results.get(ind, None),
343
357
  exception=exceptions.get(ind, None),
344
358
  )
345
-
359
+ if outcome[ind].invalid_output:
360
+ with next(get_sync_db()) as db:
361
+ update_status_of_history_unit(
362
+ history_unit_id=history_unit_ids[ind],
363
+ status=HistoryUnitStatus.FAILED,
364
+ db_sync=db,
365
+ )
346
366
  num_tasks = len(images)
347
367
  return outcome, num_tasks
348
368
 
@@ -407,6 +427,10 @@ def run_v2_task_compound(
407
427
  db.commit()
408
428
  db.refresh(history_unit)
409
429
  init_history_unit_id = history_unit.id
430
+ logger.debug(
431
+ "[run_v2_task_compound] Created `HistoryUnit` with "
432
+ f"{init_history_unit_id=}."
433
+ )
410
434
  # Create one `HistoryImageCache` for each input image
411
435
  bulk_upsert_image_cache_fast(
412
436
  db=db,
@@ -524,6 +548,10 @@ def run_v2_task_compound(
524
548
  db.commit()
525
549
  for history_unit in history_units:
526
550
  db.refresh(history_unit)
551
+ logger.debug(
552
+ f"[run_v2_task_compound] Created {len(history_units)} "
553
+ "`HistoryUnit`s."
554
+ )
527
555
  history_unit_ids = [history_unit.id for history_unit in history_units]
528
556
 
529
557
  results, exceptions = runner.multisubmit(
@@ -545,7 +573,7 @@ def run_v2_task_compound(
545
573
  failure = False
546
574
  for ind in range(len(list_function_kwargs)):
547
575
  if ind not in results.keys() and ind not in exceptions.keys():
548
- # FIXME: Could we avoid this branch?
576
+ # NOTE: see issue 2484
549
577
  error_msg = (
550
578
  f"Invalid branch: {ind=} is not in `results.keys()` "
551
579
  "nor in `exceptions.keys()`."
@@ -556,7 +584,7 @@ def run_v2_task_compound(
556
584
  result=results.get(ind, None),
557
585
  exception=exceptions.get(ind, None),
558
586
  )
559
- if compute_outcomes[ind].exception is not None:
587
+ if compute_outcomes[ind].invalid_output:
560
588
  failure = True
561
589
 
562
590
  # NOTE: For compound tasks, we update `HistoryUnit.status` from here,
@@ -84,13 +84,12 @@ def run_single_task(
84
84
  logger.debug(f"Now start running {command=}")
85
85
 
86
86
  # Write arguments to args.json file
87
- # FIXME: this could be done backend-side, with an additional
88
- # file transfer if needed (e.g. on SSH)
87
+ # NOTE: see issue 2346
89
88
  with open(args_file_remote, "w") as f:
90
89
  json.dump(parameters, f, indent=2)
91
90
 
92
91
  # Assemble full command
93
- # FIXME: this could be assembled backend-side
92
+ # NOTE: this could be assembled backend-side
94
93
  full_command = (
95
94
  f"{command} "
96
95
  f"--args-json {args_file_remote} "
@@ -282,6 +282,7 @@ def submit_workflow(
282
282
  process_workflow(
283
283
  workflow=workflow,
284
284
  dataset=dataset,
285
+ job_id=job_id,
285
286
  user_id=user_id,
286
287
  workflow_dir_local=WORKFLOW_DIR_LOCAL,
287
288
  workflow_dir_remote=WORKFLOW_DIR_REMOTE,
@@ -45,6 +45,7 @@ class HistoryRunRead(BaseModel):
45
45
  id: int
46
46
  dataset_id: int
47
47
  workflowtask_id: Optional[int] = None
48
+ job_id: int
48
49
  workflowtask_dump: dict[str, Any]
49
50
  task_group_dump: dict[str, Any]
50
51
  timestamp_started: AwareDatetime
@@ -494,7 +494,7 @@ class Settings(BaseSettings):
494
494
 
495
495
  FRACTAL_SLURM_INTERVAL_BEFORE_RETRIEVAL: int = 2
496
496
  """
497
- FIXME: this is a workaround, we are still investigating.
497
+ NOTE: see issue 2444
498
498
  """
499
499
 
500
500
  FRACTAL_SLURM_SBATCH_SLEEP: float = 0
@@ -0,0 +1,41 @@
1
+ """job id in history run
2
+
3
+ Revision ID: c90a7c76e996
4
+ Revises: f37aceb45062
5
+ Create Date: 2025-04-16 10:44:30.219309
6
+
7
+ """
8
+ import sqlalchemy as sa
9
+ from alembic import op
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = "c90a7c76e996"
14
+ down_revision = "f37aceb45062"
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ # ### commands auto generated by Alembic - please adjust! ###
21
+ with op.batch_alter_table("historyrun", schema=None) as batch_op:
22
+ batch_op.add_column(sa.Column("job_id", sa.Integer(), nullable=False))
23
+ batch_op.create_foreign_key(
24
+ batch_op.f("fk_historyrun_job_id_jobv2"),
25
+ "jobv2",
26
+ ["job_id"],
27
+ ["id"],
28
+ )
29
+
30
+ # ### end Alembic commands ###
31
+
32
+
33
+ def downgrade() -> None:
34
+ # ### commands auto generated by Alembic - please adjust! ###
35
+ with op.batch_alter_table("historyrun", schema=None) as batch_op:
36
+ batch_op.drop_constraint(
37
+ batch_op.f("fk_historyrun_job_id_jobv2"), type_="foreignkey"
38
+ )
39
+ batch_op.drop_column("job_id")
40
+
41
+ # ### end Alembic commands ###
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fractal-server"
3
- version = "2.14.0a27"
3
+ version = "2.14.0a29"
4
4
  description = "Backend component of the Fractal analytics platform"
5
5
  authors = [
6
6
  { name="Tommaso Comparin", email="tommaso.comparin@exact-lab.it" },
@@ -95,7 +95,7 @@ filterwarnings = [
95
95
  markers = ["container", "ssh"]
96
96
 
97
97
  [tool.bumpver]
98
- current_version = "2.14.0a27"
98
+ current_version = "2.14.0a29"
99
99
  version_pattern = "MAJOR.MINOR.PATCH[PYTAGNUM]"
100
100
  commit_message = "bump version {old_version} -> {new_version}"
101
101
  commit = true
@@ -1 +0,0 @@
1
- __VERSION__ = "2.14.0a27"