fractal-server 2.17.0a9__tar.gz → 2.17.0a11__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 (262) hide show
  1. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/PKG-INFO +1 -1
  2. fractal_server-2.17.0a11/fractal_server/__init__.py +1 -0
  3. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/resource.py +3 -1
  4. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +1 -1
  5. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/task_collection.py +2 -2
  6. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/current_user.py +2 -1
  7. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/group.py +1 -1
  8. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/user_group.py +2 -1
  9. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/security/__init__.py +1 -0
  10. fractal_server-2.17.0a11/fractal_server/data_migrations/2_17_0.py +321 -0
  11. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/utils_pixi.py +3 -0
  12. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/pyproject.toml +2 -2
  13. fractal_server-2.17.0a9/fractal_server/__init__.py +0 -1
  14. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/LICENSE +0 -0
  15. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/README.md +0 -0
  16. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/__main__.py +0 -0
  17. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/alembic.ini +0 -0
  18. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/__init__.py +0 -0
  19. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/db/__init__.py +0 -0
  20. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/__init__.py +0 -0
  21. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/linkusergroup.py +0 -0
  22. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/linkuserproject.py +0 -0
  23. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/security.py +0 -0
  24. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/user_settings.py +0 -0
  25. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/__init__.py +0 -0
  26. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/accounting.py +0 -0
  27. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/dataset.py +0 -0
  28. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/history.py +0 -0
  29. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/job.py +0 -0
  30. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/profile.py +0 -0
  31. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/project.py +0 -0
  32. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/resource.py +0 -0
  33. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/task.py +0 -0
  34. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/task_group.py +0 -0
  35. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/workflow.py +0 -0
  36. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/models/v2/workflowtask.py +0 -0
  37. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/__init__.py +0 -0
  38. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/__init__.py +0 -0
  39. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
  40. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/_aux_functions.py +0 -0
  41. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
  42. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
  43. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/job.py +0 -0
  44. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/profile.py +0 -0
  45. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/project.py +0 -0
  46. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/task.py +0 -0
  47. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
  48. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
  49. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/__init__.py +0 -0
  50. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/__init__.py +0 -0
  51. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
  52. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
  53. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
  54. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py +0 -0
  55. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
  56. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/dataset.py +0 -0
  57. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/history.py +0 -0
  58. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/images.py +0 -0
  59. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/job.py +0 -0
  60. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/pre_submission_checks.py +0 -0
  61. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/project.py +0 -0
  62. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/status_legacy.py +0 -0
  63. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/submit.py +0 -0
  64. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/task.py +0 -0
  65. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
  66. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/task_collection_pixi.py +0 -0
  67. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/task_group.py +0 -0
  68. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
  69. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/task_version_update.py +0 -0
  70. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/workflow.py +0 -0
  71. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
  72. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
  73. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/__init__.py +0 -0
  74. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
  75. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/login.py +0 -0
  76. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/oauth.py +0 -0
  77. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/register.py +0 -0
  78. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/router.py +0 -0
  79. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/auth/users.py +0 -0
  80. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/aux/__init__.py +0 -0
  81. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/aux/_job.py +0 -0
  82. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/aux/_runner.py +0 -0
  83. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/aux/validate_user_profile.py +0 -0
  84. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/routes/pagination.py +0 -0
  85. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/__init__.py +0 -0
  86. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/user.py +0 -0
  87. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/__init__.py +0 -0
  88. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/accounting.py +0 -0
  89. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/dataset.py +0 -0
  90. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/dumps.py +0 -0
  91. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/history.py +0 -0
  92. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/job.py +0 -0
  93. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/manifest.py +0 -0
  94. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/profile.py +0 -0
  95. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/project.py +0 -0
  96. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/resource.py +0 -0
  97. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
  98. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/task.py +0 -0
  99. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/task_collection.py +0 -0
  100. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/task_group.py +0 -0
  101. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/workflow.py +0 -0
  102. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
  103. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/security/signup_email.py +0 -0
  104. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/app/shutdown.py +0 -0
  105. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/config/__init__.py +0 -0
  106. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/config/_data.py +0 -0
  107. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/config/_database.py +0 -0
  108. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/config/_email.py +0 -0
  109. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/config/_main.py +0 -0
  110. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/config/_oauth.py +0 -0
  111. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/config/_settings_config.py +0 -0
  112. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/data_migrations/README.md +0 -0
  113. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/data_migrations/tools.py +0 -0
  114. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/exceptions.py +0 -0
  115. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/gunicorn_fractal.py +0 -0
  116. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/images/__init__.py +0 -0
  117. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/images/models.py +0 -0
  118. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/images/status_tools.py +0 -0
  119. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/images/tools.py +0 -0
  120. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/logger.py +0 -0
  121. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/main.py +0 -0
  122. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/env.py +0 -0
  123. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/naming_convention.py +0 -0
  124. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
  125. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
  126. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +0 -0
  127. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
  128. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/1a83a5260664_rename.py +0 -0
  129. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
  130. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
  131. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
  132. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
  133. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
  134. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
  135. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
  136. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
  137. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
  138. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
  139. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/791ce783d3d8_add_indices.py +0 -0
  140. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +0 -0
  141. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
  142. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
  143. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
  144. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
  145. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +0 -0
  146. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
  147. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +0 -0
  148. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
  149. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
  150. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
  151. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
  152. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
  153. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
  154. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
  155. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +0 -0
  156. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +0 -0
  157. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +0 -0
  158. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
  159. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
  160. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
  161. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
  162. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
  163. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
  164. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
  165. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +0 -0
  166. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
  167. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
  168. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/py.typed +0 -0
  169. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/__init__.py +0 -0
  170. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/components.py +0 -0
  171. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/config/__init__.py +0 -0
  172. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/config/_local.py +0 -0
  173. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/config/_slurm.py +0 -0
  174. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/config/slurm_mem_to_MB.py +0 -0
  175. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/exceptions.py +0 -0
  176. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/__init__.py +0 -0
  177. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/base_runner.py +0 -0
  178. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/call_command_wrapper.py +0 -0
  179. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/local/__init__.py +0 -0
  180. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/local/get_local_config.py +0 -0
  181. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/local/runner.py +0 -0
  182. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/__init__.py +0 -0
  183. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/_batching.py +0 -0
  184. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/_job_states.py +0 -0
  185. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/base_slurm_runner.py +0 -0
  186. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/get_slurm_config.py +0 -0
  187. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/remote.py +0 -0
  188. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/slurm_config.py +0 -0
  189. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
  190. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_ssh/__init__.py +0 -0
  191. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_ssh/run_subprocess.py +0 -0
  192. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_ssh/runner.py +0 -0
  193. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_ssh/tar_commands.py +0 -0
  194. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_sudo/__init__.py +0 -0
  195. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
  196. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/executors/slurm_sudo/runner.py +0 -0
  197. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/filenames.py +0 -0
  198. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/set_start_and_last_task_index.py +0 -0
  199. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/task_files.py +0 -0
  200. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/__init__.py +0 -0
  201. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/_local.py +0 -0
  202. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/_slurm_ssh.py +0 -0
  203. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/_slurm_sudo.py +0 -0
  204. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/db_tools.py +0 -0
  205. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/deduplicate_list.py +0 -0
  206. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/merge_outputs.py +0 -0
  207. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/runner.py +0 -0
  208. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/runner_functions.py +0 -0
  209. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/submit_workflow.py +0 -0
  210. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/v2/task_interface.py +0 -0
  211. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/runner/versions.py +0 -0
  212. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/ssh/__init__.py +0 -0
  213. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/ssh/_fabric.py +0 -0
  214. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/string_tools.py +0 -0
  215. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/syringe.py +0 -0
  216. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/__init__.py +0 -0
  217. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/config/__init__.py +0 -0
  218. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/config/_pixi.py +0 -0
  219. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/config/_python.py +0 -0
  220. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/utils.py +0 -0
  221. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/__init__.py +0 -0
  222. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/__init__.py +0 -0
  223. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/_utils.py +0 -0
  224. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/collect.py +0 -0
  225. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/collect_pixi.py +0 -0
  226. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/deactivate.py +0 -0
  227. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/deactivate_pixi.py +0 -0
  228. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/delete.py +0 -0
  229. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/reactivate.py +0 -0
  230. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/local/reactivate_pixi.py +0 -0
  231. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
  232. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +0 -0
  233. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
  234. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/collect.py +0 -0
  235. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/collect_pixi.py +0 -0
  236. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
  237. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/deactivate_pixi.py +0 -0
  238. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/delete.py +0 -0
  239. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
  240. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/ssh/reactivate_pixi.py +0 -0
  241. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
  242. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
  243. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
  244. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
  245. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
  246. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
  247. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/pixi_1_extract.sh +0 -0
  248. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/pixi_2_install.sh +0 -0
  249. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/templates/pixi_3_post_install.sh +0 -0
  250. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/utils_background.py +0 -0
  251. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/utils_database.py +0 -0
  252. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/utils_package_names.py +0 -0
  253. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
  254. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/tasks/v2/utils_templates.py +0 -0
  255. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/types/__init__.py +0 -0
  256. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/types/validators/__init__.py +0 -0
  257. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/types/validators/_common_validators.py +0 -0
  258. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/types/validators/_filter_validators.py +0 -0
  259. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/types/validators/_workflow_task_arguments_validators.py +0 -0
  260. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/urls.py +0 -0
  261. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/fractal_server/utils.py +0 -0
  262. {fractal_server-2.17.0a9 → fractal_server-2.17.0a11}/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.17.0a9
