fractal-server 2.8.1__tar.gz → 2.9.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.
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/PKG-INFO +2 -2
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/README.md +1 -1
- fractal_server-2.9.0a0/fractal_server/__init__.py +1 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v2/__init__.py +3 -3
- fractal_server-2.9.0a0/fractal_server/app/models/v2/task.py +48 -0
- fractal_server-2.8.1/fractal_server/app/models/v2/task.py → fractal_server-2.9.0a0/fractal_server/app/models/v2/task_group.py +25 -43
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/v1.py +1 -20
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/v2/job.py +1 -20
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/v2/task_group.py +53 -13
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/__init__.py +11 -2
- fractal_server-2.8.1/fractal_server/app/routes/api/v2/_aux_functions_task_collection.py → fractal_server-2.9.0a0/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +43 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +21 -14
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/task_collection.py +26 -51
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/task_collection_custom.py +3 -3
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/task_group.py +83 -14
- fractal_server-2.9.0a0/fractal_server/app/routes/api/v2/task_group_lifecycle.py +221 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/workflow.py +1 -1
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/workflow_import.py +2 -2
- fractal_server-2.9.0a0/fractal_server/app/routes/aux/_timestamp.py +25 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/__init__.py +3 -2
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/task_collection.py +0 -21
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/task_group.py +30 -6
- fractal_server-2.9.0a0/fractal_server/migrations/versions/3082479ac4ea_taskgroup_activity_and_venv_info_to_.py +105 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/ssh/_fabric.py +18 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/utils.py +2 -12
- fractal_server-2.9.0a0/fractal_server/tasks/v2/local/__init__.py +3 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/local/collect.py +291 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/local/deactivate.py +162 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/local/reactivate.py +159 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/local/utils_local.py +52 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/ssh/__init__.py +0 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/ssh/collect.py +387 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/ssh/deactivate.py +2 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/ssh/reactivate.py +2 -0
- fractal_server-2.8.1/fractal_server/tasks/v2/templates/_2_preliminary_pip_operations.sh → fractal_server-2.9.0a0/fractal_server/tasks/v2/templates/1_create_venv.sh +6 -7
- fractal_server-2.8.1/fractal_server/tasks/v2/templates/_3_pip_install.sh → fractal_server-2.9.0a0/fractal_server/tasks/v2/templates/2_pip_install.sh +8 -1
- fractal_server-2.8.1/fractal_server/tasks/v2/templates/_4_pip_freeze.sh → fractal_server-2.9.0a0/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -7
- fractal_server-2.8.1/fractal_server/tasks/v2/templates/_5_pip_show.sh → fractal_server-2.9.0a0/fractal_server/tasks/v2/templates/4_pip_show.sh +5 -6
- fractal_server-2.9.0a0/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +10 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +35 -0
- fractal_server-2.9.0a0/fractal_server/tasks/v2/utils_background.py +148 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v2/utils_templates.py +32 -2
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/utils.py +4 -2
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/pyproject.toml +2 -2
- fractal_server-2.8.1/fractal_server/__init__.py +0 -1
- fractal_server-2.8.1/fractal_server/app/models/v2/collection_state.py +0 -22
- fractal_server-2.8.1/fractal_server/tasks/v2/collection_local.py +0 -357
- fractal_server-2.8.1/fractal_server/tasks/v2/collection_ssh.py +0 -352
- fractal_server-2.8.1/fractal_server/tasks/v2/templates/_1_create_venv.sh +0 -42
- fractal_server-2.8.1/fractal_server/tasks/v2/utils_background.py +0 -209
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/LICENSE +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/__main__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v1/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v1/dataset.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v1/job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v1/project.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v1/state.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v1/task.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v1/workflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/v2/task.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/_aux_functions.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/dataset.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/project.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/task.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/task_collection.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/workflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v1/workflowtask.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/status.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/.gitignore +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/async_wrap.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/compress_folder.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/_batching.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/_slurm_config.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/remote.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/ssh/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/ssh/executor.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/sudo/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/extract_archive.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/run_subprocess.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/task_files.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_common.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_local/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_local/_local_config.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_local/_submit_setup.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_local/executor.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_slurm/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_slurm/_submit_setup.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/_slurm/get_slurm_config.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/common.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v1/handle_failed_job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local/_local_config.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local/_submit_setup.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local/executor.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local_experimental/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local_experimental/_local_config.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_local_experimental/executor.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_slurm_common/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_slurm_common/get_slurm_config.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_slurm_ssh/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_slurm_sudo/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/handle_failed_job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/runner.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/runner_functions.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/_validators.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/applyworkflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/dataset.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/dumps.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/manifest.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/project.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/state.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/task.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/task_collection.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v1/workflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/dataset.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/status.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/security/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/config.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/images/models.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/logger.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/main.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/README +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/script.py.mako +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/py.typed +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/string_tools.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/syringe.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v1/_TaskCollectPip.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v1/__init__.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v1/background_operations.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v1/endpoint_operations.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v1/get_collection_data.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v1/utils.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v2/__init__.py +0 -0
- /fractal_server-2.8.1/fractal_server/tasks/v2/database_operations.py → /fractal_server-2.9.0a0/fractal_server/tasks/v2/utils_database.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v2/utils_package_names.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/urls.py +0 -0
- {fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/zip_tools.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fractal-server
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.9.0a0
|
4
4
|
Summary: Server component of the Fractal analytics platform
|
5
5
|
Home-page: https://github.com/fractal-analytics-platform/fractal-server
|
6
6
|
License: BSD-3-Clause
|
@@ -38,7 +38,7 @@ Description-Content-Type: text/markdown
|
|
38
38
|
# Fractal Server
|
39
39
|
|
40
40
|
<p align="center">
|
41
|
-
<img src="https://
|
41
|
+
<img src="https://raw.githubusercontent.com/fractal-analytics-platform/fractal-logos/refs/heads/main/projects/fractal_server.png" alt="Fractal server" width="400">
|
42
42
|
</p>
|
43
43
|
|
44
44
|
[](https://pypi.org/project/fractal-server/)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Fractal Server
|
2
2
|
|
3
3
|
<p align="center">
|
4
|
-
<img src="https://
|
4
|
+
<img src="https://raw.githubusercontent.com/fractal-analytics-platform/fractal-logos/refs/heads/main/projects/fractal_server.png" alt="Fractal server" width="400">
|
5
5
|
</p>
|
6
6
|
|
7
7
|
[](https://pypi.org/project/fractal-server/)
|
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "2.9.0a0"
|
@@ -2,12 +2,12 @@
|
|
2
2
|
v2 `models` module
|
3
3
|
"""
|
4
4
|
from ..linkuserproject import LinkUserProjectV2
|
5
|
-
from .collection_state import CollectionStateV2
|
6
5
|
from .dataset import DatasetV2
|
7
6
|
from .job import JobV2
|
8
7
|
from .project import ProjectV2
|
9
|
-
from .task import TaskGroupV2
|
10
8
|
from .task import TaskV2
|
9
|
+
from .task_group import TaskGroupActivityV2
|
10
|
+
from .task_group import TaskGroupV2
|
11
11
|
from .workflow import WorkflowV2
|
12
12
|
from .workflowtask import WorkflowTaskV2
|
13
13
|
|
@@ -16,8 +16,8 @@ __all__ = [
|
|
16
16
|
"DatasetV2",
|
17
17
|
"JobV2",
|
18
18
|
"ProjectV2",
|
19
|
-
"CollectionStateV2",
|
20
19
|
"TaskGroupV2",
|
20
|
+
"TaskGroupActivityV2",
|
21
21
|
"TaskV2",
|
22
22
|
"WorkflowTaskV2",
|
23
23
|
"WorkflowV2",
|
@@ -0,0 +1,48 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from pydantic import HttpUrl
|
5
|
+
from sqlalchemy import Column
|
6
|
+
from sqlalchemy.types import JSON
|
7
|
+
from sqlmodel import Field
|
8
|
+
from sqlmodel import SQLModel
|
9
|
+
|
10
|
+
|
11
|
+
class TaskV2(SQLModel, table=True):
|
12
|
+
id: Optional[int] = Field(default=None, primary_key=True)
|
13
|
+
name: str
|
14
|
+
|
15
|
+
type: str
|
16
|
+
command_non_parallel: Optional[str] = None
|
17
|
+
command_parallel: Optional[str] = None
|
18
|
+
source: Optional[str] = None
|
19
|
+
|
20
|
+
meta_non_parallel: dict[str, Any] = Field(
|
21
|
+
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
22
|
+
)
|
23
|
+
meta_parallel: dict[str, Any] = Field(
|
24
|
+
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
25
|
+
)
|
26
|
+
|
27
|
+
version: Optional[str] = None
|
28
|
+
args_schema_non_parallel: Optional[dict[str, Any]] = Field(
|
29
|
+
sa_column=Column(JSON), default=None
|
30
|
+
)
|
31
|
+
args_schema_parallel: Optional[dict[str, Any]] = Field(
|
32
|
+
sa_column=Column(JSON), default=None
|
33
|
+
)
|
34
|
+
args_schema_version: Optional[str]
|
35
|
+
docs_info: Optional[str] = None
|
36
|
+
docs_link: Optional[HttpUrl] = None
|
37
|
+
|
38
|
+
input_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
39
|
+
output_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
40
|
+
|
41
|
+
taskgroupv2_id: int = Field(foreign_key="taskgroupv2.id")
|
42
|
+
|
43
|
+
category: Optional[str] = None
|
44
|
+
modality: Optional[str] = None
|
45
|
+
authors: Optional[str] = None
|
46
|
+
tags: list[str] = Field(
|
47
|
+
sa_column=Column(JSON, server_default="[]", nullable=False)
|
48
|
+
)
|
@@ -1,8 +1,6 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import Any
|
3
2
|
from typing import Optional
|
4
3
|
|
5
|
-
from pydantic import HttpUrl
|
6
4
|
from sqlalchemy import Column
|
7
5
|
from sqlalchemy.types import DateTime
|
8
6
|
from sqlalchemy.types import JSON
|
@@ -10,49 +8,10 @@ from sqlmodel import Field
|
|
10
8
|
from sqlmodel import Relationship
|
11
9
|
from sqlmodel import SQLModel
|
12
10
|
|
11
|
+
from .task import TaskV2
|
13
12
|
from fractal_server.utils import get_timestamp
|
14
13
|
|
15
14
|
|
16
|
-
class TaskV2(SQLModel, table=True):
|
17
|
-
id: Optional[int] = Field(default=None, primary_key=True)
|
18
|
-
name: str
|
19
|
-
|
20
|
-
type: str
|
21
|
-
command_non_parallel: Optional[str] = None
|
22
|
-
command_parallel: Optional[str] = None
|
23
|
-
source: Optional[str] = None
|
24
|
-
|
25
|
-
meta_non_parallel: dict[str, Any] = Field(
|
26
|
-
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
27
|
-
)
|
28
|
-
meta_parallel: dict[str, Any] = Field(
|
29
|
-
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
30
|
-
)
|
31
|
-
|
32
|
-
version: Optional[str] = None
|
33
|
-
args_schema_non_parallel: Optional[dict[str, Any]] = Field(
|
34
|
-
sa_column=Column(JSON), default=None
|
35
|
-
)
|
36
|
-
args_schema_parallel: Optional[dict[str, Any]] = Field(
|
37
|
-
sa_column=Column(JSON), default=None
|
38
|
-
)
|
39
|
-
args_schema_version: Optional[str]
|
40
|
-
docs_info: Optional[str] = None
|
41
|
-
docs_link: Optional[HttpUrl] = None
|
42
|
-
|
43
|
-
input_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
44
|
-
output_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
45
|
-
|
46
|
-
taskgroupv2_id: int = Field(foreign_key="taskgroupv2.id")
|
47
|
-
|
48
|
-
category: Optional[str] = None
|
49
|
-
modality: Optional[str] = None
|
50
|
-
authors: Optional[str] = None
|
51
|
-
tags: list[str] = Field(
|
52
|
-
sa_column=Column(JSON, server_default="[]", nullable=False)
|
53
|
-
)
|
54
|
-
|
55
|
-
|
56
15
|
class TaskGroupV2(SQLModel, table=True):
|
57
16
|
id: Optional[int] = Field(default=None, primary_key=True)
|
58
17
|
task_list: list[TaskV2] = Relationship(
|
@@ -69,7 +28,6 @@ class TaskGroupV2(SQLModel, table=True):
|
|
69
28
|
version: Optional[str] = None
|
70
29
|
python_version: Optional[str] = None
|
71
30
|
path: Optional[str] = None
|
72
|
-
venv_path: Optional[str] = None
|
73
31
|
wheel_path: Optional[str] = None
|
74
32
|
pip_extras: Optional[str] = None
|
75
33
|
pinned_package_versions: dict[str, str] = Field(
|
@@ -80,6 +38,10 @@ class TaskGroupV2(SQLModel, table=True):
|
|
80
38
|
nullable=True,
|
81
39
|
),
|
82
40
|
)
|
41
|
+
pip_freeze: Optional[str] = None
|
42
|
+
venv_path: Optional[str] = None
|
43
|
+
venv_size_in_kB: Optional[int] = None
|
44
|
+
venv_file_number: Optional[int] = None
|
83
45
|
|
84
46
|
active: bool = True
|
85
47
|
timestamp_created: datetime = Field(
|
@@ -118,3 +80,23 @@ class TaskGroupV2(SQLModel, table=True):
|
|
118
80
|
]
|
119
81
|
)
|
120
82
|
return output
|
83
|
+
|
84
|
+
|
85
|
+
class TaskGroupActivityV2(SQLModel, table=True):
|
86
|
+
|
87
|
+
id: Optional[int] = Field(default=None, primary_key=True)
|
88
|
+
user_id: int = Field(foreign_key="user_oauth.id")
|
89
|
+
taskgroupv2_id: Optional[int] = Field(foreign_key="taskgroupv2.id")
|
90
|
+
timestamp_started: datetime = Field(
|
91
|
+
default_factory=get_timestamp,
|
92
|
+
sa_column=Column(DateTime(timezone=True), nullable=False),
|
93
|
+
)
|
94
|
+
pkg_name: str
|
95
|
+
version: str
|
96
|
+
status: str
|
97
|
+
action: str
|
98
|
+
log: Optional[str] = None
|
99
|
+
timestamp_ended: Optional[datetime] = Field(
|
100
|
+
default=None,
|
101
|
+
sa_column=Column(DateTime(timezone=True)),
|
102
|
+
)
|
@@ -2,7 +2,6 @@
|
|
2
2
|
Definition of `/admin` routes.
|
3
3
|
"""
|
4
4
|
from datetime import datetime
|
5
|
-
from datetime import timezone
|
6
5
|
from pathlib import Path
|
7
6
|
from typing import Optional
|
8
7
|
|
@@ -15,8 +14,6 @@ from fastapi.responses import StreamingResponse
|
|
15
14
|
from sqlalchemy import func
|
16
15
|
from sqlmodel import select
|
17
16
|
|
18
|
-
from ....config import get_settings
|
19
|
-
from ....syringe import Inject
|
20
17
|
from ....utils import get_timestamp
|
21
18
|
from ....zip_tools import _zip_folder_to_byte_stream_iterator
|
22
19
|
from ...db import AsyncSession
|
@@ -36,27 +33,11 @@ from ..aux._job import _write_shutdown_file
|
|
36
33
|
from ..aux._runner import _check_shutdown_is_supported
|
37
34
|
from fractal_server.app.models import UserOAuth
|
38
35
|
from fractal_server.app.routes.auth import current_active_superuser
|
36
|
+
from fractal_server.app.routes.aux._timestamp import _convert_to_db_timestamp
|
39
37
|
|
40
38
|
router_admin_v1 = APIRouter()
|
41
39
|
|
42
40
|
|
43
|
-
def _convert_to_db_timestamp(dt: datetime) -> datetime:
|
44
|
-
"""
|
45
|
-
This function takes a timezone-aware datetime and converts it to UTC.
|
46
|
-
If using SQLite, it also removes the timezone information in order to make
|
47
|
-
the datetime comparable with datetimes in the database.
|
48
|
-
"""
|
49
|
-
if dt.tzinfo is None:
|
50
|
-
raise HTTPException(
|
51
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
52
|
-
detail=f"The timestamp provided has no timezone information: {dt}",
|
53
|
-
)
|
54
|
-
_dt = dt.astimezone(timezone.utc)
|
55
|
-
if Inject(get_settings).DB_ENGINE == "sqlite":
|
56
|
-
return _dt.replace(tzinfo=None)
|
57
|
-
return _dt
|
58
|
-
|
59
|
-
|
60
41
|
@router_admin_v1.get("/project/", response_model=list[ProjectReadV1])
|
61
42
|
async def view_project(
|
62
43
|
id: Optional[int] = None,
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from datetime import timezone
|
3
2
|
from pathlib import Path
|
4
3
|
from typing import Optional
|
5
4
|
|
@@ -19,35 +18,17 @@ from fractal_server.app.models.v2 import ProjectV2
|
|
19
18
|
from fractal_server.app.routes.auth import current_active_superuser
|
20
19
|
from fractal_server.app.routes.aux._job import _write_shutdown_file
|
21
20
|
from fractal_server.app.routes.aux._runner import _check_shutdown_is_supported
|
21
|
+
from fractal_server.app.routes.aux._timestamp import _convert_to_db_timestamp
|
22
22
|
from fractal_server.app.runner.filenames import WORKFLOW_LOG_FILENAME
|
23
23
|
from fractal_server.app.schemas.v2 import JobReadV2
|
24
24
|
from fractal_server.app.schemas.v2 import JobStatusTypeV2
|
25
25
|
from fractal_server.app.schemas.v2 import JobUpdateV2
|
26
|
-
from fractal_server.config import get_settings
|
27
|
-
from fractal_server.syringe import Inject
|
28
26
|
from fractal_server.utils import get_timestamp
|
29
27
|
from fractal_server.zip_tools import _zip_folder_to_byte_stream_iterator
|
30
28
|
|
31
29
|
router = APIRouter()
|
32
30
|
|
33
31
|
|
34
|
-
def _convert_to_db_timestamp(dt: datetime) -> datetime:
|
35
|
-
"""
|
36
|
-
This function takes a timezone-aware datetime and converts it to UTC.
|
37
|
-
If using SQLite, it also removes the timezone information in order to make
|
38
|
-
the datetime comparable with datetimes in the database.
|
39
|
-
"""
|
40
|
-
if dt.tzinfo is None:
|
41
|
-
raise HTTPException(
|
42
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
43
|
-
detail=f"The timestamp provided has no timezone information: {dt}",
|
44
|
-
)
|
45
|
-
_dt = dt.astimezone(timezone.utc)
|
46
|
-
if Inject(get_settings).DB_ENGINE == "sqlite":
|
47
|
-
return _dt.replace(tzinfo=None)
|
48
|
-
return _dt
|
49
|
-
|
50
|
-
|
51
32
|
@router.get("/", response_model=list[JobReadV2])
|
52
33
|
async def view_job(
|
53
34
|
id: Optional[int] = None,
|
{fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/admin/v2/task_group.py
RENAMED
@@ -1,3 +1,4 @@
|
|
1
|
+
from datetime import datetime
|
1
2
|
from typing import Optional
|
2
3
|
|
3
4
|
from fastapi import APIRouter
|
@@ -12,13 +13,16 @@ from sqlmodel import select
|
|
12
13
|
from fractal_server.app.db import AsyncSession
|
13
14
|
from fractal_server.app.db import get_async_db
|
14
15
|
from fractal_server.app.models import UserOAuth
|
15
|
-
from fractal_server.app.models.v2 import
|
16
|
+
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
16
17
|
from fractal_server.app.models.v2 import TaskGroupV2
|
17
18
|
from fractal_server.app.models.v2 import WorkflowTaskV2
|
18
19
|
from fractal_server.app.routes.auth import current_active_superuser
|
19
20
|
from fractal_server.app.routes.auth._aux_auth import (
|
20
21
|
_verify_user_belongs_to_group,
|
21
22
|
)
|
23
|
+
from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
|
24
|
+
from fractal_server.app.schemas.v2 import TaskGroupActivityStatusV2
|
25
|
+
from fractal_server.app.schemas.v2 import TaskGroupActivityV2Read
|
22
26
|
from fractal_server.app.schemas.v2 import TaskGroupReadV2
|
23
27
|
from fractal_server.app.schemas.v2 import TaskGroupUpdateV2
|
24
28
|
from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
|
@@ -29,6 +33,42 @@ router = APIRouter()
|
|
29
33
|
logger = set_logger(__name__)
|
30
34
|
|
31
35
|
|
36
|
+
@router.get("/activity/", response_model=list[TaskGroupActivityV2Read])
|
37
|
+
async def get_task_group_activity_list(
|
38
|
+
task_group_activity_id: Optional[int] = None,
|
39
|
+
user_id: Optional[int] = None,
|
40
|
+
taskgroupv2_id: Optional[int] = None,
|
41
|
+
pkg_name: Optional[str] = None,
|
42
|
+
status: Optional[TaskGroupActivityStatusV2] = None,
|
43
|
+
action: Optional[TaskGroupActivityActionV2] = None,
|
44
|
+
timestamp_started_min: Optional[datetime] = None,
|
45
|
+
superuser: UserOAuth = Depends(current_active_superuser),
|
46
|
+
db: AsyncSession = Depends(get_async_db),
|
47
|
+
) -> list[TaskGroupActivityV2Read]:
|
48
|
+
|
49
|
+
stm = select(TaskGroupActivityV2)
|
50
|
+
if task_group_activity_id is not None:
|
51
|
+
stm = stm.where(TaskGroupActivityV2.id == task_group_activity_id)
|
52
|
+
if user_id:
|
53
|
+
stm = stm.where(TaskGroupActivityV2.user_id == user_id)
|
54
|
+
if taskgroupv2_id:
|
55
|
+
stm = stm.where(TaskGroupActivityV2.taskgroupv2_id == taskgroupv2_id)
|
56
|
+
if pkg_name:
|
57
|
+
stm = stm.where(TaskGroupActivityV2.pkg_name.icontains(pkg_name))
|
58
|
+
if status:
|
59
|
+
stm = stm.where(TaskGroupActivityV2.status == status)
|
60
|
+
if action:
|
61
|
+
stm = stm.where(TaskGroupActivityV2.action == action)
|
62
|
+
if timestamp_started_min is not None:
|
63
|
+
stm = stm.where(
|
64
|
+
TaskGroupActivityV2.timestamp_started >= timestamp_started_min
|
65
|
+
)
|
66
|
+
|
67
|
+
res = await db.execute(stm)
|
68
|
+
activities = res.scalars().all()
|
69
|
+
return activities
|
70
|
+
|
71
|
+
|
32
72
|
@router.get("/{task_group_id}/", response_model=TaskGroupReadV2)
|
33
73
|
async def query_task_group(
|
34
74
|
task_group_id: int,
|
@@ -139,22 +179,22 @@ async def delete_task_group(
|
|
139
179
|
detail=f"TaskV2 {workflow_tasks[0].task_id} is still in use",
|
140
180
|
)
|
141
181
|
|
142
|
-
# Cascade operations: set foreign-keys to null for
|
143
|
-
# are in relationship with the current TaskGroupV2
|
144
|
-
logger.debug("Start of cascade operations on
|
145
|
-
stm = select(
|
146
|
-
|
182
|
+
# Cascade operations: set foreign-keys to null for TaskGroupActivityV2
|
183
|
+
# which are in relationship with the current TaskGroupV2
|
184
|
+
logger.debug("Start of cascade operations on TaskGroupActivityV2.")
|
185
|
+
stm = select(TaskGroupActivityV2).where(
|
186
|
+
TaskGroupActivityV2.taskgroupv2_id == task_group_id
|
147
187
|
)
|
148
188
|
res = await db.execute(stm)
|
149
|
-
|
150
|
-
for
|
189
|
+
task_group_activity_list = res.scalars().all()
|
190
|
+
for task_group_activity in task_group_activity_list:
|
151
191
|
logger.debug(
|
152
|
-
f"Setting
|
153
|
-
"to None."
|
192
|
+
f"Setting TaskGroupActivityV2[{task_group_activity.id}]"
|
193
|
+
".taskgroupv2_id to None."
|
154
194
|
)
|
155
|
-
|
156
|
-
db.add(
|
157
|
-
logger.debug("End of cascade operations on
|
195
|
+
task_group_activity.taskgroupv2_id = None
|
196
|
+
db.add(task_group_activity)
|
197
|
+
logger.debug("End of cascade operations on TaskGroupActivityV2.")
|
158
198
|
|
159
199
|
await db.delete(task_group)
|
160
200
|
await db.commit()
|
{fractal_server-2.8.1 → fractal_server-2.9.0a0}/fractal_server/app/routes/api/v2/__init__.py
RENAMED
@@ -13,6 +13,7 @@ from .task import router as task_router_v2
|
|
13
13
|
from .task_collection import router as task_collection_router_v2
|
14
14
|
from .task_collection_custom import router as task_collection_router_v2_custom
|
15
15
|
from .task_group import router as task_group_router_v2
|
16
|
+
from .task_group_lifecycle import router as task_group_lifecycle_router_v2
|
16
17
|
from .workflow import router as workflow_router_v2
|
17
18
|
from .workflow_import import router as workflow_import_router_v2
|
18
19
|
from .workflowtask import router as workflowtask_router_v2
|
@@ -31,13 +32,21 @@ router_api_v2.include_router(submit_job_router_v2, tags=["V2 Job"])
|
|
31
32
|
|
32
33
|
settings = Inject(get_settings)
|
33
34
|
router_api_v2.include_router(
|
34
|
-
task_collection_router_v2,
|
35
|
+
task_collection_router_v2,
|
36
|
+
prefix="/task",
|
37
|
+
tags=["V2 Task Lifecycle"],
|
35
38
|
)
|
36
39
|
router_api_v2.include_router(
|
37
40
|
task_collection_router_v2_custom,
|
38
41
|
prefix="/task",
|
39
|
-
tags=["V2 Task
|
42
|
+
tags=["V2 Task Lifecycle"],
|
43
|
+
)
|
44
|
+
router_api_v2.include_router(
|
45
|
+
task_group_lifecycle_router_v2,
|
46
|
+
prefix="/task-group",
|
47
|
+
tags=["V2 Task Lifecycle"],
|
40
48
|
)
|
49
|
+
|
41
50
|
router_api_v2.include_router(task_router_v2, prefix="/task", tags=["V2 Task"])
|
42
51
|
router_api_v2.include_router(
|
43
52
|
task_group_router_v2, prefix="/task-group", tags=["V2 TaskGroup"]
|
@@ -4,7 +4,11 @@ from fastapi import HTTPException
|
|
4
4
|
from fastapi import status
|
5
5
|
from httpx import AsyncClient
|
6
6
|
from httpx import TimeoutException
|
7
|
+
from sqlmodel import select
|
7
8
|
|
9
|
+
from fractal_server.app.db import AsyncSession
|
10
|
+
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
11
|
+
from fractal_server.app.schemas.v2 import TaskGroupActivityStatusV2
|
8
12
|
from fractal_server.logger import set_logger
|
9
13
|
|
10
14
|
|
@@ -122,3 +126,42 @@ async def get_package_version_from_pypi(
|
|
122
126
|
# Case 3: `version` is unset and we use latest
|
123
127
|
logger.info(f"No version requested, returning {latest_version=}.")
|
124
128
|
return latest_version
|
129
|
+
|
130
|
+
|
131
|
+
async def check_no_ongoing_activity(
|
132
|
+
*,
|
133
|
+
task_group_id: int,
|
134
|
+
db: AsyncSession,
|
135
|
+
) -> None:
|
136
|
+
"""
|
137
|
+
Find ongoing activities for the same task group.
|
138
|
+
|
139
|
+
Arguments:
|
140
|
+
task_group_id:
|
141
|
+
db:
|
142
|
+
"""
|
143
|
+
# DB query
|
144
|
+
stm = (
|
145
|
+
select(TaskGroupActivityV2)
|
146
|
+
.where(TaskGroupActivityV2.taskgroupv2_id == task_group_id)
|
147
|
+
.where(TaskGroupActivityV2.status == TaskGroupActivityStatusV2.ONGOING)
|
148
|
+
)
|
149
|
+
res = await db.execute(stm)
|
150
|
+
ongoing_activities = res.scalars().all()
|
151
|
+
|
152
|
+
if ongoing_activities == []:
|
153
|
+
# All good, exit
|
154
|
+
return
|
155
|
+
|
156
|
+
msg = "Found ongoing activities for the same task-group:"
|
157
|
+
for ind, activity in enumerate(ongoing_activities):
|
158
|
+
msg = (
|
159
|
+
f"{msg}\n{ind + 1}) "
|
160
|
+
f"Action={activity.action}, "
|
161
|
+
f"status={activity.status}, "
|
162
|
+
f"timestamp_started={activity.timestamp_started}."
|
163
|
+
)
|
164
|
+
raise HTTPException(
|
165
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
166
|
+
detail=msg,
|
167
|
+
)
|
@@ -13,7 +13,7 @@ from fractal_server.app.db import AsyncSession
|
|
13
13
|
from fractal_server.app.models import LinkUserGroup
|
14
14
|
from fractal_server.app.models import UserGroup
|
15
15
|
from fractal_server.app.models import UserOAuth
|
16
|
-
from fractal_server.app.models.v2 import
|
16
|
+
from fractal_server.app.models.v2 import TaskGroupActivityV2
|
17
17
|
from fractal_server.app.models.v2 import TaskGroupV2
|
18
18
|
from fractal_server.app.models.v2 import TaskV2
|
19
19
|
from fractal_server.app.models.v2 import WorkflowTaskV2
|
@@ -21,6 +21,7 @@ from fractal_server.app.routes.auth._aux_auth import _get_default_usergroup_id
|
|
21
21
|
from fractal_server.app.routes.auth._aux_auth import (
|
22
22
|
_verify_user_belongs_to_group,
|
23
23
|
)
|
24
|
+
from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
|
24
25
|
from fractal_server.logger import set_logger
|
25
26
|
|
26
27
|
logger = set_logger(__name__)
|
@@ -219,27 +220,29 @@ async def _get_valid_user_group_id(
|
|
219
220
|
return user_group_id
|
220
221
|
|
221
222
|
|
222
|
-
async def
|
223
|
+
async def _get_collection_task_group_activity_status_message(
|
223
224
|
task_group: TaskGroupV2, db: AsyncSession
|
224
225
|
) -> str:
|
225
226
|
res = await db.execute(
|
226
|
-
select(
|
227
|
-
|
227
|
+
select(TaskGroupActivityV2).where(
|
228
|
+
TaskGroupActivityV2.taskgroupv2_id == task_group.id
|
229
|
+
and TaskGroupActivityV2.action == TaskGroupActivityActionV2.COLLECT
|
228
230
|
)
|
229
231
|
)
|
230
|
-
|
231
|
-
if len(
|
232
|
+
task_group_activity_list = res.scalars().all()
|
233
|
+
if len(task_group_activity_list) > 1:
|
232
234
|
msg = (
|
233
|
-
"Expected one
|
234
|
-
f"{task_group.id}, found {len(
|
235
|
-
f"(IDs: {[
|
235
|
+
"Expected one TaskGroupActivityV2 associated to TaskGroup "
|
236
|
+
f"{task_group.id}, found {len(task_group_activity_list)} "
|
237
|
+
f"(IDs: {[tga.id for tga in task_group_activity_list]}).\n"
|
236
238
|
"Warning: this should have not happened, please contact an admin."
|
237
239
|
)
|
238
|
-
elif len(
|
240
|
+
elif len(task_group_activity_list) == 1:
|
239
241
|
msg = (
|
240
|
-
|
242
|
+
"\nThere exists a task-group activity"
|
243
|
+
f"(ID={task_group_activity_list[0].id}) for "
|
241
244
|
f"such task group (ID={task_group.id}), with status "
|
242
|
-
f"'{
|
245
|
+
f"'{task_group_activity_list[0].status}'."
|
243
246
|
)
|
244
247
|
else:
|
245
248
|
msg = ""
|
@@ -273,7 +276,9 @@ async def _verify_non_duplication_user_constraint(
|
|
273
276
|
"This should have not happened: please contact an admin."
|
274
277
|
),
|
275
278
|
)
|
276
|
-
state_msg = await
|
279
|
+
state_msg = await _get_collection_task_group_activity_status_message(
|
280
|
+
duplicate[0], db
|
281
|
+
)
|
277
282
|
raise HTTPException(
|
278
283
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
279
284
|
detail=(
|
@@ -313,7 +318,9 @@ async def _verify_non_duplication_group_constraint(
|
|
313
318
|
"This should have not happened: please contact an admin."
|
314
319
|
),
|
315
320
|
)
|
316
|
-
state_msg = await
|
321
|
+
state_msg = await _get_collection_task_group_activity_status_message(
|
322
|
+
duplicate[0], db
|
323
|
+
)
|
317
324
|
raise HTTPException(
|
318
325
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
319
326
|
detail=(
|