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