3
+ Version: 2.17.0a11
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  License-Expression: BSD-3-Clause
6
6
  License-File: LICENSE
@@ -0,0 +1 @@
1
+ __VERSION__ = "2.17.0a11"
@@ -180,7 +180,9 @@ async def get_resource_profiles(
180
180
  await _get_resource_or_404(resource_id=resource_id, db=db)
181
181
 
182
182
  res = await db.execute(
183
- select(Profile).where(Profile.resource_id == resource_id)
183
+ select(Profile)
184
+ .where(Profile.resource_id == resource_id)
185
+ .order_by(Profile.id)
184
186
  )
185
187
  profiles = res.scalars().all()
186
188
 
@@ -52,8 +52,8 @@ async def _disambiguate_task_groups(
52
52
 
53
53
  # Medium priority: task groups owned by default user group
54
54
  settings = Inject(get_settings)
55
+ list_user_group_ids = [tg.user_group_id for tg in matching_task_groups]
55
56
  if settings.FRACTAL_DEFAULT_GROUP_NAME is not None:
56
- list_user_group_ids = [tg.user_group_id for tg in matching_task_groups]
57
57
  try:
58
58
  ind_user_group_id = list_user_group_ids.index(default_group_id)
59
59
  task_group = matching_task_groups[ind_user_group_id]
@@ -200,8 +200,8 @@ async def collect_tasks_pip(
200
200
  raise HTTPException(
201
201
  status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
202
202
  detail=(
203
- f"Python version {task_group_attrs['python_version']} is "
204
- "not available for Fractal task collection."
203
+ f"Python version {task_group_attrs['python_version']} "
204
+ "is not available on this Fractal instance."
205
205
  ),
206
206
  )
207
207
 
@@ -15,6 +15,7 @@ from fractal_server.app.models import Resource
15
15
  from fractal_server.app.models import UserGroup
16
16
  from fractal_server.app.models import UserOAuth
17
17
  from fractal_server.app.routes.auth import current_user_act
18
+ from fractal_server.app.routes.auth import current_user_act_ver
18
19
  from fractal_server.app.routes.auth._aux_auth import (
19
20
  _get_single_user_with_groups,
20
21
  )
@@ -111,7 +112,7 @@ async def get_current_user_profile_info(
111
112
  "/current-user/allowed-viewer-paths/", response_model=list[str]
112
113
  )
113
114
  async def get_current_user_allowed_viewer_paths(
114
- current_user: UserOAuth = Depends(current_user_act),
115
+ current_user: UserOAuth = Depends(current_user_act_ver),
115
116
  db: AsyncSession = Depends(get_async_db),
116
117
  ) -> list[str]:
117
118
  """
@@ -40,7 +40,7 @@ async def get_list_user_groups(
40
40
  db: AsyncSession = Depends(get_async_db),
41
41
  ) -> list[UserGroupRead]:
42
42
  # Get all groups
43
- stm_all_groups = select(UserGroup)
43
+ stm_all_groups = select(UserGroup).order_by(UserGroup.id)
44
44
  res = await db.execute(stm_all_groups)
45
45
  groups = res.scalars().all()
46
46
 
@@ -7,6 +7,7 @@ from pydantic import field_serializer
7
7
  from pydantic.types import AwareDatetime
8
8
 
9
9
  from fractal_server.types import ListUniqueAbsolutePathStr
10
+ from fractal_server.types import NonEmptyStr
10
11
 
11
12
  __all__ = (
12
13
  "UserGroupRead",
@@ -50,7 +51,7 @@ class UserGroupCreate(BaseModel):
50
51
 
51
52
  model_config = ConfigDict(extra="forbid")
52
53
 
53
- name: str
54
+ name: NonEmptyStr
54
55
  viewer_paths: ListUniqueAbsolutePathStr = Field(default_factory=list)
55
56
 
56
57
 
@@ -442,6 +442,7 @@ async def _create_first_user(
442
442
  raise e
443
443
  finally:
444
444
  function_logger.info(f"END _create_first_user, with email '{email}'")
445
+ close_logger(function_logger)
445
446
 
446
447
 
447
448
  def _create_first_group():
@@ -0,0 +1,321 @@
1
+ """
2
+
3
+ PRELIMINARY CHECKS (TO DO WITH 2.16)
4
+ * All users who are meant to actually use Fractal must be marked as active and verified.
5
+ * All users who are not active and verified will still be able to log in, but they won't have access to the rest of the API.
6
+ * All active users must have `project_dir` set, in their user settings.
7
+ * `FRACTAL_SLURM_WORKER_PYTHON` must be included explicitly in the old env file.
8
+
9
+ DATA-MIGRATION REQUIREMENTS
10
+ * Old `.fractal_server.env`, renamed into `.fractal_server.env.old`.
11
+ * New `.fractal_server.env` - see XXX for list of changes.
12
+ * Old JSON file with SLURM configuration.
13
+ * Old JSON file with pixi configuration - if applicable.
14
+
15
+
16
+ MANUAL FIXES POST DATA MIGRATION:
17
+ * Rename resource
18
+ * Rename profiles - if needed
19
+ """
20
+ import json
21
+ import logging
22
+ import sys
23
+ from typing import Any
24
+
25
+ from devtools import debug
26
+ from dotenv.main import DotEnv
27
+ from pydantic import BaseModel
28
+ from sqlalchemy.orm import Session
29
+ from sqlalchemy.sql.operators import is_
30
+ from sqlalchemy.sql.operators import is_not
31
+ from sqlmodel import select
32
+
33
+ from fractal_server.app.db import get_sync_db
34
+ from fractal_server.app.models import Profile
35
+ from fractal_server.app.models import ProjectV2
36
+ from fractal_server.app.models import Resource
37
+ from fractal_server.app.models import TaskGroupV2
38
+ from fractal_server.app.models import UserOAuth
39
+ from fractal_server.app.models import UserSettings
40
+ from fractal_server.app.schemas.v2.profile import cast_serialize_profile
41
+ from fractal_server.app.schemas.v2.resource import cast_serialize_resource
42
+ from fractal_server.config import get_settings
43
+ from fractal_server.runner.config import JobRunnerConfigSLURM
44
+ from fractal_server.tasks.config import TasksPixiSettings
45
+ from fractal_server.tasks.config import TasksPythonSettings
46
+ from fractal_server.types import AbsolutePathStr
47
+ from fractal_server.types import ListUniqueNonEmptyString
48
+ from fractal_server.urls import normalize_url
49
+
50
+ logger = logging.getLogger("fix_db")
51
+ logger.setLevel(logging.INFO)
52
+
53
+
54
+ class UserUpdateInfo(BaseModel):
55
+ user_id: int
56
+ project_dir: AbsolutePathStr
57
+ slurm_accounts: ListUniqueNonEmptyString
58
+
59
+
60
+ class ProfileUsersUpdateInfo(BaseModel):
61
+ data: dict[str, Any]
62
+ user_updates: list[UserUpdateInfo]
63
+
64
+
65
+ def _get_user_settings(user: UserOAuth, db: Session) -> UserSettings:
66
+ if user.user_settings_id is None:
67
+ sys.exit(f"User {user.email} is active but {user.user_settings_id=}.")
68
+ user_settings = db.get(UserSettings, user.user_settings_id)
69
+ return user_settings
70
+
71
+
72
+ def assert_user_setting_key(
73
+ user: UserOAuth,
74
+ user_settings: UserSettings,
75
+ keys: list[str],
76
+ ) -> None:
77
+ for key in keys:
78
+ if getattr(user_settings, key) is None:
79
+ sys.exit(
80
+ f"User {user.email} is active and verified but their "
81
+ f"user settings have {key}=None."
82
+ )
83
+
84
+
85
+ def prepare_profile_and_user_updates() -> dict[str, ProfileUsersUpdateInfo]:
86
+ settings = get_settings()
87
+ profiles_and_users: dict[str, ProfileUsersUpdateInfo] = {}
88
+ with next(get_sync_db()) as db:
89
+ # Get active&verified users
90
+ res = db.execute(
91
+ select(UserOAuth)
92
+ .where(is_(UserOAuth.is_active, True))
93
+ .where(is_(UserOAuth.is_verified, True))
94
+ .order_by(UserOAuth.id)
95
+ )
96
+ for user in res.unique().scalars().all():
97
+ # Get user settings
98
+ user_settings = _get_user_settings(user=user, db=db)
99
+ assert_user_setting_key(user, user_settings, ["project_dir"])
100
+
101
+ # Prepare profile data and user update
102
+ new_profile_data = dict()
103
+ if settings.FRACTAL_RUNNER_BACKEND == "slurm_sudo":
104
+ assert_user_setting_key(user, user_settings, ["slurm_user"])
105
+ username = user_settings.slurm_user
106
+ elif settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
107
+ assert_user_setting_key(
108
+ user,
109
+ user_settings,
110
+ [
111
+ "ssh_username",
112
+ "ssh_private_key_path",
113
+ "ssh_tasks_dir",
114
+ "ssh_jobs_dir",
115
+ ],
116
+ )
117
+ username = user_settings.ssh_username
118
+ new_profile_data.update(
119
+ ssh_key_path=user_settings.ssh_private_key_path,
120
+ tasks_remote_dir=normalize_url(
121
+ user_settings.ssh_tasks_dir
122
+ ),
123
+ jobs_remote_dir=normalize_url(user_settings.ssh_jobs_dir),
124
+ )
125
+
126
+ new_profile_data.update(
127
+ name=f"Profile {username}",
128
+ username=username,
129
+ resource_type=settings.FRACTAL_RUNNER_BACKEND,
130
+ )
131
+ debug(new_profile_data)
132
+ cast_serialize_profile(new_profile_data)
133
+
134
+ user_update_info = UserUpdateInfo(
135
+ user_id=user.id,
136
+ project_dir=normalize_url(user_settings.project_dir),
137
+ slurm_accounts=user_settings.slurm_accounts or [],
138
+ )
139
+
140
+ if username in profiles_and_users.keys():
141
+ if profiles_and_users[username].data != new_profile_data:
142
+ # FIXME
143
+ debug(new_profile_data)
144
+ debug(profiles_and_users[username].data)
145
+ raise ValueError()
146
+ profiles_and_users[username].user_updates.append(
147
+ user_update_info
148
+ )
149
+ else:
150
+ profiles_and_users[username] = ProfileUsersUpdateInfo(
151
+ data=new_profile_data,
152
+ user_updates=[user_update_info],
153
+ )
154
+
155
+ return profiles_and_users
156
+
157
+
158
+ def get_old_dotenv_variables() -> dict[str, str | None]:
159
+ """
160
+ See
161
+ https://github.com/fractal-analytics-platform/fractal-server/blob/2.16.x/fractal_server/config.py
162
+ """
163
+ OLD_DOTENV_FILE = ".fractal_server.env.old"
164
+ return dict(
165
+ **DotEnv(
166
+ dotenv_path=OLD_DOTENV_FILE,
167
+ override=False,
168
+ ).dict()
169
+ )
170
+
171
+
172
+ def get_TasksPythonSettings(
173
+ old_config: dict[str, str | None]
174
+ ) -> dict[str, Any]:
175
+ versions = {}
176
+ for version_underscore in ["3_9", "3_10", "3_11", "3_12"]:
177
+ key = f"FRACTAL_TASKS_PYTHON_{version_underscore}"
178
+ version_dot = version_underscore.replace("_", ".")
179
+ value = old_config.get(key, None)
180
+ if value is not None:
181
+ versions[version_dot] = value
182
+ obj = TasksPythonSettings(
183
+ default_version=old_config["FRACTAL_TASKS_PYTHON_DEFAULT_VERSION"],
184
+ versions=versions,
185
+ pip_cache_dir=old_config.get("FRACTAL_PIP_CACHE_DIR", None),
186
+ )
187
+ return obj.model_dump()
188
+
189
+
190
+ def get_TasksPixiSettings(old_config: dict[str, str | None]) -> dict[str, Any]:
191
+ pixi_file = old_config.get("FRACTAL_PIXI_CONFIG_FILE", None)
192
+ if pixi_file is None:
193
+ return {}
194
+ with open(pixi_file) as f:
195
+ old_pixi_config = json.load(f)
196
+ TasksPixiSettings(**old_pixi_config)
197
+ return old_pixi_config
198
+
199
+
200
+ def get_JobRunnerConfigSLURM(
201
+ old_config: dict[str, str | None]
202
+ ) -> dict[str, Any]:
203
+ slurm_file = old_config["FRACTAL_SLURM_CONFIG_FILE"]
204
+ with open(slurm_file) as f:
205
+ old_slurm_config = json.load(f)
206
+ JobRunnerConfigSLURM(**old_slurm_config)
207
+ return old_slurm_config
208
+
209
+
210
+ def get_ssh_host() -> str:
211
+ with next(get_sync_db()) as db:
212
+ res = db.execute(
213
+ select(UserSettings.ssh_host).where(
214
+ is_not(UserSettings.ssh_host, None)
215
+ )
216
+ )
217
+ hosts = res.scalars().all()
218
+ if len(set(hosts)) > 1:
219
+ host = max(set(hosts), key=hosts.count)
220
+ print(f"MOST FREQUENT HOST: {host}")
221
+ else:
222
+ host = hosts[0]
223
+ return host
224
+
225
+
226
+ def prepare_resource_data(old_config: dict[str, str | None]) -> dict[str, Any]:
227
+ settings = get_settings()
228
+
229
+ resource_data = dict(
230
+ type=settings.FRACTAL_RUNNER_BACKEND,
231
+ name="Resource Name",
232
+ tasks_python_config=get_TasksPythonSettings(old_config),
233
+ tasks_pixi_config=get_TasksPixiSettings(old_config),
234
+ jobs_runner_config=get_JobRunnerConfigSLURM(old_config),
235
+ tasks_local_dir=old_config["FRACTAL_TASKS_DIR"],
236
+ jobs_local_dir=old_config["FRACTAL_RUNNER_WORKING_BASE_DIR"],
237
+ jobs_slurm_python_worker=old_config["FRACTAL_SLURM_WORKER_PYTHON"],
238
+ jobs_poll_interval=int(
239
+ old_config.get("FRACTAL_SLURM_POLL_INTERVAL", 15)
240
+ ),
241
+ )
242
+ if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
243
+ resource_data["host"] = get_ssh_host()
244
+
245
+ resource_data = cast_serialize_resource(resource_data)
246
+
247
+ return resource_data
248
+
249
+
250
+ def fix_db():
251
+ # READ-ONLY CHECK
252
+
253
+ settings = get_settings()
254
+
255
+ # Verify that we are in a SLURM instance
256
+ if settings.FRACTAL_RUNNER_BACKEND == "local":
257
+ sys.exit(
258
+ "ERROR: FRACTAL_RUNNER_BACKEND='local' is not "
259
+ "supported for this data migration."
260
+ )
261
+
262
+ # Read old env file
263
+ old_config = get_old_dotenv_variables()
264
+
265
+ # Prepare resource data
266
+ resource_data = prepare_resource_data(old_config)
267
+
268
+ # Prepare profile/users data
269
+ profile_and_user_updates = prepare_profile_and_user_updates()
270
+
271
+ # ---------------------------------------
272
+
273
+ # WRITES
274
+
275
+ with next(get_sync_db()) as db:
276
+ # Create new resource
277
+ resource = Resource(**resource_data)
278
+ db.add(resource)
279
+ db.commit()
280
+ db.refresh(resource)
281
+ db.expunge(resource)
282
+ resource_id = resource.id
283
+ debug(f"CREATED RESOURCE with {resource_id=}")
284
+
285
+ # Update task groups
286
+ res = db.execute(select(TaskGroupV2).order_by(TaskGroupV2.id))
287
+ for taskgroup in res.scalars().all():
288
+ taskgroup.resource_id = resource_id
289
+ db.add(taskgroup)
290
+ db.commit()
291
+
292
+ # Update projects
293
+ res = db.execute(select(ProjectV2).order_by(ProjectV2.id))
294
+ for project in res.scalars().all():
295
+ project.resource_id = resource_id
296
+ db.add(project)
297
+ db.commit()
298
+
299
+ db.expunge_all()
300
+
301
+ for _, info in profile_and_user_updates.items():
302
+ debug(info)
303
+
304
+ # Create profile
305
+ profile_data = info.data
306
+ profile_data["resource_id"] = resource_id
307
+ profile = Profile(**profile_data)
308
+ db.add(profile)
309
+ db.commit()
310
+ db.refresh(profile)
311
+ db.expunge(profile)
312
+ profile_id = profile.id
313
+
314
+ # Update users
315
+ for user_update in info.user_updates:
316
+ user = db.get(UserOAuth, user_update.user_id)
317
+ user.profile_id = profile_id
318
+ user.project_dir = user_update.project_dir
319
+ user.slurm_accounts = user_update.slurm_accounts
320
+ db.add(user)
321
+ db.commit()
@@ -74,6 +74,9 @@ def simplify_pyproject_toml(
74
74
  return original_toml_string
75
75
 
76
76
  # Use a single platform (or skip, if not set)
77
+ # Note: we look both for `[workspace.platforms]` and `[project.platforms]`,
78
+ # even though `[project]` is deprecated as of
79
+ # https://pixi.sh/dev/CHANGELOG/#0570-2025-10-20.
77
80
  try:
78
81
  pixi_data["workspace"]["platforms"] = [pixi_platform]
79
82
  except KeyError:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fractal-server"
3
- version = "2.17.0a9"
3
+ version = "2.17.0a11"
4
4
  description = "Backend component of the Fractal analytics platform"
5
5
  authors = [
6
6
  { name="Tommaso Comparin", email="tommaso.comparin@exact-lab.it" },
@@ -94,7 +94,7 @@ filterwarnings = [
94
94
  markers = ["container", "ssh", "fails_on_macos", "oauth"]
95
95
 
96
96
  [tool.bumpver]
97
- current_version = "2.17.0a9"
97
+ current_version = "2.17.0a11"
98
98
  version_pattern = "MAJOR.MINOR.PATCH[PYTAGNUM]"
99
99
  commit_message = "bump version {old_version} -> {new_version}"
100
100
  commit = true
@@ -1 +0,0 @@
1
- __VERSION__ = "2.17.0a9"