fractal-server 2.7.1__tar.gz → 2.8.1__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.1 → fractal_server-2.8.1}/PKG-INFO +11 -8
- {fractal_server-2.7.1 → fractal_server-2.8.1}/README.md +10 -7
- fractal_server-2.8.1/fractal_server/__init__.py +1 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/user_settings.py +1 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/task.py +15 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/dataset.py +39 -6
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/task.py +2 -5
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/task_collection.py +14 -42
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/task_collection_custom.py +3 -3
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/_validators.py +1 -1
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/user_settings.py +18 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/dataset.py +6 -4
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/task_collection.py +31 -12
- fractal_server-2.8.1/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +39 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/string_tools.py +10 -3
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/utils.py +0 -31
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v1/background_operations.py +11 -11
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v1/endpoint_operations.py +5 -5
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v1/utils.py +2 -2
- fractal_server-2.8.1/fractal_server/tasks/v2/collection_local.py +357 -0
- fractal_server-2.7.1/fractal_server/tasks/v2/background_operations_ssh.py → fractal_server-2.8.1/fractal_server/tasks/v2/collection_ssh.py +108 -102
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v2/templates/_1_create_venv.sh +0 -8
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v2/templates/_2_preliminary_pip_operations.sh +2 -2
- fractal_server-2.8.1/fractal_server/tasks/v2/templates/_3_pip_install.sh +49 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v2/templates/_5_pip_show.sh +5 -5
- fractal_server-2.8.1/fractal_server/tasks/v2/utils_background.py +209 -0
- fractal_server-2.8.1/fractal_server/tasks/v2/utils_package_names.py +77 -0
- fractal_server-2.7.1/fractal_server/tasks/v2/utils.py → fractal_server-2.8.1/fractal_server/tasks/v2/utils_python_interpreter.py +0 -26
- fractal_server-2.8.1/fractal_server/tasks/v2/utils_templates.py +59 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/utils.py +48 -3
- {fractal_server-2.7.1 → fractal_server-2.8.1}/pyproject.toml +2 -2
- fractal_server-2.7.1/fractal_server/__init__.py +0 -1
- fractal_server-2.7.1/fractal_server/tasks/v2/_venv_pip.py +0 -198
- fractal_server-2.7.1/fractal_server/tasks/v2/background_operations.py +0 -456
- fractal_server-2.7.1/fractal_server/tasks/v2/templates/_3_pip_install.sh +0 -28
- {fractal_server-2.7.1 → fractal_server-2.8.1}/LICENSE +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/__main__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v1/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v1/dataset.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v1/job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v1/project.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v1/state.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v1/task.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v1/workflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/collection_state.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/admin/v1.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/admin/v2/job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/admin/v2/task.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/_aux_functions.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/dataset.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/project.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/task.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/task_collection.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/workflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v1/workflowtask.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
- /fractal_server-2.7.1/fractal_server/tasks/v2/endpoint_operations.py → /fractal_server-2.8.1/fractal_server/app/routes/api/v2/_aux_functions_task_collection.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/status.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/task_group.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/workflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/.gitignore +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/async_wrap.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/compress_folder.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/_batching.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/_slurm_config.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/remote.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/ssh/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/ssh/executor.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/sudo/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/executors/slurm/sudo/executor.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/extract_archive.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/run_subprocess.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/task_files.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_common.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_local/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_local/_local_config.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_local/_submit_setup.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_local/executor.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_slurm/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_slurm/_submit_setup.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/_slurm/get_slurm_config.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/common.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v1/handle_failed_job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local/_local_config.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local/_submit_setup.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local/executor.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local_experimental/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local_experimental/_local_config.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_local_experimental/executor.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_slurm_common/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_slurm_common/get_slurm_config.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_slurm_ssh/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_slurm_sudo/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/handle_failed_job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/runner.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/runner_functions.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/applyworkflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/dataset.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/dumps.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/manifest.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/project.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/state.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/task.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/task_collection.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v1/workflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/status.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/task_group.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/security/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/config.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/images/models.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/logger.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/main.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/README +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/script.py.mako +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/py.typed +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/ssh/_fabric.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/syringe.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v1/_TaskCollectPip.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v1/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v1/get_collection_data.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v2/database_operations.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/tasks/v2/templates/_4_pip_freeze.sh +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/urls.py +0 -0
- {fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/zip_tools.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fractal-server
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.8.1
|
4
4
|
Summary: Server component of the Fractal analytics platform
|
5
5
|
Home-page: https://github.com/fractal-analytics-platform/fractal-server
|
6
6
|
License: BSD-3-Clause
|
@@ -37,15 +37,20 @@ Description-Content-Type: text/markdown
|
|
37
37
|
|
38
38
|
# Fractal Server
|
39
39
|
|
40
|
+
<p align="center">
|
41
|
+
<img src="https://github.com/user-attachments/assets/16e9cf11-d47d-4db8-a9b1-f5349e4175b7" alt="Fractal server" width="400">
|
42
|
+
</p>
|
43
|
+
|
40
44
|
[](https://pypi.org/project/fractal-server/)
|
45
|
+
[](https://opensource.org/licenses/BSD-3-Clause)
|
41
46
|
[](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/ci.yml?query=branch%3Amain)
|
42
47
|
[](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/python-coverage-comment-action-data/htmlcov/index.html)
|
43
|
-
[](https://fractal-analytics-platform.github.io/fractal-server)
|
44
49
|
[](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/benchmark-api/benchmarks/bench.html)
|
45
50
|
|
46
51
|
[Fractal](https://fractal-analytics-platform.github.io/) is a framework developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) to process bioimaging data at scale in the OME-Zarr format and prepare the images for interactive visualization.
|
47
52
|
|
48
|
-

|
49
54
|
|
50
55
|
This is the server component of the fractal analytics platform.
|
51
56
|
Find more information about Fractal in general and the other repositories at
|
@@ -58,14 +63,12 @@ See https://fractal-analytics-platform.github.io/fractal-server.
|
|
58
63
|
|
59
64
|
# Contributors and license
|
60
65
|
|
61
|
-
|
62
|
-
|
63
|
-
|
66
|
+
Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it).
|
67
|
+
|
68
|
+
Unless otherwise specified, Fractal components are released under the BSD 3-Clause License, and copyright is with the BioVisionCenter at the University of Zurich.
|
64
69
|
|
65
70
|
The SLURM compatibility layer is based on
|
66
71
|
[`clusterfutures`](https://github.com/sampsyo/clusterfutures), by
|
67
72
|
[@sampsyo](https://github.com/sampsyo) and collaborators, and it is released
|
68
73
|
under the terms of the MIT license.
|
69
74
|
|
70
|
-
Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it/).
|
71
|
-
|
@@ -1,14 +1,19 @@
|
|
1
1
|
# Fractal Server
|
2
2
|
|
3
|
+
<p align="center">
|
4
|
+
<img src="https://github.com/user-attachments/assets/16e9cf11-d47d-4db8-a9b1-f5349e4175b7" alt="Fractal server" width="400">
|
5
|
+
</p>
|
6
|
+
|
3
7
|
[](https://pypi.org/project/fractal-server/)
|
8
|
+
[](https://opensource.org/licenses/BSD-3-Clause)
|
4
9
|
[](https://github.com/fractal-analytics-platform/fractal-server/actions/workflows/ci.yml?query=branch%3Amain)
|
5
10
|
[](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/python-coverage-comment-action-data/htmlcov/index.html)
|
6
|
-
[](https://fractal-analytics-platform.github.io/fractal-server)
|
7
12
|
[](https://htmlpreview.github.io/?https://github.com/fractal-analytics-platform/fractal-server/blob/benchmark-api/benchmarks/bench.html)
|
8
13
|
|
9
14
|
[Fractal](https://fractal-analytics-platform.github.io/) is a framework developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) to process bioimaging data at scale in the OME-Zarr format and prepare the images for interactive visualization.
|
10
15
|
|
11
|
-

|
12
17
|
|
13
18
|
This is the server component of the fractal analytics platform.
|
14
19
|
Find more information about Fractal in general and the other repositories at
|
@@ -21,13 +26,11 @@ See https://fractal-analytics-platform.github.io/fractal-server.
|
|
21
26
|
|
22
27
|
# Contributors and license
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it).
|
30
|
+
|
31
|
+
Unless otherwise specified, Fractal components are released under the BSD 3-Clause License, and copyright is with the BioVisionCenter at the University of Zurich.
|
27
32
|
|
28
33
|
The SLURM compatibility layer is based on
|
29
34
|
[`clusterfutures`](https://github.com/sampsyo/clusterfutures), by
|
30
35
|
[@sampsyo](https://github.com/sampsyo) and collaborators, and it is released
|
31
36
|
under the terms of the MIT license.
|
32
|
-
|
33
|
-
Fractal was conceived in the Liberali Lab at the Friedrich Miescher Institute for Biomedical Research and in the Pelkmans Lab at the University of Zurich by [@jluethi](https://github.com/jluethi) and [@gusqgm](https://github.com/gusqgm). The Fractal project is now developed at the [BioVisionCenter](https://www.biovisioncenter.uzh.ch/en.html) at the University of Zurich and the project lead is with [@jluethi](https://github.com/jluethi). The core development is done under contract by [eXact lab S.r.l.](https://www.exact-lab.it/).
|
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "2.8.1"
|
@@ -103,3 +103,18 @@ class TaskGroupV2(SQLModel, table=True):
|
|
103
103
|
f"{self.pkg_name=}, {self.wheel_path=}, {self.version=}."
|
104
104
|
)
|
105
105
|
return f"{self.pkg_name}{extras}=={self.version}"
|
106
|
+
|
107
|
+
@property
|
108
|
+
def pinned_package_versions_string(self) -> str:
|
109
|
+
"""
|
110
|
+
Prepare string to be used in `python -m pip install`.
|
111
|
+
"""
|
112
|
+
if self.pinned_package_versions is None:
|
113
|
+
return ""
|
114
|
+
output = " ".join(
|
115
|
+
[
|
116
|
+
f"{key}=={value}"
|
117
|
+
for key, value in self.pinned_package_versions.items()
|
118
|
+
]
|
119
|
+
)
|
120
|
+
return output
|
@@ -22,6 +22,8 @@ from ._aux_functions import _get_project_check_owner
|
|
22
22
|
from ._aux_functions import _get_submitted_jobs_statement
|
23
23
|
from fractal_server.app.models import UserOAuth
|
24
24
|
from fractal_server.app.routes.auth import current_active_user
|
25
|
+
from fractal_server.string_tools import sanitize_string
|
26
|
+
from fractal_server.urls import normalize_url
|
25
27
|
|
26
28
|
router = APIRouter()
|
27
29
|
|
@@ -40,14 +42,45 @@ async def create_dataset(
|
|
40
42
|
"""
|
41
43
|
Add new dataset to current project
|
42
44
|
"""
|
43
|
-
await _get_project_check_owner(
|
45
|
+
project = await _get_project_check_owner(
|
44
46
|
project_id=project_id, user_id=user.id, db=db
|
45
47
|
)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
|
49
|
+
if dataset.zarr_dir is None:
|
50
|
+
|
51
|
+
if user.settings.project_dir is None:
|
52
|
+
raise HTTPException(
|
53
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
54
|
+
detail=(
|
55
|
+
"Both 'dataset.zarr_dir' and 'user.settings.project_dir' "
|
56
|
+
"are null"
|
57
|
+
),
|
58
|
+
)
|
59
|
+
|
60
|
+
db_dataset = DatasetV2(
|
61
|
+
project_id=project_id,
|
62
|
+
zarr_dir="__PLACEHOLDER__",
|
63
|
+
**dataset.dict(exclude={"zarr_dir"}),
|
64
|
+
)
|
65
|
+
db.add(db_dataset)
|
66
|
+
await db.commit()
|
67
|
+
await db.refresh(db_dataset)
|
68
|
+
path = (
|
69
|
+
f"{user.settings.project_dir}/fractal/"
|
70
|
+
f"{project_id}_{sanitize_string(project.name)}/"
|
71
|
+
f"{db_dataset.id}_{sanitize_string(db_dataset.name)}"
|
72
|
+
)
|
73
|
+
normalized_path = normalize_url(path)
|
74
|
+
db_dataset.zarr_dir = normalized_path
|
75
|
+
|
76
|
+
db.add(db_dataset)
|
77
|
+
await db.commit()
|
78
|
+
await db.refresh(db_dataset)
|
79
|
+
else:
|
80
|
+
db_dataset = DatasetV2(project_id=project_id, **dataset.dict())
|
81
|
+
db.add(db_dataset)
|
82
|
+
await db.commit()
|
83
|
+
await db.refresh(db_dataset)
|
51
84
|
|
52
85
|
return db_dataset
|
53
86
|
|
@@ -36,8 +36,7 @@ logger = set_logger(__name__)
|
|
36
36
|
|
37
37
|
@router.get("/", response_model=list[TaskReadV2])
|
38
38
|
async def get_list_task(
|
39
|
-
|
40
|
-
args_schema_non_parallel: bool = True,
|
39
|
+
args_schema: bool = True,
|
41
40
|
category: Optional[str] = None,
|
42
41
|
modality: Optional[str] = None,
|
43
42
|
author: Optional[str] = None,
|
@@ -72,11 +71,9 @@ async def get_list_task(
|
|
72
71
|
res = await db.execute(stm)
|
73
72
|
task_list = res.scalars().all()
|
74
73
|
await db.close()
|
75
|
-
if
|
74
|
+
if args_schema is False:
|
76
75
|
for task in task_list:
|
77
76
|
setattr(task, "args_schema_parallel", None)
|
78
|
-
if args_schema_non_parallel is False:
|
79
|
-
for task in task_list:
|
80
77
|
setattr(task, "args_schema_non_parallel", None)
|
81
78
|
|
82
79
|
return task_list
|
{fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/routes/api/v2/task_collection.py
RENAMED
@@ -24,6 +24,7 @@ from ....schemas.v2 import CollectionStatusV2
|
|
24
24
|
from ....schemas.v2 import TaskCollectPipV2
|
25
25
|
from ....schemas.v2 import TaskGroupCreateV2
|
26
26
|
from ...aux.validate_user_settings import validate_user_settings
|
27
|
+
from ._aux_functions_task_collection import get_package_version_from_pypi
|
27
28
|
from ._aux_functions_tasks import _get_valid_user_group_id
|
28
29
|
from ._aux_functions_tasks import _verify_non_duplication_group_constraint
|
29
30
|
from ._aux_functions_tasks import _verify_non_duplication_user_constraint
|
@@ -31,16 +32,14 @@ from fractal_server.app.models import UserOAuth
|
|
31
32
|
from fractal_server.app.routes.auth import current_active_user
|
32
33
|
from fractal_server.app.routes.auth import current_active_verified_user
|
33
34
|
from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
|
34
|
-
from fractal_server.tasks.
|
35
|
-
|
36
|
-
from fractal_server.tasks.v2.background_operations import (
|
37
|
-
background_collect_pip,
|
35
|
+
from fractal_server.tasks.v2.collection_local import (
|
36
|
+
collect_package_local,
|
38
37
|
)
|
39
|
-
from fractal_server.tasks.v2.
|
40
|
-
|
38
|
+
from fractal_server.tasks.v2.utils_package_names import _parse_wheel_filename
|
39
|
+
from fractal_server.tasks.v2.utils_package_names import normalize_package_name
|
40
|
+
from fractal_server.tasks.v2.utils_python_interpreter import (
|
41
|
+
get_python_interpreter_v2,
|
41
42
|
)
|
42
|
-
from fractal_server.tasks.v2.utils import _parse_wheel_filename
|
43
|
-
from fractal_server.tasks.v2.utils import get_python_interpreter_v2
|
44
43
|
|
45
44
|
router = APIRouter()
|
46
45
|
|
@@ -118,14 +117,14 @@ async def collect_tasks_pip(
|
|
118
117
|
f"Original error: {str(e)}",
|
119
118
|
),
|
120
119
|
)
|
121
|
-
task_group_attrs["pkg_name"] =
|
120
|
+
task_group_attrs["pkg_name"] = normalize_package_name(
|
122
121
|
wheel_info["distribution"]
|
123
122
|
)
|
124
123
|
task_group_attrs["version"] = wheel_info["version"]
|
125
124
|
task_group_attrs["origin"] = TaskGroupV2OriginEnum.WHEELFILE
|
126
125
|
else:
|
127
126
|
pkg_name = task_collect.package
|
128
|
-
task_group_attrs["pkg_name"] =
|
127
|
+
task_group_attrs["pkg_name"] = normalize_package_name(pkg_name)
|
129
128
|
task_group_attrs["origin"] = TaskGroupV2OriginEnum.PYPI
|
130
129
|
latest_version = await get_package_version_from_pypi(
|
131
130
|
task_collect.package,
|
@@ -249,8 +248,8 @@ async def collect_tasks_pip(
|
|
249
248
|
if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
|
250
249
|
# SSH task collection
|
251
250
|
|
252
|
-
from fractal_server.tasks.v2.
|
253
|
-
|
251
|
+
from fractal_server.tasks.v2.collection_ssh import (
|
252
|
+
collect_package_ssh,
|
254
253
|
)
|
255
254
|
|
256
255
|
# User appropriate FractalSSH object
|
@@ -263,7 +262,7 @@ async def collect_tasks_pip(
|
|
263
262
|
fractal_ssh = fractal_ssh_list.get(**ssh_credentials)
|
264
263
|
|
265
264
|
background_tasks.add_task(
|
266
|
-
|
265
|
+
collect_package_ssh,
|
267
266
|
state_id=state.id,
|
268
267
|
task_group=task_group,
|
269
268
|
fractal_ssh=fractal_ssh,
|
@@ -273,7 +272,7 @@ async def collect_tasks_pip(
|
|
273
272
|
else:
|
274
273
|
# Local task collection
|
275
274
|
background_tasks.add_task(
|
276
|
-
|
275
|
+
collect_package_local,
|
277
276
|
state_id=state.id,
|
278
277
|
task_group=task_group,
|
279
278
|
)
|
@@ -296,42 +295,15 @@ async def collect_tasks_pip(
|
|
296
295
|
async def check_collection_status(
|
297
296
|
state_id: int,
|
298
297
|
user: UserOAuth = Depends(current_active_user),
|
299
|
-
verbose: bool = False,
|
300
298
|
db: AsyncSession = Depends(get_async_db),
|
301
299
|
) -> CollectionStateReadV2: # State[TaskCollectStatus]
|
302
300
|
"""
|
303
301
|
Check status of background task collection
|
304
302
|
"""
|
305
|
-
|
306
|
-
logger = set_logger(logger_name="check_collection_status")
|
307
|
-
logger.debug(f"Querying state for state.id={state_id}")
|
308
303
|
state = await db.get(CollectionStateV2, state_id)
|
309
|
-
if
|
310
|
-
await db.close()
|
304
|
+
if state is None:
|
311
305
|
raise HTTPException(
|
312
306
|
status_code=status.HTTP_404_NOT_FOUND,
|
313
307
|
detail=f"No task collection info with id={state_id}",
|
314
308
|
)
|
315
|
-
|
316
|
-
settings = Inject(get_settings)
|
317
|
-
if settings.FRACTAL_RUNNER_BACKEND == "slurm_ssh":
|
318
|
-
# FIXME SSH: add logic for when data.state["log"] is empty
|
319
|
-
pass
|
320
|
-
else:
|
321
|
-
# Non-SSH mode
|
322
|
-
# In some cases (i.e. a successful or ongoing task collection),
|
323
|
-
# state.data["log"] is not set; if so, we collect the current logs.
|
324
|
-
if verbose and not state.data.get("log"):
|
325
|
-
if "path" not in state.data.keys():
|
326
|
-
await db.close()
|
327
|
-
raise HTTPException(
|
328
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
329
|
-
detail=(
|
330
|
-
f"No 'path' in CollectionStateV2[{state_id}].data"
|
331
|
-
),
|
332
|
-
)
|
333
|
-
state.data["log"] = get_collection_log_v2(Path(state.data["path"]))
|
334
|
-
|
335
|
-
reset_logger_handlers(logger)
|
336
|
-
await db.close()
|
337
309
|
return state
|
@@ -27,12 +27,12 @@ from fractal_server.config import get_settings
|
|
27
27
|
from fractal_server.logger import set_logger
|
28
28
|
from fractal_server.string_tools import validate_cmd
|
29
29
|
from fractal_server.syringe import Inject
|
30
|
-
from fractal_server.tasks.v2.background_operations import (
|
31
|
-
_prepare_tasks_metadata,
|
32
|
-
)
|
33
30
|
from fractal_server.tasks.v2.database_operations import (
|
34
31
|
create_db_tasks_and_update_task_group,
|
35
32
|
)
|
33
|
+
from fractal_server.tasks.v2.utils_background import (
|
34
|
+
_prepare_tasks_metadata,
|
35
|
+
)
|
36
36
|
|
37
37
|
router = APIRouter()
|
38
38
|
|
@@ -74,7 +74,7 @@ def val_absolute_path(attribute: str, accept_none: bool = False):
|
|
74
74
|
Check that a string attribute is an absolute path
|
75
75
|
"""
|
76
76
|
|
77
|
-
def val(string: Optional[str]) -> str:
|
77
|
+
def val(string: Optional[str]) -> Optional[str]:
|
78
78
|
if string is None:
|
79
79
|
if accept_none:
|
80
80
|
return string
|
@@ -19,6 +19,10 @@ __all__ = (
|
|
19
19
|
|
20
20
|
|
21
21
|
class UserSettingsRead(BaseModel):
|
22
|
+
"""
|
23
|
+
Schema reserved for superusers
|
24
|
+
"""
|
25
|
+
|
22
26
|
id: int
|
23
27
|
ssh_host: Optional[str] = None
|
24
28
|
ssh_username: Optional[str] = None
|
@@ -28,6 +32,7 @@ class UserSettingsRead(BaseModel):
|
|
28
32
|
slurm_user: Optional[str] = None
|
29
33
|
slurm_accounts: list[str]
|
30
34
|
cache_dir: Optional[str] = None
|
35
|
+
project_dir: Optional[str] = None
|
31
36
|
|
32
37
|
|
33
38
|
class UserSettingsReadStrict(BaseModel):
|
@@ -35,9 +40,14 @@ class UserSettingsReadStrict(BaseModel):
|
|
35
40
|
slurm_accounts: list[str]
|
36
41
|
cache_dir: Optional[str] = None
|
37
42
|
ssh_username: Optional[str] = None
|
43
|
+
project_dir: Optional[str] = None
|
38
44
|
|
39
45
|
|
40
46
|
class UserSettingsUpdate(BaseModel, extra=Extra.forbid):
|
47
|
+
"""
|
48
|
+
Schema reserved for superusers
|
49
|
+
"""
|
50
|
+
|
41
51
|
ssh_host: Optional[str] = None
|
42
52
|
ssh_username: Optional[str] = None
|
43
53
|
ssh_private_key_path: Optional[str] = None
|
@@ -46,6 +56,7 @@ class UserSettingsUpdate(BaseModel, extra=Extra.forbid):
|
|
46
56
|
slurm_user: Optional[str] = None
|
47
57
|
slurm_accounts: Optional[list[StrictStr]] = None
|
48
58
|
cache_dir: Optional[str] = None
|
59
|
+
project_dir: Optional[str] = None
|
49
60
|
|
50
61
|
_ssh_host = validator("ssh_host", allow_reuse=True)(
|
51
62
|
valstr("ssh_host", accept_none=True)
|
@@ -83,6 +94,13 @@ class UserSettingsUpdate(BaseModel, extra=Extra.forbid):
|
|
83
94
|
validate_cmd(value)
|
84
95
|
return val_absolute_path("cache_dir")(value)
|
85
96
|
|
97
|
+
@validator("project_dir")
|
98
|
+
def project_dir_validator(cls, value):
|
99
|
+
if value is None:
|
100
|
+
return None
|
101
|
+
validate_cmd(value)
|
102
|
+
return val_absolute_path("project_dir")(value)
|
103
|
+
|
86
104
|
|
87
105
|
class UserSettingsUpdateStrict(BaseModel, extra=Extra.forbid):
|
88
106
|
slurm_accounts: Optional[list[StrictStr]] = None
|
@@ -33,14 +33,16 @@ class DatasetCreateV2(BaseModel, extra=Extra.forbid):
|
|
33
33
|
|
34
34
|
name: str
|
35
35
|
|
36
|
-
zarr_dir: str
|
36
|
+
zarr_dir: Optional[str] = None
|
37
37
|
|
38
38
|
filters: Filters = Field(default_factory=Filters)
|
39
39
|
|
40
40
|
# Validators
|
41
41
|
@validator("zarr_dir")
|
42
|
-
def normalize_zarr_dir(cls, v: str) -> str:
|
43
|
-
|
42
|
+
def normalize_zarr_dir(cls, v: Optional[str]) -> Optional[str]:
|
43
|
+
if v is not None:
|
44
|
+
return normalize_url(v)
|
45
|
+
return v
|
44
46
|
|
45
47
|
_name = validator("name", allow_reuse=True)(valstr("name"))
|
46
48
|
|
@@ -95,7 +97,7 @@ class DatasetImportV2(BaseModel, extra=Extra.forbid):
|
|
95
97
|
|
96
98
|
name: str
|
97
99
|
zarr_dir: str
|
98
|
-
images: list[SingleImage] = Field(default_factory=
|
100
|
+
images: list[SingleImage] = Field(default_factory=list)
|
99
101
|
filters: Filters = Field(default_factory=Filters)
|
100
102
|
|
101
103
|
# Validators
|
{fractal_server-2.7.1 → fractal_server-2.8.1}/fractal_server/app/schemas/v2/task_collection.py
RENAMED
@@ -10,7 +10,6 @@ from pydantic import Extra
|
|
10
10
|
from pydantic import root_validator
|
11
11
|
from pydantic import validator
|
12
12
|
|
13
|
-
from .._validators import valdictkeys
|
14
13
|
from .._validators import valstr
|
15
14
|
from fractal_server.app.schemas._validators import valutc
|
16
15
|
from fractal_server.app.schemas.v2 import ManifestV2
|
@@ -58,19 +57,29 @@ class TaskCollectPipV2(BaseModel, extra=Extra.forbid):
|
|
58
57
|
python_version: Optional[Literal["3.9", "3.10", "3.11", "3.12"]] = None
|
59
58
|
pinned_package_versions: Optional[dict[str, str]] = None
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
60
|
+
@validator("pinned_package_versions")
|
61
|
+
def pinned_package_versions_validator(cls, value):
|
62
|
+
if value is None:
|
63
|
+
return value
|
64
|
+
old_keys = list(value.keys())
|
65
|
+
new_keys = [
|
66
|
+
valstr(f"pinned_package_versions[{key}]")(key) for key in old_keys
|
67
|
+
]
|
68
|
+
if len(new_keys) != len(set(new_keys)):
|
69
|
+
raise ValueError(
|
70
|
+
f"Dictionary contains multiple identical keys: {value}."
|
71
|
+
)
|
72
|
+
for old_key, new_key in zip(old_keys, new_keys):
|
73
|
+
if new_key != old_key:
|
74
|
+
value[new_key] = value.pop(old_key)
|
75
|
+
for pkg, version in value.items():
|
76
|
+
validate_cmd(pkg)
|
77
|
+
validate_cmd(version)
|
78
|
+
return value
|
71
79
|
|
72
80
|
@validator("package")
|
73
81
|
def package_validator(cls, value):
|
82
|
+
value = valstr("package")(value)
|
74
83
|
if "/" in value or value.endswith(".whl"):
|
75
84
|
if not value.endswith(".whl"):
|
76
85
|
raise ValueError(
|
@@ -81,17 +90,27 @@ class TaskCollectPipV2(BaseModel, extra=Extra.forbid):
|
|
81
90
|
raise ValueError(
|
82
91
|
f"Local-package path must be absolute: (given {value})."
|
83
92
|
)
|
93
|
+
validate_cmd(value, attribute_name="package")
|
84
94
|
return value
|
85
95
|
|
86
96
|
@validator("package_version")
|
87
|
-
def package_version_validator(
|
97
|
+
def package_version_validator(
|
98
|
+
cls, v: Optional[str], values
|
99
|
+
) -> Optional[str]:
|
88
100
|
v = valstr("package_version")(v)
|
89
101
|
if values["package"].endswith(".whl"):
|
90
102
|
raise ValueError(
|
91
103
|
"Cannot provide package version when package is a wheel file."
|
92
104
|
)
|
105
|
+
validate_cmd(v, attribute_name="package_version")
|
93
106
|
return v
|
94
107
|
|
108
|
+
@validator("package_extras")
|
109
|
+
def package_extras_validator(cls, value: Optional[str]) -> Optional[str]:
|
110
|
+
value = valstr("package_extras")(value)
|
111
|
+
validate_cmd(value, attribute_name="package_extras")
|
112
|
+
return value
|
113
|
+
|
95
114
|
|
96
115
|
class TaskCollectCustomV2(BaseModel, extra=Extra.forbid):
|
97
116
|
"""
|
fractal_server-2.8.1/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
"""user settings project dir
|
2
|
+
|
3
|
+
Revision ID: 19eca0dd47a9
|
4
|
+
Revises: 8e8f227a3e36
|
5
|
+
Create Date: 2024-10-30 14:34:28.219355
|
6
|
+
|
7
|
+
"""
|
8
|
+
import sqlalchemy as sa
|
9
|
+
import sqlmodel
|
10
|
+
from alembic import op
|
11
|
+
|
12
|
+
|
13
|
+
# revision identifiers, used by Alembic.
|
14
|
+
revision = "19eca0dd47a9"
|
15
|
+
down_revision = "8e8f227a3e36"
|
16
|
+
branch_labels = None
|
17
|
+
depends_on = None
|
18
|
+
|
19
|
+
|
20
|
+
def upgrade() -> None:
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
22
|
+
with op.batch_alter_table("user_settings", schema=None) as batch_op:
|
23
|
+
batch_op.add_column(
|
24
|
+
sa.Column(
|
25
|
+
"project_dir",
|
26
|
+
sqlmodel.sql.sqltypes.AutoString(),
|
27
|
+
nullable=True,
|
28
|
+
)
|
29
|
+
)
|
30
|
+
|
31
|
+
# ### end Alembic commands ###
|
32
|
+
|
33
|
+
|
34
|
+
def downgrade() -> None:
|
35
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
36
|
+
with op.batch_alter_table("user_settings", schema=None) as batch_op:
|
37
|
+
batch_op.drop_column("project_dir")
|
38
|
+
|
39
|
+
# ### end Alembic commands ###
|
@@ -54,7 +54,12 @@ def slugify_task_name_for_source_v1(task_name: str) -> str:
|
|
54
54
|
return task_name.replace(" ", "_").lower()
|
55
55
|
|
56
56
|
|
57
|
-
def validate_cmd(
|
57
|
+
def validate_cmd(
|
58
|
+
command: str,
|
59
|
+
*,
|
60
|
+
allow_char: Optional[str] = None,
|
61
|
+
attribute_name: str = "Command",
|
62
|
+
):
|
58
63
|
"""
|
59
64
|
Assert that the provided `command` does not contain any of the forbidden
|
60
65
|
characters for commands
|
@@ -63,6 +68,7 @@ def validate_cmd(command: str, allow_char: Optional[str] = None):
|
|
63
68
|
Args:
|
64
69
|
command: command to validate.
|
65
70
|
allow_char: chars to accept among the forbidden ones
|
71
|
+
attribute_name: Name of the attribute, to be used in error message.
|
66
72
|
"""
|
67
73
|
if not isinstance(command, str):
|
68
74
|
raise ValueError(f"{command=} is not a string.")
|
@@ -71,6 +77,7 @@ def validate_cmd(command: str, allow_char: Optional[str] = None):
|
|
71
77
|
forbidden = forbidden - set(allow_char)
|
72
78
|
if not forbidden.isdisjoint(set(command)):
|
73
79
|
raise ValueError(
|
74
|
-
f"
|
75
|
-
f"
|
80
|
+
f"{attribute_name} must not contain any of this characters: "
|
81
|
+
f"'{forbidden}'\n"
|
82
|
+
f"Provided {attribute_name.lower()}: '{command}'."
|
76
83
|
)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import re
|
2
1
|
from pathlib import Path
|
3
2
|
|
4
3
|
from fractal_server.config import get_settings
|
@@ -42,38 +41,8 @@ def get_collection_log_v1(path: Path) -> str:
|
|
42
41
|
return log
|
43
42
|
|
44
43
|
|
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
44
|
def get_collection_freeze_v1(venv_path: Path) -> str:
|
52
45
|
package_path = get_absolute_venv_path_v1(venv_path)
|
53
46
|
freeze_path = get_freeze_path(package_path)
|
54
47
|
freeze = freeze_path.open().read()
|
55
48
|
return freeze
|
56
|
-
|
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
|
-
|
64
|
-
def _normalize_package_name(name: str) -> str:
|
65
|
-
"""
|
66
|
-
Implement PyPa specifications for package-name normalization
|
67
|
-
|
68
|
-
The name should be lowercased with all runs of the characters `.`, `-`,
|
69
|
-
or `_` replaced with a single `-` character. This can be implemented in
|
70
|
-
Python with the re module.
|
71
|
-
(https://packaging.python.org/en/latest/specifications/name-normalization)
|
72
|
-
|
73
|
-
Args:
|
74
|
-
name: The non-normalized package name.
|
75
|
-
|
76
|
-
Returns:
|
77
|
-
The normalized package name.
|
78
|
-
"""
|
79
|
-
return re.sub(r"[-_.]+", "-", name).lower()
|