fractal-server 2.19.0__tar.gz → 2.19.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 (282) hide show
  1. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/PKG-INFO +2 -2
  2. fractal_server-2.19.0a0/fractal_server/__init__.py +1 -0
  3. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/dataset.py +4 -0
  4. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/job.py +0 -4
  5. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/task.py +1 -0
  6. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/task_group.py +0 -4
  7. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/workflow.py +0 -2
  8. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/workflowtask.py +0 -3
  9. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/task.py +5 -0
  10. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -6
  11. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/__init__.py +2 -0
  12. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +20 -1
  13. fractal_server-2.19.0a0/fractal_server/app/routes/api/v2/status_legacy.py +156 -0
  14. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/submit.py +1 -3
  15. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/task_collection.py +0 -2
  16. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/task_collection_pixi.py +0 -2
  17. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/task_group.py +24 -2
  18. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -6
  19. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/workflow.py +1 -1
  20. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/workflow_import.py +43 -12
  21. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/workflowtask.py +6 -1
  22. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/current_user.py +0 -8
  23. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/__init__.py +1 -0
  24. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/dumps.py +1 -0
  25. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/task.py +5 -0
  26. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/workflow.py +0 -2
  27. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/workflowtask.py +2 -6
  28. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/security/__init__.py +3 -8
  29. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/submit_workflow.py +2 -0
  30. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/pyproject.toml +4 -3
  31. fractal_server-2.19.0/fractal_server/__init__.py +0 -1
  32. fractal_server-2.19.0/fractal_server/app/routes/aux/_versions.py +0 -42
  33. fractal_server-2.19.0/fractal_server/migrations/versions/18a26fcdea5d_drop_dataset_history.py +0 -41
  34. fractal_server-2.19.0/fractal_server/migrations/versions/1bf8785755f9_add_description_to_workflow_and_.py +0 -53
  35. fractal_server-2.19.0/fractal_server/migrations/versions/5fb08bf05b14_drop_taskv2_source.py +0 -36
  36. fractal_server-2.19.0/fractal_server/migrations/versions/cfd13f7954e7_add_fractal_server_version_to_jobv2_and_.py +0 -52
  37. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/LICENSE +0 -0
  38. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/README.md +0 -0
  39. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/__main__.py +0 -0
  40. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/alembic.ini +0 -0
  41. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/__init__.py +0 -0
  42. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/db/__init__.py +0 -0
  43. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/__init__.py +0 -0
  44. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/linkusergroup.py +0 -0
  45. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/linkuserproject.py +0 -0
  46. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/security.py +0 -0
  47. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/__init__.py +0 -0
  48. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/accounting.py +0 -0
  49. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/history.py +0 -0
  50. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/profile.py +0 -0
  51. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/project.py +0 -0
  52. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/models/v2/resource.py +0 -0
  53. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/__init__.py +0 -0
  54. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/__init__.py +0 -0
  55. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
  56. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/_aux_functions.py +0 -0
  57. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
  58. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
  59. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/job.py +0 -0
  60. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/profile.py +0 -0
  61. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/resource.py +0 -0
  62. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/sharing.py +0 -0
  63. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
  64. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/__init__.py +0 -0
  65. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/alive.py +0 -0
  66. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/settings.py +0 -0
  67. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
  68. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
  69. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/_aux_functions_sharing.py +0 -0
  70. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py +0 -0
  71. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
  72. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +0 -0
  73. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/dataset.py +0 -0
  74. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/history.py +0 -0
  75. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/images.py +0 -0
  76. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/job.py +0 -0
  77. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/pre_submission_checks.py +0 -0
  78. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/project.py +0 -0
  79. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/sharing.py +0 -0
  80. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/task.py +0 -0
  81. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
  82. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/api/v2/task_version_update.py +0 -0
  83. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/__init__.py +0 -0
  84. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
  85. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/group.py +0 -0
  86. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/login.py +0 -0
  87. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/oauth.py +0 -0
  88. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/register.py +0 -0
  89. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/router.py +0 -0
  90. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/users.py +0 -0
  91. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/auth/viewer_paths.py +0 -0
  92. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/aux/__init__.py +0 -0
  93. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/aux/_job.py +0 -0
  94. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/aux/_runner.py +0 -0
  95. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/aux/validate_user_profile.py +0 -0
  96. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/routes/pagination.py +0 -0
  97. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/__init__.py +0 -0
  98. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/user.py +0 -0
  99. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/user_group.py +0 -0
  100. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/accounting.py +0 -0
  101. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/dataset.py +0 -0
  102. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/history.py +0 -0
  103. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/job.py +0 -0
  104. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/manifest.py +0 -0
  105. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/profile.py +0 -0
  106. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/project.py +0 -0
  107. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/resource.py +0 -0
  108. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/sharing.py +0 -0
  109. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
  110. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/task_collection.py +0 -0
  111. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/schemas/v2/task_group.py +0 -0
  112. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/security/signup_email.py +0 -0
  113. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/app/shutdown.py +0 -0
  114. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/config/__init__.py +0 -0
  115. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/config/_data.py +0 -0
  116. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/config/_database.py +0 -0
  117. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/config/_email.py +0 -0
  118. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/config/_main.py +0 -0
  119. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/config/_oauth.py +0 -0
  120. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/config/_settings_config.py +0 -0
  121. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/data_migrations/tools.py +0 -0
  122. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/exceptions.py +0 -0
  123. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/gunicorn_fractal.py +0 -0
  124. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/images/__init__.py +0 -0
  125. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/images/models.py +0 -0
  126. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/images/status_tools.py +0 -0
  127. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/images/tools.py +0 -0
  128. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/logger.py +0 -0
  129. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/main.py +0 -0
  130. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/env.py +0 -0
  131. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/naming_convention.py +0 -0
  132. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
  133. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/068496367952_drop_taskgroup_venv_size_and_files_.py +0 -0
  134. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
  135. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +0 -0
  136. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
  137. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/1a83a5260664_rename.py +0 -0
  138. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
  139. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
  140. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/40d6d6511b20_add_index_to_history_models.py +0 -0
  141. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/45fbb391d7af_make_resource_id_fk_non_nullable.py +0 -0
  142. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
  143. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/49d0856e9569_drop_table.py +0 -0
  144. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
  145. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
  146. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
  147. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
  148. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
  149. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
  150. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
  151. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/7673fe18c05d_remove_project_dir_server_default.py +0 -0
  152. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/7910eed4cf97_user_project_dirs_and_usergroup_viewer_.py +0 -0
  153. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/791ce783d3d8_add_indices.py +0 -0
  154. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +0 -0
  155. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
  156. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/88270f589c9b_add_prevent_new_submissions.py +0 -0
  157. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
  158. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
  159. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
  160. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +0 -0
  161. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
  162. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +0 -0
  163. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
  164. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
  165. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
  166. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
  167. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
  168. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
  169. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
  170. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +0 -0
  171. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +0 -0
  172. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/b7477cc98f45_2_18_1.py +0 -0
  173. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/bc0e8b3327a7_project_sharing.py +0 -0
  174. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +0 -0
  175. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/caba9fb1ea5e_drop_useroauth_user_settings_id.py +0 -0
  176. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
  177. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
  178. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
  179. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
  180. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/e0e717ae2f26_delete_linkuserproject_ondelete_project.py +0 -0
  181. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/e53dc51fdf93_add_useroauth_is_guest.py +0 -0
  182. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
  183. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
  184. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
  185. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/f0702066b007_one_submitted_job_per_dataset.py +0 -0
  186. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +0 -0
  187. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
  188. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
  189. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/py.typed +0 -0
  190. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/__init__.py +0 -0
  191. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/components.py +0 -0
  192. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/config/__init__.py +0 -0
  193. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/config/_local.py +0 -0
  194. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/config/_slurm.py +0 -0
  195. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/config/slurm_mem_to_MB.py +0 -0
  196. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/exceptions.py +0 -0
  197. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/__init__.py +0 -0
  198. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/base_runner.py +0 -0
  199. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/call_command_wrapper.py +0 -0
  200. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/local/__init__.py +0 -0
  201. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/local/get_local_config.py +0 -0
  202. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/local/runner.py +0 -0
  203. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/__init__.py +0 -0
  204. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/_batching.py +0 -0
  205. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/_job_states.py +0 -0
  206. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/base_slurm_runner.py +0 -0
  207. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/get_slurm_config.py +0 -0
  208. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/remote.py +0 -0
  209. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/slurm_config.py +0 -0
  210. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
  211. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_ssh/__init__.py +0 -0
  212. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_ssh/run_subprocess.py +0 -0
  213. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_ssh/runner.py +0 -0
  214. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_ssh/tar_commands.py +0 -0
  215. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_sudo/__init__.py +0 -0
  216. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
  217. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/executors/slurm_sudo/runner.py +0 -0
  218. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/filenames.py +0 -0
  219. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/set_start_and_last_task_index.py +0 -0
  220. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/task_files.py +0 -0
  221. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/__init__.py +0 -0
  222. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/_local.py +0 -0
  223. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/_slurm_ssh.py +0 -0
  224. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/_slurm_sudo.py +0 -0
  225. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/db_tools.py +0 -0
  226. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/deduplicate_list.py +0 -0
  227. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/merge_outputs.py +0 -0
  228. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/runner.py +0 -0
  229. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/runner_functions.py +0 -0
  230. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/v2/task_interface.py +0 -0
  231. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/runner/versions.py +0 -0
  232. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/ssh/__init__.py +0 -0
  233. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/ssh/_fabric.py +0 -0
  234. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/string_tools.py +0 -0
  235. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/syringe.py +0 -0
  236. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/__init__.py +0 -0
  237. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/config/__init__.py +0 -0
  238. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/config/_pixi.py +0 -0
  239. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/config/_python.py +0 -0
  240. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/utils.py +0 -0
  241. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/__init__.py +0 -0
  242. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/__init__.py +0 -0
  243. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/_utils.py +0 -0
  244. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/collect.py +0 -0
  245. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/collect_pixi.py +0 -0
  246. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/deactivate.py +0 -0
  247. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/deactivate_pixi.py +0 -0
  248. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/delete.py +0 -0
  249. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/reactivate.py +0 -0
  250. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/local/reactivate_pixi.py +0 -0
  251. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
  252. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +0 -0
  253. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
  254. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/collect.py +0 -0
  255. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/collect_pixi.py +0 -0
  256. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
  257. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/deactivate_pixi.py +0 -0
  258. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/delete.py +0 -0
  259. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
  260. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/ssh/reactivate_pixi.py +0 -0
  261. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
  262. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
  263. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
  264. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
  265. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/5_pip_install_from_freeze.sh +0 -0
  266. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/pixi_1_extract.sh +0 -0
  267. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/pixi_2_install.sh +0 -0
  268. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/templates/pixi_3_post_install.sh +0 -0
  269. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/utils_background.py +0 -0
  270. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/utils_database.py +0 -0
  271. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/utils_package_names.py +0 -0
  272. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/utils_pixi.py +0 -0
  273. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
  274. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/tasks/v2/utils_templates.py +0 -0
  275. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/types/__init__.py +0 -0
  276. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/types/validators/__init__.py +0 -0
  277. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/types/validators/_common_validators.py +0 -0
  278. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/types/validators/_filter_validators.py +0 -0
  279. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/types/validators/_workflow_task_arguments_validators.py +0 -0
  280. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/urls.py +0 -0
  281. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/utils.py +0 -0
  282. {fractal_server-2.19.0 → fractal_server-2.19.0a0}/fractal_server/zip_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fractal-server
