fractal-server 2.7.0a4__tar.gz → 2.7.0a5__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.7.0a4 → fractal_server-2.7.0a5}/PKG-INFO +1 -1
- fractal_server-2.7.0a5/fractal_server/__init__.py +1 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/v2/task.py +0 -5
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/task_collection.py +2 -2
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/_aux_functions.py +1 -7
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/task_collection.py +49 -39
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/task_group.py +10 -6
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/workflowtask.py +0 -1
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/dumps.py +0 -1
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/task.py +1 -6
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/workflowtask.py +0 -3
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/utils.py +19 -5
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/background_operations.py +3 -3
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/get_collection_data.py +2 -2
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/background_operations.py +4 -4
- fractal_server-2.7.0a5/fractal_server/tasks/v2/endpoint_operations.py +124 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/pyproject.toml +2 -2
- fractal_server-2.7.0a4/fractal_server/__init__.py +0 -1
- fractal_server-2.7.0a4/fractal_server/tasks/v2/endpoint_operations.py +0 -44
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/LICENSE +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/README.md +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/__main__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v1/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v1/dataset.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v1/job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v1/project.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v1/state.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v1/task.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v1/workflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/collection_state.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/task.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/v1.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/v2/job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/_aux_functions.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/dataset.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/project.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/task.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/workflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v1/workflowtask.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/status.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/workflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/.gitignore +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/async_wrap.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/compress_folder.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/_batching.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/_slurm_config.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/remote.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/ssh/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/ssh/executor.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/sudo/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/extract_archive.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/run_subprocess.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/task_files.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_common.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_local/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_local/_local_config.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_local/_submit_setup.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_local/executor.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_slurm/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_slurm/_submit_setup.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/_slurm/get_slurm_config.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/common.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v1/handle_failed_job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local/_local_config.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local/_submit_setup.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local/executor.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local_experimental/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local_experimental/_local_config.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_local_experimental/executor.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_slurm_common/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_slurm_common/get_slurm_config.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_slurm_ssh/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_slurm_sudo/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/handle_failed_job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/runner.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/runner_functions.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/_validators.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/applyworkflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/dataset.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/dumps.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/manifest.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/project.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/state.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/task.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/task_collection.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v1/workflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/dataset.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/status.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/task_collection.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/task_group.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/security/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/config.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/data_migrations/2_7_0.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/images/models.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/logger.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/main.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/README +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/script.py.mako +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/py.typed +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/ssh/_fabric.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/string_tools.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/syringe.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/_TaskCollectPip.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/endpoint_operations.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/utils.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/_venv_pip.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/background_operations_ssh.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/database_operations.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/templates/_1_create_venv.sh +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/templates/_2_upgrade_pip.sh +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/templates/_3_pip_install.sh +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/templates/_4_pip_freeze.sh +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/templates/_5_pip_show.sh +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/utils.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/urls.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/utils.py +0 -0
- {fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/zip_tools.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "2.7.0a5"
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/admin/v2/task.py
RENAMED
@@ -29,7 +29,6 @@ class TaskV2Minimal(BaseModel):
|
|
29
29
|
command_non_parallel: Optional[str] = None
|
30
30
|
command_parallel: Optional[str]
|
31
31
|
source: Optional[str] = None
|
32
|
-
owner: Optional[str] = None
|
33
32
|
version: Optional[str] = None
|
34
33
|
|
35
34
|
|
@@ -60,7 +59,6 @@ async def query_tasks(
|
|
60
59
|
source: Optional[str] = None,
|
61
60
|
version: Optional[str] = None,
|
62
61
|
name: Optional[str] = None,
|
63
|
-
owner: Optional[str] = None,
|
64
62
|
max_number_of_results: int = 25,
|
65
63
|
user: UserOAuth = Depends(current_active_superuser),
|
66
64
|
db: AsyncSession = Depends(get_async_db),
|
@@ -75,7 +73,6 @@ async def query_tasks(
|
|
75
73
|
`task.source`.
|
76
74
|
version: If not `None`, query for matching `task.version`.
|
77
75
|
name: If not `None`, query for contained case insensitive `task.name`.
|
78
|
-
owner: If not `None`, query for matching `task.owner`.
|
79
76
|
max_number_of_results: The maximum length of the response.
|
80
77
|
"""
|
81
78
|
|
@@ -89,8 +86,6 @@ async def query_tasks(
|
|
89
86
|
stm = stm.where(TaskV2.version == version)
|
90
87
|
if name is not None:
|
91
88
|
stm = stm.where(TaskV2.name.icontains(name))
|
92
|
-
if owner is not None:
|
93
|
-
stm = stm.where(TaskV2.owner == owner)
|
94
89
|
|
95
90
|
res = await db.execute(stm)
|
96
91
|
task_list = res.scalars().all()
|
@@ -27,7 +27,7 @@ from fractal_server.app.models import UserOAuth
|
|
27
27
|
from fractal_server.app.routes.auth import current_active_user
|
28
28
|
from fractal_server.app.routes.auth import current_active_verified_user
|
29
29
|
from fractal_server.string_tools import slugify_task_name_for_source_v1
|
30
|
-
from fractal_server.tasks.utils import
|
30
|
+
from fractal_server.tasks.utils import get_collection_log_v1
|
31
31
|
from fractal_server.tasks.v1._TaskCollectPip import _TaskCollectPip
|
32
32
|
from fractal_server.tasks.v1.background_operations import (
|
33
33
|
background_collect_pip,
|
@@ -232,7 +232,7 @@ async def check_collection_status(
|
|
232
232
|
# In some cases (i.e. a successful or ongoing task collection), data.log is
|
233
233
|
# not set; if so, we collect the current logs
|
234
234
|
if verbose and not data.log:
|
235
|
-
data.log =
|
235
|
+
data.log = get_collection_log_v1(data.venv_path)
|
236
236
|
state.data = data.sanitised_dict()
|
237
237
|
close_logger(logger)
|
238
238
|
await db.close()
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/_aux_functions.py
RENAMED
@@ -332,7 +332,6 @@ async def _workflow_insert_task(
|
|
332
332
|
*,
|
333
333
|
workflow_id: int,
|
334
334
|
task_id: int,
|
335
|
-
order: Optional[int] = None,
|
336
335
|
meta_parallel: Optional[dict[str, Any]] = None,
|
337
336
|
meta_non_parallel: Optional[dict[str, Any]] = None,
|
338
337
|
args_non_parallel: Optional[dict[str, Any]] = None,
|
@@ -347,7 +346,6 @@ async def _workflow_insert_task(
|
|
347
346
|
workflow_id:
|
348
347
|
task_id:
|
349
348
|
|
350
|
-
order:
|
351
349
|
meta_parallel:
|
352
350
|
meta_non_parallel:
|
353
351
|
args_non_parallel:
|
@@ -359,9 +357,6 @@ async def _workflow_insert_task(
|
|
359
357
|
if db_workflow is None:
|
360
358
|
raise ValueError(f"Workflow {workflow_id} does not exist")
|
361
359
|
|
362
|
-
if order is None:
|
363
|
-
order = len(db_workflow.task_list)
|
364
|
-
|
365
360
|
# Get task from db
|
366
361
|
db_task = await db.get(TaskV2, task_id)
|
367
362
|
if db_task is None:
|
@@ -397,8 +392,7 @@ async def _workflow_insert_task(
|
|
397
392
|
meta_non_parallel=final_meta_non_parallel,
|
398
393
|
**input_filters_kwarg,
|
399
394
|
)
|
400
|
-
db_workflow.task_list.
|
401
|
-
db_workflow.task_list.reorder() # type: ignore
|
395
|
+
db_workflow.task_list.append(wf_task)
|
402
396
|
flag_modified(db_workflow, "task_list")
|
403
397
|
await db.commit()
|
404
398
|
|
@@ -31,7 +31,7 @@ from fractal_server.app.models import UserOAuth
|
|
31
31
|
from fractal_server.app.routes.auth import current_active_user
|
32
32
|
from fractal_server.app.routes.auth import current_active_verified_user
|
33
33
|
from fractal_server.tasks.utils import _normalize_package_name
|
34
|
-
from fractal_server.tasks.utils import
|
34
|
+
from fractal_server.tasks.utils import get_collection_log_v2
|
35
35
|
from fractal_server.tasks.v2.background_operations import (
|
36
36
|
background_collect_pip,
|
37
37
|
)
|
@@ -70,33 +70,40 @@ async def collect_tasks_pip(
|
|
70
70
|
# Get settings
|
71
71
|
settings = Inject(get_settings)
|
72
72
|
|
73
|
+
# Initialize task-group attributes
|
74
|
+
task_group_attrs = dict(user_id=user.id)
|
75
|
+
|
73
76
|
# Set/check python version
|
74
77
|
if task_collect.python_version is None:
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
+
task_group_attrs[
|
79
|
+
"python_version"
|
80
|
+
] = settings.FRACTAL_TASKS_PYTHON_DEFAULT_VERSION
|
81
|
+
else:
|
82
|
+
task_group_attrs["python_version"] = task_collect.python_version
|
78
83
|
try:
|
79
|
-
get_python_interpreter_v2(
|
84
|
+
get_python_interpreter_v2(
|
85
|
+
python_version=task_group_attrs["python_version"]
|
86
|
+
)
|
80
87
|
except ValueError:
|
81
88
|
raise HTTPException(
|
82
89
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
83
90
|
detail=(
|
84
|
-
f"Python version {
|
91
|
+
f"Python version {task_group_attrs['python_version']} is "
|
85
92
|
"not available for Fractal task collection."
|
86
93
|
),
|
87
94
|
)
|
88
95
|
|
89
|
-
#
|
90
|
-
task_group_attrs = dict(
|
91
|
-
user_id=user.id,
|
92
|
-
python_version=task_collect.python_version,
|
93
|
-
)
|
96
|
+
# Set pip_extras
|
94
97
|
if task_collect.package_extras is not None:
|
95
98
|
task_group_attrs["pip_extras"] = task_collect.package_extras
|
99
|
+
|
100
|
+
# Set pinned_package_versions
|
96
101
|
if task_collect.pinned_package_versions is not None:
|
97
102
|
task_group_attrs[
|
98
103
|
"pinned_package_versions"
|
99
104
|
] = task_collect.pinned_package_versions
|
105
|
+
|
106
|
+
# Set pkg_name, version, origin and wheel_path
|
100
107
|
if task_collect.package.endswith(".whl"):
|
101
108
|
try:
|
102
109
|
task_group_attrs["wheel_path"] = task_collect.package
|
@@ -119,19 +126,11 @@ async def collect_tasks_pip(
|
|
119
126
|
pkg_name = task_collect.package
|
120
127
|
task_group_attrs["pkg_name"] = _normalize_package_name(pkg_name)
|
121
128
|
task_group_attrs["origin"] = "pypi"
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
task_collect.package_version = latest_version
|
128
|
-
else:
|
129
|
-
task_group_attrs["version"] = task_collect.package_version
|
130
|
-
|
131
|
-
# Validate user settings (backend-specific)
|
132
|
-
user_settings = await validate_user_settings(
|
133
|
-
user=user, backend=settings.FRACTAL_RUNNER_BACKEND, db=db
|
134
|
-
)
|
129
|
+
latest_version = await get_package_version_from_pypi(
|
130
|
+
task_collect.package,
|
131
|
+
task_collect.package_version,
|
132
|
+
)
|
133
|
+
task_group_attrs["version"] = latest_version
|
135
134
|
|
136
135
|
# Validate query parameters related to user-group ownership
|
137
136
|
user_group_id = await _get_valid_user_group_id(
|
@@ -140,9 +139,16 @@ async def collect_tasks_pip(
|
|
140
139
|
user_id=user.id,
|
141
140
|
db=db,
|
142
141
|
)
|
142
|
+
|
143
|
+
# Set user_group_id
|
143
144
|
task_group_attrs["user_group_id"] = user_group_id
|
144
145
|
|
145
|
-
#
|
146
|
+
# Validate user settings (backend-specific)
|
147
|
+
user_settings = await validate_user_settings(
|
148
|
+
user=user, backend=settings.FRACTAL_RUNNER_BACKEND, db=db
|
149
|
+
)
|
150
|
+
|
151
|
+
# Set path and venv_path
|
146
152
|
if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
|
147
153
|
base_tasks_path = user_settings.ssh_tasks_dir
|
148
154
|
else:
|
@@ -165,6 +171,8 @@ async def collect_tasks_pip(
|
|
165
171
|
detail=f"Invalid task-group object. Original error: {e}",
|
166
172
|
)
|
167
173
|
|
174
|
+
# Database checks
|
175
|
+
|
168
176
|
# Verify non-duplication constraints
|
169
177
|
await _verify_non_duplication_user_constraint(
|
170
178
|
user_id=user.id,
|
@@ -191,15 +199,18 @@ async def collect_tasks_pip(
|
|
191
199
|
),
|
192
200
|
)
|
193
201
|
|
194
|
-
#
|
202
|
+
# On-disk checks
|
203
|
+
|
195
204
|
if settings.FRACTAL_RUNNER_BACKEND != "slurm_ssh":
|
205
|
+
|
206
|
+
# Verify that folder does not exist (for local collection)
|
196
207
|
if Path(task_group_path).exists():
|
197
208
|
raise HTTPException(
|
198
209
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
199
210
|
detail=f"{task_group_path} already exists.",
|
200
211
|
)
|
201
212
|
|
202
|
-
|
213
|
+
# Verify that wheel file exists
|
203
214
|
wheel_path = task_group_attrs.get("wheel_path", None)
|
204
215
|
if wheel_path is not None:
|
205
216
|
if not Path(wheel_path).exists():
|
@@ -216,13 +227,15 @@ async def collect_tasks_pip(
|
|
216
227
|
db.expunge(task_group)
|
217
228
|
|
218
229
|
# All checks are OK, proceed with task collection
|
219
|
-
|
230
|
+
collection_state_data = dict(
|
220
231
|
status=CollectionStatusV2.PENDING,
|
221
|
-
|
222
|
-
|
232
|
+
package=task_group.pkg_name,
|
233
|
+
version=task_group.version,
|
234
|
+
path=task_group.path,
|
235
|
+
venv_path=task_group.venv_path,
|
223
236
|
)
|
224
237
|
state = CollectionStateV2(
|
225
|
-
data=
|
238
|
+
data=collection_state_data, taskgroupv2_id=task_group.id
|
226
239
|
)
|
227
240
|
db.add(state)
|
228
241
|
await db.commit()
|
@@ -270,7 +283,7 @@ async def collect_tasks_pip(
|
|
270
283
|
reset_logger_handlers(logger)
|
271
284
|
info = (
|
272
285
|
"Collecting tasks in the background. "
|
273
|
-
f"GET /task/collect/{state.id} to query collection status"
|
286
|
+
f"GET /task/collect/{state.id}/ to query collection status"
|
274
287
|
)
|
275
288
|
state.data["info"] = info
|
276
289
|
response.status_code = status.HTTP_201_CREATED
|
@@ -306,20 +319,17 @@ async def check_collection_status(
|
|
306
319
|
else:
|
307
320
|
# Non-SSH mode
|
308
321
|
# In some cases (i.e. a successful or ongoing task collection),
|
309
|
-
# state.data
|
322
|
+
# state.data["log"] is not set; if so, we collect the current logs.
|
310
323
|
if verbose and not state.data.get("log"):
|
311
|
-
if "
|
324
|
+
if "path" not in state.data.keys():
|
312
325
|
await db.close()
|
313
326
|
raise HTTPException(
|
314
327
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
315
328
|
detail=(
|
316
|
-
f"No '
|
329
|
+
f"No 'path' in CollectionStateV2[{state_id}].data"
|
317
330
|
),
|
318
331
|
)
|
319
|
-
state.data["log"] =
|
320
|
-
Path(state.data["venv_path"])
|
321
|
-
)
|
322
|
-
state.data["venv_path"] = str(state.data["venv_path"])
|
332
|
+
state.data["log"] = get_collection_log_v2(Path(state.data["path"]))
|
323
333
|
|
324
334
|
reset_logger_handlers(logger)
|
325
335
|
await db.close()
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/task_group.py
RENAMED
@@ -143,12 +143,16 @@ async def patch_task_group(
|
|
143
143
|
user_id=user.id,
|
144
144
|
db=db,
|
145
145
|
)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
146
|
+
if (
|
147
|
+
"user_group_id" in task_group_update.dict(exclude_unset=True)
|
148
|
+
and task_group_update.user_group_id != task_group.user_group_id
|
149
|
+
):
|
150
|
+
await _verify_non_duplication_group_constraint(
|
151
|
+
db=db,
|
152
|
+
pkg_name=task_group.pkg_name,
|
153
|
+
version=task_group.version,
|
154
|
+
user_group_id=task_group_update.user_group_id,
|
155
|
+
)
|
152
156
|
for key, value in task_group_update.dict(exclude_unset=True).items():
|
153
157
|
if (key == "user_group_id") and (value is not None):
|
154
158
|
await _verify_user_belongs_to_group(
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/routes/api/v2/workflowtask.py
RENAMED
@@ -77,7 +77,6 @@ async def create_workflowtask(
|
|
77
77
|
workflow_task = await _workflow_insert_task(
|
78
78
|
workflow_id=workflow.id,
|
79
79
|
task_id=task_id,
|
80
|
-
order=new_task.order,
|
81
80
|
meta_non_parallel=new_task.meta_non_parallel,
|
82
81
|
meta_parallel=new_task.meta_parallel,
|
83
82
|
args_non_parallel=new_task.args_non_parallel,
|
@@ -21,7 +21,6 @@ class TaskCreateV2(BaseModel, extra=Extra.forbid):
|
|
21
21
|
|
22
22
|
command_non_parallel: Optional[str] = None
|
23
23
|
command_parallel: Optional[str] = None
|
24
|
-
source: Optional[str] = None
|
25
24
|
|
26
25
|
meta_non_parallel: Optional[dict[str, Any]] = None
|
27
26
|
meta_parallel: Optional[dict[str, Any]] = None
|
@@ -64,7 +63,6 @@ class TaskCreateV2(BaseModel, extra=Extra.forbid):
|
|
64
63
|
_command_parallel = validator("command_parallel", allow_reuse=True)(
|
65
64
|
valstr("command_parallel")
|
66
65
|
)
|
67
|
-
_source = validator("source", allow_reuse=True)(valstr("source"))
|
68
66
|
_version = validator("version", allow_reuse=True)(valstr("version"))
|
69
67
|
|
70
68
|
_meta_non_parallel = validator("meta_non_parallel", allow_reuse=True)(
|
@@ -137,7 +135,6 @@ class TaskReadV2(BaseModel):
|
|
137
135
|
class TaskUpdateV2(BaseModel, extra=Extra.forbid):
|
138
136
|
|
139
137
|
name: Optional[str] = None
|
140
|
-
version: Optional[str] = None
|
141
138
|
command_parallel: Optional[str] = None
|
142
139
|
command_non_parallel: Optional[str] = None
|
143
140
|
input_types: Optional[dict[str, bool]] = None
|
@@ -156,9 +153,7 @@ class TaskUpdateV2(BaseModel, extra=Extra.forbid):
|
|
156
153
|
return v
|
157
154
|
|
158
155
|
_name = validator("name", allow_reuse=True)(valstr("name"))
|
159
|
-
|
160
|
-
valstr("version", accept_none=True)
|
161
|
-
)
|
156
|
+
|
162
157
|
_command_parallel = validator("command_parallel", allow_reuse=True)(
|
163
158
|
valstr("command_parallel")
|
164
159
|
)
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/app/schemas/v2/workflowtask.py
RENAMED
@@ -8,7 +8,6 @@ from pydantic import Field
|
|
8
8
|
from pydantic import validator
|
9
9
|
|
10
10
|
from .._validators import valdictkeys
|
11
|
-
from .._validators import valint
|
12
11
|
from .task import TaskExportV2
|
13
12
|
from .task import TaskImportV2
|
14
13
|
from .task import TaskReadV2
|
@@ -42,7 +41,6 @@ class WorkflowTaskCreateV2(BaseModel, extra=Extra.forbid):
|
|
42
41
|
meta_parallel: Optional[dict[str, Any]]
|
43
42
|
args_non_parallel: Optional[dict[str, Any]]
|
44
43
|
args_parallel: Optional[dict[str, Any]]
|
45
|
-
order: Optional[int]
|
46
44
|
input_filters: Filters = Field(default_factory=Filters)
|
47
45
|
|
48
46
|
# Validators
|
@@ -52,7 +50,6 @@ class WorkflowTaskCreateV2(BaseModel, extra=Extra.forbid):
|
|
52
50
|
_meta_parallel = validator("meta_parallel", allow_reuse=True)(
|
53
51
|
valdictkeys("meta_parallel")
|
54
52
|
)
|
55
|
-
_order = validator("order", allow_reuse=True)(valint("order", min_val=0))
|
56
53
|
|
57
54
|
@validator("args_non_parallel")
|
58
55
|
def validate_args_non_parallel(cls, value):
|
@@ -9,9 +9,11 @@ COLLECTION_LOG_FILENAME = "collection.log"
|
|
9
9
|
COLLECTION_FREEZE_FILENAME = "collection_freeze.txt"
|
10
10
|
|
11
11
|
|
12
|
-
def
|
12
|
+
def get_absolute_venv_path_v1(venv_path: Path) -> Path:
|
13
13
|
"""
|
14
14
|
If a path is not absolute, make it a relative path of FRACTAL_TASKS_DIR.
|
15
|
+
|
16
|
+
As of v2.7.0, we rename this to v1 since it is only to be used in v1.
|
15
17
|
"""
|
16
18
|
if venv_path.is_absolute():
|
17
19
|
package_path = venv_path
|
@@ -33,20 +35,32 @@ def get_freeze_path(base: Path) -> Path:
|
|
33
35
|
return base / COLLECTION_FREEZE_FILENAME
|
34
36
|
|
35
37
|
|
36
|
-
def
|
37
|
-
package_path =
|
38
|
+
def get_collection_log_v1(path: Path) -> str:
|
39
|
+
package_path = get_absolute_venv_path_v1(path)
|
38
40
|
log_path = get_log_path(package_path)
|
39
41
|
log = log_path.open().read()
|
40
42
|
return log
|
41
43
|
|
42
44
|
|
43
|
-
def
|
44
|
-
|
45
|
+
def get_collection_log_v2(path: Path) -> str:
|
46
|
+
log_path = get_log_path(path)
|
47
|
+
log = log_path.open().read()
|
48
|
+
return log
|
49
|
+
|
50
|
+
|
51
|
+
def get_collection_freeze_v1(venv_path: Path) -> str:
|
52
|
+
package_path = get_absolute_venv_path_v1(venv_path)
|
45
53
|
freeze_path = get_freeze_path(package_path)
|
46
54
|
freeze = freeze_path.open().read()
|
47
55
|
return freeze
|
48
56
|
|
49
57
|
|
58
|
+
def get_collection_freeze_v2(path: Path) -> str:
|
59
|
+
freeze_path = get_freeze_path(path)
|
60
|
+
freeze = freeze_path.open().read()
|
61
|
+
return freeze
|
62
|
+
|
63
|
+
|
50
64
|
def _normalize_package_name(name: str) -> str:
|
51
65
|
"""
|
52
66
|
Implement PyPa specifications for package-name normalization
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/background_operations.py
RENAMED
@@ -8,7 +8,7 @@ from shutil import rmtree as shell_rmtree
|
|
8
8
|
|
9
9
|
from ...string_tools import slugify_task_name_for_source_v1
|
10
10
|
from ..utils import _normalize_package_name
|
11
|
-
from ..utils import
|
11
|
+
from ..utils import get_collection_log_v1
|
12
12
|
from ..utils import get_collection_path
|
13
13
|
from ..utils import get_log_path
|
14
14
|
from ._TaskCollectPip import _TaskCollectPip
|
@@ -321,7 +321,7 @@ async def background_collect_pip(
|
|
321
321
|
|
322
322
|
# Update DB
|
323
323
|
data.status = "OK"
|
324
|
-
data.log =
|
324
|
+
data.log = get_collection_log_v1(venv_path)
|
325
325
|
state.data = data.sanitised_dict()
|
326
326
|
db.add(state)
|
327
327
|
db.merge(state)
|
@@ -342,7 +342,7 @@ async def background_collect_pip(
|
|
342
342
|
# Update db
|
343
343
|
data.status = "fail"
|
344
344
|
data.info = f"Original error: {e}"
|
345
|
-
data.log =
|
345
|
+
data.log = get_collection_log_v1(venv_path)
|
346
346
|
state.data = data.sanitised_dict()
|
347
347
|
db.merge(state)
|
348
348
|
db.commit()
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v1/get_collection_data.py
RENAMED
@@ -2,12 +2,12 @@ import json
|
|
2
2
|
from pathlib import Path
|
3
3
|
|
4
4
|
from fractal_server.app.schemas.v1 import TaskCollectStatusV1
|
5
|
-
from fractal_server.tasks.utils import
|
5
|
+
from fractal_server.tasks.utils import get_absolute_venv_path_v1
|
6
6
|
from fractal_server.tasks.utils import get_collection_path
|
7
7
|
|
8
8
|
|
9
9
|
def get_collection_data(venv_path: Path) -> TaskCollectStatusV1:
|
10
|
-
package_path =
|
10
|
+
package_path = get_absolute_venv_path_v1(venv_path)
|
11
11
|
collection_path = get_collection_path(package_path)
|
12
12
|
with collection_path.open() as f:
|
13
13
|
data = json.load(f)
|
{fractal_server-2.7.0a4 → fractal_server-2.7.0a5}/fractal_server/tasks/v2/background_operations.py
RENAMED
@@ -14,8 +14,8 @@ from sqlalchemy.orm import Session as DBSyncSession
|
|
14
14
|
from sqlalchemy.orm.attributes import flag_modified
|
15
15
|
from sqlmodel import select
|
16
16
|
|
17
|
-
from ..utils import
|
18
|
-
from ..utils import
|
17
|
+
from ..utils import get_collection_freeze_v2
|
18
|
+
from ..utils import get_collection_log_v2
|
19
19
|
from ..utils import get_collection_path
|
20
20
|
from ..utils import get_log_path
|
21
21
|
from .database_operations import create_db_tasks_and_update_task_group
|
@@ -419,10 +419,10 @@ async def background_collect_pip(
|
|
419
419
|
for task in task_group.task_list
|
420
420
|
]
|
421
421
|
collection_state.data["task_list"] = task_read_list
|
422
|
-
collection_state.data["log"] =
|
422
|
+
collection_state.data["log"] = get_collection_log_v2(
|
423
423
|
Path(task_group.path)
|
424
424
|
)
|
425
|
-
collection_state.data["freeze"] =
|
425
|
+
collection_state.data["freeze"] = get_collection_freeze_v2(
|
426
426
|
Path(task_group.path)
|
427
427
|
)
|
428
428
|
with collection_path.open("w") as f:
|
@@ -0,0 +1,124 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from fastapi import HTTPException
|
4
|
+
from fastapi import status
|
5
|
+
from httpx import AsyncClient
|
6
|
+
from httpx import TimeoutException
|
7
|
+
|
8
|
+
from fractal_server.logger import set_logger
|
9
|
+
|
10
|
+
|
11
|
+
logger = set_logger(__name__)
|
12
|
+
|
13
|
+
|
14
|
+
async def get_package_version_from_pypi(
|
15
|
+
name: str,
|
16
|
+
version: Optional[str] = None,
|
17
|
+
) -> str:
|
18
|
+
"""
|
19
|
+
Make a GET call to PyPI JSON API and get latest *compatible* version.
|
20
|
+
|
21
|
+
There are three cases:
|
22
|
+
|
23
|
+
1. `version` is set and it is found on PyPI as-is.
|
24
|
+
2. `version` is set but it is not found on PyPI as-is.
|
25
|
+
3. `version` is unset, and we query `PyPI` for latest.
|
26
|
+
|
27
|
+
Ref https://warehouse.pypa.io/api-reference/json.html.
|
28
|
+
|
29
|
+
Arguments:
|
30
|
+
name: Package name.
|
31
|
+
version:
|
32
|
+
Could be a correct version (`1.3.0`), an incomplete one
|
33
|
+
(`1.3`) or `None`.
|
34
|
+
"""
|
35
|
+
|
36
|
+
url = f"https://pypi.org/pypi/{name}/json"
|
37
|
+
hint = f"Hint: specify the required version for '{name}'."
|
38
|
+
|
39
|
+
# Make request to PyPI
|
40
|
+
try:
|
41
|
+
async with AsyncClient(timeout=5.0) as client:
|
42
|
+
res = await client.get(url)
|
43
|
+
except TimeoutException as e:
|
44
|
+
error_msg = (
|
45
|
+
f"A TimeoutException occurred while getting {url}.\n"
|
46
|
+
f"Original error: {str(e)}."
|
47
|
+
)
|
48
|
+
logger.error(error_msg)
|
49
|
+
raise HTTPException(
|
50
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
51
|
+
detail=error_msg,
|
52
|
+
)
|
53
|
+
except BaseException as e:
|
54
|
+
error_msg = (
|
55
|
+
f"An unknown error occurred while getting {url}. "
|
56
|
+
f"Original error: {str(e)}."
|
57
|
+
)
|
58
|
+
logger.error(error_msg)
|
59
|
+
raise HTTPException(
|
60
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
61
|
+
detail=error_msg,
|
62
|
+
)
|
63
|
+
|
64
|
+
# Parse response
|
65
|
+
if res.status_code != 200:
|
66
|
+
raise HTTPException(
|
67
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
68
|
+
detail=(
|
69
|
+
f"Could not get {url} (status_code {res.status_code})."
|
70
|
+
f"\n{hint}"
|
71
|
+
),
|
72
|
+
)
|
73
|
+
try:
|
74
|
+
response_data = res.json()
|
75
|
+
latest_version = response_data["info"]["version"]
|
76
|
+
available_releases = response_data["releases"].keys()
|
77
|
+
except KeyError as e:
|
78
|
+
logger.error(
|
79
|
+
f"A KeyError occurred while getting {url}. "
|
80
|
+
f"Original error: {str(e)}."
|
81
|
+
)
|
82
|
+
raise HTTPException(
|
83
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
84
|
+
detail=f"A KeyError error occurred while getting {url}.\n{hint}",
|
85
|
+
)
|
86
|
+
|
87
|
+
logger.info(
|
88
|
+
f"Obtained data from {url}: "
|
89
|
+
f"{len(available_releases)} releases, "
|
90
|
+
f"latest={latest_version}."
|
91
|
+
)
|
92
|
+
|
93
|
+
if version is not None:
|
94
|
+
if version in available_releases:
|
95
|
+
logger.info(f"Requested {version=} available on PyPI.")
|
96
|
+
# Case 1: `version` is set and it is found on PyPI as-is
|
97
|
+
return version
|
98
|
+
else:
|
99
|
+
# Case 2: `version` is set but it is not found on PyPI as-is
|
100
|
+
# Filter using `version` as prefix, and sort
|
101
|
+
matching_versions = [
|
102
|
+
v for v in available_releases if v.startswith(version)
|
103
|
+
]
|
104
|
+
logger.info(
|
105
|
+
f"Requested {version=} not available on PyPI, "
|
106
|
+
f"found {len(matching_versions)} versions matching "
|
107
|
+
f"`{version}*`."
|
108
|
+
)
|
109
|
+
if len(matching_versions) == 0:
|
110
|
+
logger.info(f"No version starting with {version} found.")
|
111
|
+
raise HTTPException(
|
112
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
113
|
+
detail=(
|
114
|
+
f"No version starting with {version} found.\n"
|
115
|
+
f"{hint}"
|
116
|
+
),
|
117
|
+
)
|
118
|
+
else:
|
119
|
+
latest_matching_version = sorted(matching_versions)[-1]
|
120
|
+
return latest_matching_version
|
121
|
+
else:
|
122
|
+
# Case 3: `version` is unset and we use latest
|
123
|
+
logger.info(f"No version requested, returning {latest_version=}.")
|
124
|
+
return latest_version
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "fractal-server"
|
3
|
-
version = "2.7.
|
3
|
+
version = "2.7.0a5"
|
4
4
|
description = "Server component of the Fractal analytics platform"
|
5
5
|
authors = [
|
6
6
|
"Tommaso Comparin <tommaso.comparin@exact-lab.it>",
|
@@ -92,7 +92,7 @@ filterwarnings = [
|
|
92
92
|
]
|
93
93
|
|
94
94
|
[tool.bumpver]
|
95
|
-
current_version = "2.7.
|
95
|
+
current_version = "2.7.0a5"
|
96
96
|
version_pattern = "MAJOR.MINOR.PATCH[PYTAGNUM]"
|
97
97
|
commit_message = "bump version {old_version} -> {new_version}"
|
98
98
|
commit = true
|
@@ -1 +0,0 @@
|
|
1
|
-
__VERSION__ = "2.7.0a4"
|