3
- Version: 2.19.0
3
+ Version: 2.19.0a0
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  Author: Tommaso Comparin, Marco Franzon, Yuri Chiucconi, Jacopo Nespolo
6
6
  Author-email: Tommaso Comparin <tommaso.comparin@exact-lab.it>, Marco Franzon <marco.franzon@exact-lab.it>, Yuri Chiucconi <yuri.chiucconi@exact-lab.it>, Jacopo Nespolo <jacopo.nespolo@exact-lab.it>
@@ -17,7 +17,7 @@ Requires-Dist: pydantic>=2.12.0,<2.13.0
17
17
  Requires-Dist: pydantic-settings==2.12.0
18
18
  Requires-Dist: packaging>=25.0.0,<26.0.0
19
19
  Requires-Dist: fabric>=3.2.2,<3.3.0
20
- Requires-Dist: gunicorn>=24.1,<25
20
+ Requires-Dist: gunicorn>=23.0,<24.0
21
21
  Requires-Dist: psycopg[binary]>=3.1.0,<4.0.0
22
22
  Requires-Dist: tomli-w>=1.2.0,<1.3.0
23
23
  Requires-Python: >=3.12, <3.15
@@ -0,0 +1 @@
1
+ __VERSION__ = "2.19.0a0"
@@ -27,6 +27,10 @@ class DatasetV2(SQLModel, table=True):
27
27
  sa_relationship_kwargs=dict(lazy="selectin"),
28
28
  )
29
29
 
30
+ history: list[dict[str, Any]] = Field(
31
+ sa_column=Column(JSONB, server_default="[]", nullable=False)
32
+ )
33
+
30
34
  timestamp_created: datetime = Field(
31
35
  default_factory=get_timestamp,
32
36
  sa_column=Column(DateTime(timezone=True), nullable=False),
@@ -5,7 +5,6 @@ from pydantic import ConfigDict
5
5
  from sqlalchemy import Column
6
6
  from sqlalchemy.dialects.postgresql import JSONB
7
7
  from sqlalchemy.types import DateTime
8
- from sqlalchemy.types import String
9
8
  from sqlmodel import Field
10
9
  from sqlmodel import Index
11
10
  from sqlmodel import SQLModel
@@ -45,9 +44,6 @@ class JobV2(SQLModel, table=True):
45
44
  project_dump: dict[str, Any] = Field(
46
45
  sa_column=Column(JSONB, nullable=False)
47
46
  )
48
- fractal_server_version: str = Field(
49
- sa_column=Column(String, server_default="pre-2.19.0", nullable=False)
50
- )
51
47
 
52
48
  worker_init: str | None = None
53
49
  working_dir: str | None = None
@@ -14,6 +14,7 @@ class TaskV2(SQLModel, table=True):
14
14
  type: str
15
15
  command_non_parallel: str | None = None
16
16
  command_parallel: str | None = None
17
+ source: str | None = None
17
18
 
18
19
  meta_non_parallel: dict[str, Any] = Field(
19
20
  sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
@@ -4,7 +4,6 @@ from datetime import timezone
4
4
  from sqlalchemy import Column
5
5
  from sqlalchemy.dialects.postgresql import JSONB
6
6
  from sqlalchemy.types import DateTime
7
- from sqlalchemy.types import String
8
7
  from sqlmodel import Field
9
8
  from sqlmodel import Relationship
10
9
  from sqlmodel import SQLModel
@@ -152,6 +151,3 @@ class TaskGroupActivityV2(SQLModel, table=True):
152
151
  default=None,
153
152
  sa_column=Column(DateTime(timezone=True)),
154
153
  )
155
- fractal_server_version: str = Field(
156
- sa_column=Column(String, server_default="pre-2.19.0", nullable=False)
157
- )
@@ -32,5 +32,3 @@ class WorkflowV2(SQLModel, table=True):
32
32
  default_factory=get_timestamp,
33
33
  sa_column=Column(DateTime(timezone=True), nullable=False),
34
34
  )
35
-
36
- description: str | None = Field(default=None, nullable=True)
@@ -39,6 +39,3 @@ class WorkflowTaskV2(SQLModel, table=True):
39
39
  task_type: str
40
40
  task_id: int = Field(foreign_key="taskv2.id")
41
41
  task: TaskV2 = Relationship(sa_relationship_kwargs=dict(lazy="selectin"))
42
-
43
- alias: str | None = Field(default=None, nullable=True)
44
- description: str | None = Field(default=None, nullable=True)
@@ -30,6 +30,7 @@ class TaskMinimal(BaseModel):
30
30
  taskgroupv2_id: int
31
31
  command_non_parallel: str | None = None
32
32
  command_parallel: str | None = None
33
+ source: str | None = None
33
34
  version: str | None = None
34
35
 
35
36
 
@@ -54,6 +55,7 @@ class TaskInfo(BaseModel):
54
55
  @router.get("/", response_model=PaginationResponse[TaskInfo])
55
56
  async def query_tasks(
56
57
  id: int | None = None,
58
+ source: str | None = None,
57
59
  version: str | None = None,
58
60
  name: str | None = None,
59
61
  task_type: TaskType | None = None,
@@ -79,6 +81,9 @@ async def query_tasks(
79
81
  if id is not None:
80
82
  stm = stm.where(TaskV2.id == id)
81
83
  stm_count = stm_count.where(TaskV2.id == id)
84
+ if source is not None:
85
+ stm = stm.where(TaskV2.source.icontains(source))
86
+ stm_count = stm_count.where(TaskV2.source.icontains(source))
82
87
  if version is not None:
83
88
  stm = stm.where(TaskV2.version == version)
84
89
  stm_count = stm_count.where(TaskV2.version == version)
@@ -5,7 +5,6 @@ from fastapi import HTTPException
5
5
  from fastapi import Response
6
6
  from fastapi import status
7
7
 
8
- from fractal_server import __VERSION__
9
8
  from fractal_server.app.db import AsyncSession
10
9
  from fractal_server.app.db import get_async_db
11
10
  from fractal_server.app.models import UserOAuth
@@ -94,7 +93,6 @@ async def deactivate_task_group(
94
93
  ),
95
94
  timestamp_started=get_timestamp(),
96
95
  timestamp_ended=get_timestamp(),
97
- fractal_server_version=__VERSION__,
98
96
  )
99
97
  db.add(task_group)
100
98
  db.add(task_group_activity)
@@ -110,7 +108,6 @@ async def deactivate_task_group(
110
108
  pkg_name=task_group.pkg_name,
111
109
  version=task_group.version,
112
110
  timestamp_started=get_timestamp(),
113
- fractal_server_version=__VERSION__,
114
111
  )
115
112
  db.add(task_group_activity)
116
113
  await db.commit()
@@ -191,7 +188,6 @@ async def reactivate_task_group(
191
188
  ),
192
189
  timestamp_started=get_timestamp(),
193
190
  timestamp_ended=get_timestamp(),
194
- fractal_server_version=__VERSION__,
195
191
  )
196
192
  db.add(task_group)
197
193
  db.add(task_group_activity)
@@ -215,7 +211,6 @@ async def reactivate_task_group(
215
211
  pkg_name=task_group.pkg_name,
216
212
  version=task_group.version,
217
213
  timestamp_started=get_timestamp(),
218
- fractal_server_version=__VERSION__,
219
214
  )
220
215
  db.add(task_group_activity)
221
216
  await db.commit()
@@ -269,7 +264,6 @@ async def delete_task_group(
269
264
  pkg_name=task_group.pkg_name,
270
265
  version=(task_group.version or "N/A"),
271
266
  timestamp_started=get_timestamp(),
272
- fractal_server_version=__VERSION__,
273
267
  )
274
268
  db.add(task_group_activity)
275
269
  await db.commit()
@@ -14,6 +14,7 @@ from .job import router as job_router
14
14
  from .pre_submission_checks import router as pre_submission_checks_router
15
15
  from .project import router as project_router
16
16
  from .sharing import router as sharing_router
17
+ from .status_legacy import router as status_legacy_router
17
18
  from .submit import router as submit_job_router
18
19
  from .task import router as task_router
19
20
  from .task_collection import router as task_collection_router
@@ -36,6 +37,7 @@ router_api.include_router(sharing_router, tags=["Project Sharing"])
36
37
  router_api.include_router(project_router, tags=["Project"])
37
38
  router_api.include_router(submit_job_router, tags=["Job"])
38
39
  router_api.include_router(history_router, tags=["History"])
40
+ router_api.include_router(status_legacy_router, tags=["Status Legacy"])
39
41
 
40
42
 
41
43
  settings = Inject(get_settings)
@@ -2,6 +2,8 @@ from fastapi import HTTPException
2
2
  from fastapi import status
3
3
  from httpx import AsyncClient
4
4
  from httpx import TimeoutException
5
+ from packaging.version import InvalidVersion
6
+ from packaging.version import Version
5
7
  from sqlmodel import func
6
8
  from sqlmodel import select
7
9
 
@@ -12,7 +14,6 @@ from fractal_server.app.models.v2 import TaskGroupV2
12
14
  from fractal_server.app.models.v2 import TaskV2
13
15
  from fractal_server.app.models.v2 import WorkflowTaskV2
14
16
  from fractal_server.app.models.v2 import WorkflowV2
15
- from fractal_server.app.routes.aux._versions import _find_latest_version_or_422
16
17
  from fractal_server.app.schemas.v2 import JobStatusType
17
18
  from fractal_server.app.schemas.v2 import TaskGroupActivityStatus
18
19
  from fractal_server.logger import set_logger
@@ -25,6 +26,24 @@ PYPI_JSON_HEADERS = {"Accept": "application/vnd.pypi.simple.v1+json"}
25
26
  logger = set_logger(__name__)
26
27
 
27
28
 
29
+ def _find_latest_version_or_422(versions: list[str]) -> str:
30
+ """
31
+ > For PEP 440 versions, this is easy enough for the client to do (using
32
+ > the `packaging` library [...]. For non-standard versions, there is no
33
+ > well-defined ordering, and clients will need to decide on what rule is
34
+ > appropriate for their needs.
35
+ (https://peps.python.org/pep-0700/#why-not-provide-a-latest-version-value)
36
+ """
37
+ try:
38
+ latest = max(versions, key=lambda v_str: Version(v_str))
39
+ return latest
40
+ except InvalidVersion as e:
41
+ raise HTTPException(
42
+ status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
43
+ detail=f"Cannot find latest version (original error: {str(e)}).",
44
+ )
45
+
46
+
28
47
  async def get_package_version_from_pypi(
29
48
  name: str,
30
49
  version: str | None = None,
@@ -0,0 +1,156 @@
1
+ from fastapi import APIRouter
2
+ from fastapi import Depends
3
+
4
+ from fractal_server.app.db import AsyncSession
5
+ from fractal_server.app.db import get_async_db
6
+ from fractal_server.app.models import UserOAuth
7
+ from fractal_server.app.models.v2 import JobV2
8
+ from fractal_server.app.routes.auth import get_api_guest
9
+ from fractal_server.app.schemas.v2.sharing import ProjectPermissions
10
+ from fractal_server.app.schemas.v2.status_legacy import LegacyStatusRead
11
+ from fractal_server.app.schemas.v2.status_legacy import WorkflowTaskStatusType
12
+ from fractal_server.logger import set_logger
13
+
14
+ from ._aux_functions import _get_dataset_check_access
15
+ from ._aux_functions import _get_submitted_jobs_statement
16
+ from ._aux_functions import _get_workflow_check_access
17
+
18
+ router = APIRouter()
19
+
20
+ logger = set_logger(__name__)
21
+
22
+
23
+ @router.get(
24
+ "/project/{project_id}/status-legacy/",
25
+ response_model=LegacyStatusRead,
26
+ )
27
+ async def get_workflowtask_status(
28
+ project_id: int,
29
+ dataset_id: int,
30
+ workflow_id: int,
31
+ user: UserOAuth = Depends(get_api_guest),
32
+ db: AsyncSession = Depends(get_async_db),
33
+ ) -> LegacyStatusRead | None:
34
+ """
35
+ Extract the status of all `WorkflowTaskV2` of a given `WorkflowV2` that ran
36
+ on a given `DatasetV2`.
37
+
38
+ *NOTE*: the current endpoint is not guaranteed to provide consistent
39
+ results if the workflow task list is modified in a non-trivial way
40
+ (that is, by adding intermediate tasks, removing tasks, or changing their
41
+ order). See fractal-server GitHub issues: 793, 1083.
42
+ """
43
+ # Get the dataset DB entry
44
+ output = await _get_dataset_check_access(
45
+ project_id=project_id,
46
+ dataset_id=dataset_id,
47
+ user_id=user.id,
48
+ required_permissions=ProjectPermissions.READ,
49
+ db=db,
50
+ )
51
+ dataset = output["dataset"]
52
+
53
+ # Get the workflow DB entry
54
+ workflow = await _get_workflow_check_access(
55
+ project_id=project_id,
56
+ workflow_id=workflow_id,
57
+ user_id=user.id,
58
+ required_permissions=ProjectPermissions.READ,
59
+ db=db,
60
+ )
61
+
62
+ # Check whether there exists a submitted job associated to this
63
+ # workflow/dataset pair. If it does exist, it will be used later.
64
+ # If there are multiple jobs, raise an error.
65
+ res = await db.execute(
66
+ _get_submitted_jobs_statement()
67
+ .where(JobV2.dataset_id == dataset_id)
68
+ .where(JobV2.workflow_id == workflow_id)
69
+ )
70
+ running_job = res.scalars().one_or_none()
71
+
72
+ # Initialize empty dictionary for WorkflowTaskV2 status
73
+ workflow_tasks_status_dict: dict = {}
74
+
75
+ # Lowest priority: read status from DB, which corresponds to jobs that are
76
+ # not running
77
+ history = dataset.history
78
+ for history_item in history:
79
+ wftask_id = history_item["workflowtask"]["id"]
80
+ wftask_status = history_item["status"]
81
+ workflow_tasks_status_dict[wftask_id] = wftask_status
82
+
83
+ if running_job is None:
84
+ # If no job is running, the chronological-last history item is also the
85
+ # positional-last workflow task to be included in the response.
86
+ if len(history) > 0:
87
+ last_valid_wftask_id = history[-1]["workflowtask"]["id"]
88
+ else:
89
+ last_valid_wftask_id = None
90
+ else:
91
+ # If a job is running, then gather more up-to-date information
92
+
93
+ # Mid priority: Set all WorkflowTask's that are part of the running job
94
+ # as "submitted"
95
+ start = running_job.first_task_index
96
+ end = running_job.last_task_index + 1
97
+
98
+ running_job_wftasks = workflow.task_list[start:end]
99
+ running_job_statuses = [
100
+ workflow_tasks_status_dict.get(wft.id, None)
101
+ for wft in running_job_wftasks
102
+ ]
103
+ try:
104
+ first_submitted_index = running_job_statuses.index(
105
+ WorkflowTaskStatusType.SUBMITTED
106
+ )
107
+ except ValueError:
108
+ logger.warning(
109
+ f"Job {running_job.id} is submitted but its task list does not"
110
+ f" contain a {WorkflowTaskStatusType.SUBMITTED} task."
111
+ )
112
+ first_submitted_index = 0
113
+
114
+ for wftask in running_job_wftasks[first_submitted_index:]:
115
+ workflow_tasks_status_dict[wftask.id] = (
116
+ WorkflowTaskStatusType.SUBMITTED
117
+ )
118
+
119
+ # The last workflow task that is included in the submitted job is also
120
+ # the positional-last workflow task to be included in the response.
121
+ try:
122
+ last_valid_wftask_id = workflow.task_list[end - 1].id
123
+ except IndexError as e:
124
+ logger.warning(
125
+ f"Handled IndexError in `get_workflowtask_status` ({str(e)})."
126
+ )
127
+ logger.warning(
128
+ "Additional information: "
129
+ f"{running_job.first_task_index=}; "
130
+ f"{running_job.last_task_index=}; "
131
+ f"{len(workflow.task_list)=}; "
132
+ f"{dataset_id=}; "
133
+ f"{workflow_id=}."
134
+ )
135
+ last_valid_wftask_id = None
136
+ logger.warning(f"Now setting {last_valid_wftask_id=}.")
137
+
138
+ # Based on previously-gathered information, clean up the response body
139
+ clean_workflow_tasks_status_dict = {}
140
+ for wf_task in workflow.task_list:
141
+ wf_task_status = workflow_tasks_status_dict.get(wf_task.id)
142
+ if wf_task_status is None:
143
+ # If a wftask ID was not found, ignore it and continue
144
+ continue
145
+ clean_workflow_tasks_status_dict[str(wf_task.id)] = wf_task_status
146
+ if wf_task_status == WorkflowTaskStatusType.FAILED:
147
+ # Starting from the beginning of `workflow.task_list`, stop the
148
+ # first time that you hit a failed job
149
+ break
150
+ if wf_task.id == last_valid_wftask_id:
151
+ # Starting from the beginning of `workflow.task_list`, stop the
152
+ # first time that you hit `last_valid_wftask_id``
153
+ break
154
+
155
+ response_body = LegacyStatusRead(status=clean_workflow_tasks_status_dict)
156
+ return response_body
@@ -11,7 +11,6 @@ from fastapi import status
11
11
  from sqlmodel import select
12
12
  from sqlmodel import update
13
13
 
14
- from fractal_server import __VERSION__
15
14
  from fractal_server.app.db import AsyncSession
16
15
  from fractal_server.app.db import get_async_db
17
16
  from fractal_server.app.models import Profile
@@ -217,12 +216,11 @@ async def submit_job(
217
216
  dataset.model_dump_json(exclude={"images", "history"})
218
217
  ),
219
218
  workflow_dump=json.loads(
220
- workflow.model_dump_json(exclude={"task_list", "description"})
219
+ workflow.model_dump_json(exclude={"task_list"})
221
220
  ),
222
221
  project_dump=json.loads(
223
222
  project.model_dump_json(exclude={"resource_id"})
224
223
  ),
225
- fractal_server_version=__VERSION__,
226
224
  **job_create.model_dump(),
227
225
  )
228
226
 
@@ -14,7 +14,6 @@ from pydantic import BaseModel
14
14
  from pydantic import ValidationError
15
15
  from pydantic import model_validator
16
16
 
17
- from fractal_server import __VERSION__
18
17
  from fractal_server.app.db import AsyncSession
19
18
  from fractal_server.app.db import get_async_db
20
19
  from fractal_server.app.models import UserOAuth
@@ -333,7 +332,6 @@ async def collect_tasks_pip(
333
332
  action=TaskGroupActivityAction.COLLECT,
334
333
  pkg_name=task_group.pkg_name,
335
334
  version=task_group.version,
336
- fractal_server_version=__VERSION__,
337
335
  )
338
336
  db.add(task_group_activity)
339
337
  await db.commit()
@@ -10,7 +10,6 @@ from fastapi import Response
10
10
  from fastapi import UploadFile
11
11
  from fastapi import status
12
12
 
13
- from fractal_server import __VERSION__
14
13
  from fractal_server.app.db import AsyncSession
15
14
  from fractal_server.app.db import get_async_db
16
15
  from fractal_server.app.models import UserOAuth
@@ -183,7 +182,6 @@ async def collect_task_pixi(
183
182
  action=TaskGroupActivityAction.COLLECT,
184
183
  pkg_name=task_group.pkg_name,
185
184
  version=task_group.version,
186
- fractal_server_version=__VERSION__,
187
185
  )
188
186
  db.add(task_group_activity)
189
187
  await db.commit()
@@ -4,6 +4,9 @@ from fastapi import APIRouter
4
4
  from fastapi import Depends
5
5
  from fastapi import HTTPException
6
6
  from fastapi import status
7
+ from packaging.version import InvalidVersion
8
+ from packaging.version import Version
9
+ from packaging.version import parse
7
10
  from pydantic.types import AwareDatetime
8
11
  from sqlmodel import or_
9
12
  from sqlmodel import select
@@ -22,7 +25,6 @@ from fractal_server.app.routes.auth._aux_auth import (
22
25
  from fractal_server.app.routes.auth._aux_auth import (
23
26
  _verify_user_belongs_to_group,
24
27
  )
25
- from fractal_server.app.routes.aux._versions import _version_sort_key
26
28
  from fractal_server.app.schemas.v2 import TaskGroupActivityAction
27
29
  from fractal_server.app.schemas.v2 import TaskGroupActivityRead
28
30
  from fractal_server.app.schemas.v2 import TaskGroupActivityStatus
@@ -41,6 +43,26 @@ router = APIRouter()
41
43
  logger = set_logger(__name__)
42
44
 
43
45
 
46
+ def _version_sort_key(
47
+ task_group: TaskGroupV2,
48
+ ) -> tuple[int, Version | str | None]:
49
+ """
50
+ Returns a tuple used as (reverse) ordering key for TaskGroups in
51
+ `get_task_group_list`.
52
+ The TaskGroups with a parsable versions are the first in order,
53
+ sorted according to the sorting rules of packaging.version.Version.
54
+ Next in order we have the TaskGroups with non-null non-parsable versions,
55
+ sorted alphabetically.
56
+ Last we have the TaskGroups with null version.
57
+ """
58
+ if task_group.version is None:
59
+ return (0, task_group.version)
60
+ try:
61
+ return (2, parse(task_group.version))
62
+ except InvalidVersion:
63
+ return (1, task_group.version)
64
+
65
+
44
66
  @router.get("/activity/", response_model=list[TaskGroupActivityRead])
45
67
  async def get_task_group_activity_list(
46
68
  task_group_activity_id: int | None = None,
@@ -154,7 +176,7 @@ async def get_task_group_list(
154
176
  await remove_duplicate_task_groups(
155
177
  task_groups=sorted(
156
178
  list(groups),
157
- key=lambda group: _version_sort_key(group.version),
179
+ key=_version_sort_key,
158
180
  reverse=True,
159
181
  ),
160
182
  user_id=user.id,
@@ -5,7 +5,6 @@ from fastapi import HTTPException
5
5
  from fastapi import Response
6
6
  from fastapi import status
7
7
 
8
- from fractal_server import __VERSION__
9
8
  from fractal_server.app.db import AsyncSession
10
9
  from fractal_server.app.db import get_async_db
11
10
  from fractal_server.app.models import UserOAuth
@@ -100,7 +99,6 @@ async def deactivate_task_group(
100
99
  ),
101
100
  timestamp_started=get_timestamp(),
102
101
  timestamp_ended=get_timestamp(),
103
- fractal_server_version=__VERSION__,
104
102
  )
105
103
  db.add(task_group)
106
104
  db.add(task_group_activity)
@@ -116,7 +114,6 @@ async def deactivate_task_group(
116
114
  pkg_name=task_group.pkg_name,
117
115
  version=task_group.version,
118
116
  timestamp_started=get_timestamp(),
119
- fractal_server_version=__VERSION__,
120
117
  )
121
118
  task_group.active = False
122
119
  db.add(task_group)
@@ -205,7 +202,6 @@ async def reactivate_task_group(
205
202
  ),
206
203
  timestamp_started=get_timestamp(),
207
204
  timestamp_ended=get_timestamp(),
208
- fractal_server_version=__VERSION__,
209
205
  )
210
206
  db.add(task_group)
211
207
  db.add(task_group_activity)
@@ -229,7 +225,6 @@ async def reactivate_task_group(
229
225
  pkg_name=task_group.pkg_name,
230
226
  version=task_group.version,
231
227
  timestamp_started=get_timestamp(),
232
- fractal_server_version=__VERSION__,
233
228
  )
234
229
  db.add(task_group_activity)
235
230
  await db.commit()
@@ -293,7 +288,6 @@ async def delete_task_group(
293
288
  pkg_name=task_group.pkg_name,
294
289
  version=(task_group.version or "N/A"),
295
290
  timestamp_started=get_timestamp(),
296
- fractal_server_version=__VERSION__,
297
291
  )
298
292
  db.add(task_group_activity)
299
293
  await db.commit()
@@ -149,7 +149,7 @@ async def update_workflow(
149
149
  db=db,
150
150
  )
151
151
 
152
- if patch.name and patch.name != workflow.name:
152
+ if patch.name:
153
153
  await _check_workflow_exists(
154
154
  name=patch.name, project_id=project_id, db=db
155
155
  )
@@ -19,8 +19,8 @@ from fractal_server.app.routes.auth import get_api_user
19
19
  from fractal_server.app.routes.auth._aux_auth import (
20
20
  _get_default_usergroup_id_or_none,
21
21
  )
22
- from fractal_server.app.routes.aux._versions import _version_sort_key
23
22
  from fractal_server.app.schemas.v2 import TaskImport
23
+ from fractal_server.app.schemas.v2 import TaskImportLegacy
24
24
  from fractal_server.app.schemas.v2 import WorkflowImport
25
25
  from fractal_server.app.schemas.v2 import WorkflowReadWithWarnings
26
26
  from fractal_server.app.schemas.v2 import WorkflowTaskCreate
@@ -73,6 +73,32 @@ async def _get_user_accessible_taskgroups(
73
73
  return accessible_task_groups
74
74
 
75
75
 
76
+ async def _get_task_by_source(
77
+ source: str,
78
+ task_groups_list: list[TaskGroupV2],
79
+ ) -> int | None:
80
+ """
81
+ Find task with a given source.
82
+
83
+ Args:
84
+ source: `source` of the task to be imported.
85
+ task_groups_list: Current list of valid task groups.
86
+
87
+ Return:
88
+ `id` of the matching task, or `None`.
89
+ """
90
+ task_id = next(
91
+ iter(
92
+ task.id
93
+ for task_group in task_groups_list
94
+ for task in task_group.task_list
95
+ if task.source == source
96
+ ),
97
+ None,
98
+ )
99
+ return task_id
100
+
101
+
76
102
  async def _get_task_by_taskimport(
77
103
  *,
78
104
  task_import: TaskImport,
@@ -115,15 +141,14 @@ async def _get_task_by_taskimport(
115
141
  return None
116
142
 
117
143
  # Determine target `version`
144
+ # Note that task_import.version cannot be "", due to a validator
118
145
  if task_import.version is None:
119
146
  logger.debug(
120
147
  "[_get_task_by_taskimport] "
121
148
  "No version requested, looking for latest."
122
149
  )
123
- version = max(
124
- [tg.version for tg in matching_task_groups],
125
- key=_version_sort_key,
126
- )
150
+ latest_task = max(matching_task_groups, key=lambda tg: tg.version or "")
151
+ version = latest_task.version
127
152
  logger.debug(
128
153
  f"[_get_task_by_taskimport] Latest version set to {version}."
129
154
  )
@@ -221,13 +246,19 @@ async def import_workflow(
221
246
  list_task_ids = []
222
247
  for wf_task in workflow_import.task_list:
223
248
  task_import = wf_task.task
224
- task_id = await _get_task_by_taskimport(
225
- task_import=task_import,
226
- user_id=user.id,
227
- default_group_id=default_group_id,
228
- task_groups_list=task_group_list,
229
- db=db,
230
- )
249
+ if isinstance(task_import, TaskImportLegacy):
250
+ task_id = await _get_task_by_source(
251
+ source=task_import.source,
252
+ task_groups_list=task_group_list,
253
+ )
254
+ else:
255
+ task_id = await _get_task_by_taskimport(
256
+ task_import=task_import,
257
+ user_id=user.id,
258
+ default_group_id=default_group_id,
259
+ task_groups_list=task_group_list,
260
+ db=db,
261
+ )
231
262
  if task_id is None:
232
263
  raise HTTPException(
233
264
  status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
@@ -193,8 +193,13 @@ async def update_workflowtask(
193
193
  if not actual_args:
194
194
  actual_args = None
195
195
  setattr(db_wf_task, key, actual_args)
196
- else:
196
+ elif key in ["meta_parallel", "meta_non_parallel", "type_filters"]:
197
197
  setattr(db_wf_task, key, value)
198
+ else:
199
+ raise HTTPException(
200
+ status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
201
+ detail=f"patch_workflow_task endpoint cannot set {key=}",
202
+ )
198
203
 
199
204
  await db.commit()
200
205
  await db.refresh(db_wf_task)
@@ -4,8 +4,6 @@ Definition of `/auth/current-user/` endpoints
4
4
 
5
5
  from fastapi import APIRouter
6
6
  from fastapi import Depends
7
- from fastapi import HTTPException
8
- from fastapi import status
9
7
  from sqlalchemy.ext.asyncio import AsyncSession
10
8
  from sqlmodel import select
11
9
 
@@ -54,12 +52,6 @@ async def patch_current_user(
54
52
  Note: a user cannot patch their own password (as enforced within the
55
53
  `UserUpdateStrict` schema).
56
54
  """
57
- if current_user.is_guest:
58
- raise HTTPException(
59
- status_code=status.HTTP_403_FORBIDDEN,
60
- detail="This feature is not available for guest users.",
61
- )
62
-
63
55
  update = UserUpdate(**user_update.model_dump(exclude_unset=True))
64
56
 
65
57
  # NOTE: here it would be relevant to catch an `InvalidPasswordException`