fractal-server 2.8.0__tar.gz → 2.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fractal_server-2.8.0 → fractal_server-2.9.0}/PKG-INFO +3 -5
- {fractal_server-2.8.0 → fractal_server-2.9.0}/README.md +1 -1
- fractal_server-2.9.0/fractal_server/__init__.py +1 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/db/__init__.py +2 -35
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v2/__init__.py +3 -3
- fractal_server-2.9.0/fractal_server/app/models/v2/task.py +48 -0
- fractal_server-2.8.0/fractal_server/app/models/v2/task.py → fractal_server-2.9.0/fractal_server/app/models/v2/task_group.py +36 -43
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/v1.py +13 -30
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/v2/__init__.py +4 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/v2/job.py +13 -24
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/v2/task.py +13 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/v2/task_group.py +75 -14
- fractal_server-2.9.0/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +267 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/project.py +7 -19
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/__init__.py +11 -2
- fractal_server-2.8.0/fractal_server/app/routes/api/v2/_aux_functions_task_collection.py → fractal_server-2.9.0/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +83 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +27 -17
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/submit.py +19 -24
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/task_collection.py +33 -65
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/task_collection_custom.py +3 -3
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/task_group.py +86 -14
- fractal_server-2.9.0/fractal_server/app/routes/api/v2/task_group_lifecycle.py +272 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/workflow.py +1 -1
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/workflow_import.py +2 -2
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/current_user.py +60 -17
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/group.py +67 -39
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/users.py +97 -99
- fractal_server-2.9.0/fractal_server/app/routes/aux/__init__.py +20 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/_slurm_config.py +0 -17
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/ssh/executor.py +49 -204
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/sudo/executor.py +26 -109
- fractal_server-2.9.0/fractal_server/app/runner/executors/slurm/utils_executors.py +58 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local_experimental/executor.py +2 -1
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/_validators.py +1 -16
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/user.py +16 -10
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/user_group.py +0 -11
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/applyworkflow.py +0 -8
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/dataset.py +0 -5
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/project.py +0 -5
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/state.py +0 -5
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/workflow.py +0 -5
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/__init__.py +4 -2
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/dataset.py +1 -7
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/job.py +0 -8
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/project.py +0 -5
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/task_collection.py +13 -31
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/task_group.py +59 -8
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/workflow.py +0 -5
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/security/__init__.py +17 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/config.py +61 -59
- fractal_server-2.9.0/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +117 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/ssh/_fabric.py +156 -83
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/string_tools.py +10 -3
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/utils.py +2 -12
- fractal_server-2.9.0/fractal_server/tasks/v2/local/__init__.py +3 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/local/_utils.py +70 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/local/collect.py +291 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/local/deactivate.py +218 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/local/reactivate.py +159 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/ssh/__init__.py +3 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/ssh/_utils.py +87 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/ssh/collect.py +311 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/ssh/deactivate.py +253 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/ssh/reactivate.py +202 -0
- fractal_server-2.8.0/fractal_server/tasks/v2/templates/_2_preliminary_pip_operations.sh → fractal_server-2.9.0/fractal_server/tasks/v2/templates/1_create_venv.sh +6 -7
- fractal_server-2.8.0/fractal_server/tasks/v2/templates/_3_pip_install.sh → fractal_server-2.9.0/fractal_server/tasks/v2/templates/2_pip_install.sh +8 -1
- fractal_server-2.8.0/fractal_server/tasks/v2/templates/_4_pip_freeze.sh → fractal_server-2.9.0/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -7
- fractal_server-2.8.0/fractal_server/tasks/v2/templates/_5_pip_show.sh → fractal_server-2.9.0/fractal_server/tasks/v2/templates/4_pip_show.sh +5 -6
- fractal_server-2.9.0/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +10 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +35 -0
- fractal_server-2.9.0/fractal_server/tasks/v2/utils_background.py +124 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v2/utils_templates.py +32 -2
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/utils.py +4 -2
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/zip_tools.py +21 -4
- {fractal_server-2.8.0 → fractal_server-2.9.0}/pyproject.toml +3 -5
- fractal_server-2.8.0/fractal_server/__init__.py +0 -1
- fractal_server-2.8.0/fractal_server/app/models/v2/collection_state.py +0 -22
- fractal_server-2.8.0/fractal_server/tasks/v2/__init__.py +0 -0
- fractal_server-2.8.0/fractal_server/tasks/v2/collection_local.py +0 -357
- fractal_server-2.8.0/fractal_server/tasks/v2/collection_ssh.py +0 -352
- fractal_server-2.8.0/fractal_server/tasks/v2/templates/_1_create_venv.sh +0 -42
- fractal_server-2.8.0/fractal_server/tasks/v2/utils_background.py +0 -209
- {fractal_server-2.8.0 → fractal_server-2.9.0}/LICENSE +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/__main__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v1/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v1/dataset.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v1/job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v1/project.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v1/state.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v1/task.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v1/workflow.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/_aux_functions.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/dataset.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/task.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/task_collection.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/workflow.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v1/workflowtask.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/status.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/.gitignore +0 -0
- {fractal_server-2.8.0/fractal_server/app/routes/aux → fractal_server-2.9.0/fractal_server/app/runner}/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/async_wrap.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/compress_folder.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.8.0/fractal_server/app/runner → fractal_server-2.9.0/fractal_server/app/runner/executors}/__init__.py +0 -0
- {fractal_server-2.8.0/fractal_server/app/runner/executors → fractal_server-2.9.0/fractal_server/app/runner/executors/slurm}/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/_batching.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/remote.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/ssh/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/ssh/_executor_wait_thread.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/ssh/_slurm_job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/sudo/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/sudo/_check_jobs_status.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/sudo/_executor_wait_thread.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/executors/slurm/sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/extract_archive.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/run_subprocess.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/task_files.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_common.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_local/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_local/_local_config.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_local/_submit_setup.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_local/executor.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_slurm/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_slurm/_submit_setup.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/_slurm/get_slurm_config.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/common.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v1/handle_failed_job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local/_local_config.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local/_submit_setup.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local/executor.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local_experimental/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local_experimental/_local_config.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_local_experimental/_submit_setup.py +0 -0
- {fractal_server-2.8.0/fractal_server/app/runner/executors/slurm → fractal_server-2.9.0/fractal_server/app/runner/v2/_slurm_common}/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_slurm_common/get_slurm_config.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_slurm_ssh/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_slurm_ssh/_submit_setup.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_slurm_sudo/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/_slurm_sudo/_submit_setup.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/handle_failed_job.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/runner.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/runner_functions.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/dumps.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/manifest.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/task.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v1/task_collection.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/status.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/images/models.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/logger.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/main.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/README +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/script.py.mako +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/py.typed +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/syringe.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v1/_TaskCollectPip.py +0 -0
- {fractal_server-2.8.0/fractal_server/app/runner/v2/_slurm_common → fractal_server-2.9.0/fractal_server/tasks/v1}/__init__.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v1/background_operations.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v1/endpoint_operations.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v1/get_collection_data.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v1/utils.py +0 -0
- {fractal_server-2.8.0/fractal_server/tasks/v1 → fractal_server-2.9.0/fractal_server/tasks/v2}/__init__.py +0 -0
- /fractal_server-2.8.0/fractal_server/tasks/v2/database_operations.py → /fractal_server-2.9.0/fractal_server/tasks/v2/utils_database.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v2/utils_package_names.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/urls.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fractal-server
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.9.0
|
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
|
@@ -12,14 +12,12 @@ Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
15
|
-
Requires-Dist: aiosqlite (>=0.19.0,<0.20.0)
|
16
15
|
Requires-Dist: alembic (>=1.13.1,<2.0.0)
|
17
|
-
Requires-Dist: bcrypt (==4.0.1)
|
18
16
|
Requires-Dist: cloudpickle (>=3.0.0,<3.1.0)
|
19
17
|
Requires-Dist: clusterfutures (>=0.5,<0.6)
|
20
18
|
Requires-Dist: fabric (>=3.2.2,<4.0.0)
|
21
19
|
Requires-Dist: fastapi (>=0.115.0,<0.116.0)
|
22
|
-
Requires-Dist: fastapi-users[oauth] (>=
|
20
|
+
Requires-Dist: fastapi-users[oauth] (>=14,<15)
|
23
21
|
Requires-Dist: gunicorn (>=21.2,<23.0)
|
24
22
|
Requires-Dist: packaging (>=23.2,<24.0)
|
25
23
|
Requires-Dist: psutil (>=5.9.8,<6.0.0)
|
@@ -38,7 +36,7 @@ Description-Content-Type: text/markdown
|
|
38
36
|
# Fractal Server
|
39
37
|
|
40
38
|
<p align="center">
|
41
|
-
<img src="https://
|
39
|
+
<img src="https://raw.githubusercontent.com/fractal-analytics-platform/fractal-logos/refs/heads/main/projects/fractal_server.png" alt="Fractal server" width="400">
|
42
40
|
</p>
|
43
41
|
|
44
42
|
[](https://pypi.org/project/fractal-server/)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Fractal Server
|
2
2
|
|
3
3
|
<p align="center">
|
4
|
-
<img src="https://
|
4
|
+
<img src="https://raw.githubusercontent.com/fractal-analytics-platform/fractal-logos/refs/heads/main/projects/fractal_server.png" alt="Fractal server" width="400">
|
5
5
|
</p>
|
6
6
|
|
7
7
|
[](https://pypi.org/project/fractal-server/)
|
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "2.9.0"
|
@@ -2,17 +2,14 @@
|
|
2
2
|
`db` module, loosely adapted from
|
3
3
|
https://testdriven.io/blog/fastapi-sqlmodel/#async-sqlmodel
|
4
4
|
"""
|
5
|
-
import sqlite3
|
6
5
|
from typing import AsyncGenerator
|
7
6
|
from typing import Generator
|
8
7
|
|
9
8
|
from sqlalchemy import create_engine
|
10
|
-
from sqlalchemy import event
|
11
9
|
from sqlalchemy.ext.asyncio import AsyncSession
|
12
10
|
from sqlalchemy.ext.asyncio import create_async_engine
|
13
11
|
from sqlalchemy.orm import Session as DBSyncSession
|
14
12
|
from sqlalchemy.orm import sessionmaker
|
15
|
-
from sqlalchemy.pool import StaticPool
|
16
13
|
|
17
14
|
from ...config import get_settings
|
18
15
|
from ...logger import set_logger
|
@@ -21,14 +18,6 @@ from ...syringe import Inject
|
|
21
18
|
|
22
19
|
logger = set_logger(__name__)
|
23
20
|
|
24
|
-
SQLITE_WARNING_MESSAGE = (
|
25
|
-
"SQLite is supported (supported version >=3.37, "
|
26
|
-
f"current {sqlite3.sqlite_version=}) "
|
27
|
-
"but discouraged in production. "
|
28
|
-
"Given its partial support for ForeignKey constraints, "
|
29
|
-
"database consistency cannot be guaranteed."
|
30
|
-
)
|
31
|
-
|
32
21
|
|
33
22
|
class DB:
|
34
23
|
"""
|
@@ -56,14 +45,7 @@ class DB:
|
|
56
45
|
settings = Inject(get_settings)
|
57
46
|
settings.check_db()
|
58
47
|
|
59
|
-
|
60
|
-
logger.warning(SQLITE_WARNING_MESSAGE)
|
61
|
-
# Set some sqlite-specific options
|
62
|
-
engine_kwargs_async = dict(poolclass=StaticPool)
|
63
|
-
else:
|
64
|
-
engine_kwargs_async = {
|
65
|
-
"pool_pre_ping": True,
|
66
|
-
}
|
48
|
+
engine_kwargs_async = {"pool_pre_ping": True}
|
67
49
|
|
68
50
|
cls._engine_async = create_async_engine(
|
69
51
|
settings.DATABASE_ASYNC_URL,
|
@@ -83,15 +65,7 @@ class DB:
|
|
83
65
|
settings = Inject(get_settings)
|
84
66
|
settings.check_db()
|
85
67
|
|
86
|
-
|
87
|
-
logger.warning(SQLITE_WARNING_MESSAGE)
|
88
|
-
# Set some sqlite-specific options
|
89
|
-
engine_kwargs_sync = dict(
|
90
|
-
poolclass=StaticPool,
|
91
|
-
connect_args={"check_same_thread": False},
|
92
|
-
)
|
93
|
-
else:
|
94
|
-
engine_kwargs_sync = {}
|
68
|
+
engine_kwargs_sync = {}
|
95
69
|
|
96
70
|
cls._engine_sync = create_engine(
|
97
71
|
settings.DATABASE_SYNC_URL,
|
@@ -107,13 +81,6 @@ class DB:
|
|
107
81
|
future=True,
|
108
82
|
)
|
109
83
|
|
110
|
-
@event.listens_for(cls._engine_sync, "connect")
|
111
|
-
def set_sqlite_pragma(dbapi_connection, connection_record):
|
112
|
-
if settings.DB_ENGINE == "sqlite":
|
113
|
-
cursor = dbapi_connection.cursor()
|
114
|
-
cursor.execute("PRAGMA journal_mode=WAL")
|
115
|
-
cursor.close()
|
116
|
-
|
117
84
|
@classmethod
|
118
85
|
async def get_async_db(cls) -> AsyncGenerator[AsyncSession, None]:
|
119
86
|
"""
|
@@ -2,12 +2,12 @@
|
|
2
2
|
v2 `models` module
|
3
3
|
"""
|
4
4
|
from ..linkuserproject import LinkUserProjectV2
|
5
|
-
from .collection_state import CollectionStateV2
|
6
5
|
from .dataset import DatasetV2
|
7
6
|
from .job import JobV2
|
8
7
|
from .project import ProjectV2
|
9
|
-
from .task import TaskGroupV2
|
10
8
|
from .task import TaskV2
|
9
|
+
from .task_group import TaskGroupActivityV2
|
10
|
+
from .task_group import TaskGroupV2
|
11
11
|
from .workflow import WorkflowV2
|
12
12
|
from .workflowtask import WorkflowTaskV2
|
13
13
|
|
@@ -16,8 +16,8 @@ __all__ = [
|
|
16
16
|
"DatasetV2",
|
17
17
|
"JobV2",
|
18
18
|
"ProjectV2",
|
19
|
-
"CollectionStateV2",
|
20
19
|
"TaskGroupV2",
|
20
|
+
"TaskGroupActivityV2",
|
21
21
|
"TaskV2",
|
22
22
|
"WorkflowTaskV2",
|
23
23
|
"WorkflowV2",
|
@@ -0,0 +1,48 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from pydantic import HttpUrl
|
5
|
+
from sqlalchemy import Column
|
6
|
+
from sqlalchemy.types import JSON
|
7
|
+
from sqlmodel import Field
|
8
|
+
from sqlmodel import SQLModel
|
9
|
+
|
10
|
+
|
11
|
+
class TaskV2(SQLModel, table=True):
|
12
|
+
id: Optional[int] = Field(default=None, primary_key=True)
|
13
|
+
name: str
|
14
|
+
|
15
|
+
type: str
|
16
|
+
command_non_parallel: Optional[str] = None
|
17
|
+
command_parallel: Optional[str] = None
|
18
|
+
source: Optional[str] = None
|
19
|
+
|
20
|
+
meta_non_parallel: dict[str, Any] = Field(
|
21
|
+
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
22
|
+
)
|
23
|
+
meta_parallel: dict[str, Any] = Field(
|
24
|
+
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
25
|
+
)
|
26
|
+
|
27
|
+
version: Optional[str] = None
|
28
|
+
args_schema_non_parallel: Optional[dict[str, Any]] = Field(
|
29
|
+
sa_column=Column(JSON), default=None
|
30
|
+
)
|
31
|
+
args_schema_parallel: Optional[dict[str, Any]] = Field(
|
32
|
+
sa_column=Column(JSON), default=None
|
33
|
+
)
|
34
|
+
args_schema_version: Optional[str]
|
35
|
+
docs_info: Optional[str] = None
|
36
|
+
docs_link: Optional[HttpUrl] = None
|
37
|
+
|
38
|
+
input_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
39
|
+
output_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
40
|
+
|
41
|
+
taskgroupv2_id: int = Field(foreign_key="taskgroupv2.id")
|
42
|
+
|
43
|
+
category: Optional[str] = None
|
44
|
+
modality: Optional[str] = None
|
45
|
+
authors: Optional[str] = None
|
46
|
+
tags: list[str] = Field(
|
47
|
+
sa_column=Column(JSON, server_default="[]", nullable=False)
|
48
|
+
)
|
@@ -1,8 +1,7 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from
|
2
|
+
from datetime import timezone
|
3
3
|
from typing import Optional
|
4
4
|
|
5
|
-
from pydantic import HttpUrl
|
6
5
|
from sqlalchemy import Column
|
7
6
|
from sqlalchemy.types import DateTime
|
8
7
|
from sqlalchemy.types import JSON
|
@@ -10,49 +9,10 @@ from sqlmodel import Field
|
|
10
9
|
from sqlmodel import Relationship
|
11
10
|
from sqlmodel import SQLModel
|
12
11
|
|
12
|
+
from .task import TaskV2
|
13
13
|
from fractal_server.utils import get_timestamp
|
14
14
|
|
15
15
|
|
16
|
-
class TaskV2(SQLModel, table=True):
|
17
|
-
id: Optional[int] = Field(default=None, primary_key=True)
|
18
|
-
name: str
|
19
|
-
|
20
|
-
type: str
|
21
|
-
command_non_parallel: Optional[str] = None
|
22
|
-
command_parallel: Optional[str] = None
|
23
|
-
source: Optional[str] = None
|
24
|
-
|
25
|
-
meta_non_parallel: dict[str, Any] = Field(
|
26
|
-
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
27
|
-
)
|
28
|
-
meta_parallel: dict[str, Any] = Field(
|
29
|
-
sa_column=Column(JSON, server_default="{}", default={}, nullable=False)
|
30
|
-
)
|
31
|
-
|
32
|
-
version: Optional[str] = None
|
33
|
-
args_schema_non_parallel: Optional[dict[str, Any]] = Field(
|
34
|
-
sa_column=Column(JSON), default=None
|
35
|
-
)
|
36
|
-
args_schema_parallel: Optional[dict[str, Any]] = Field(
|
37
|
-
sa_column=Column(JSON), default=None
|
38
|
-
)
|
39
|
-
args_schema_version: Optional[str]
|
40
|
-
docs_info: Optional[str] = None
|
41
|
-
docs_link: Optional[HttpUrl] = None
|
42
|
-
|
43
|
-
input_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
44
|
-
output_types: dict[str, bool] = Field(sa_column=Column(JSON), default={})
|
45
|
-
|
46
|
-
taskgroupv2_id: int = Field(foreign_key="taskgroupv2.id")
|
47
|
-
|
48
|
-
category: Optional[str] = None
|
49
|
-
modality: Optional[str] = None
|
50
|
-
authors: Optional[str] = None
|
51
|
-
tags: list[str] = Field(
|
52
|
-
sa_column=Column(JSON, server_default="[]", nullable=False)
|
53
|
-
)
|
54
|
-
|
55
|
-
|
56
16
|
class TaskGroupV2(SQLModel, table=True):
|
57
17
|
id: Optional[int] = Field(default=None, primary_key=True)
|
58
18
|
task_list: list[TaskV2] = Relationship(
|
@@ -69,7 +29,6 @@ class TaskGroupV2(SQLModel, table=True):
|
|
69
29
|
version: Optional[str] = None
|
70
30
|
python_version: Optional[str] = None
|
71
31
|
path: Optional[str] = None
|
72
|
-
venv_path: Optional[str] = None
|
73
32
|
wheel_path: Optional[str] = None
|
74
33
|
pip_extras: Optional[str] = None
|
75
34
|
pinned_package_versions: dict[str, str] = Field(
|
@@ -80,12 +39,26 @@ class TaskGroupV2(SQLModel, table=True):
|
|
80
39
|
nullable=True,
|
81
40
|
),
|
82
41
|
)
|
42
|
+
pip_freeze: Optional[str] = None
|
43
|
+
venv_path: Optional[str] = None
|
44
|
+
venv_size_in_kB: Optional[int] = None
|
45
|
+
venv_file_number: Optional[int] = None
|
83
46
|
|
84
47
|
active: bool = True
|
85
48
|
timestamp_created: datetime = Field(
|
86
49
|
default_factory=get_timestamp,
|
87
50
|
sa_column=Column(DateTime(timezone=True), nullable=False),
|
88
51
|
)
|
52
|
+
timestamp_last_used: datetime = Field(
|
53
|
+
default_factory=get_timestamp,
|
54
|
+
sa_column=Column(
|
55
|
+
DateTime(timezone=True),
|
56
|
+
nullable=False,
|
57
|
+
server_default=(
|
58
|
+
datetime(2024, 11, 20, tzinfo=timezone.utc).isoformat()
|
59
|
+
),
|
60
|
+
),
|
61
|
+
)
|
89
62
|
|
90
63
|
@property
|
91
64
|
def pip_install_string(self) -> str:
|
@@ -118,3 +91,23 @@ class TaskGroupV2(SQLModel, table=True):
|
|
118
91
|
]
|
119
92
|
)
|
120
93
|
return output
|
94
|
+
|
95
|
+
|
96
|
+
class TaskGroupActivityV2(SQLModel, table=True):
|
97
|
+
|
98
|
+
id: Optional[int] = Field(default=None, primary_key=True)
|
99
|
+
user_id: int = Field(foreign_key="user_oauth.id")
|
100
|
+
taskgroupv2_id: Optional[int] = Field(foreign_key="taskgroupv2.id")
|
101
|
+
timestamp_started: datetime = Field(
|
102
|
+
default_factory=get_timestamp,
|
103
|
+
sa_column=Column(DateTime(timezone=True), nullable=False),
|
104
|
+
)
|
105
|
+
pkg_name: str
|
106
|
+
version: str
|
107
|
+
status: str
|
108
|
+
action: str
|
109
|
+
log: Optional[str] = None
|
110
|
+
timestamp_ended: Optional[datetime] = Field(
|
111
|
+
default=None,
|
112
|
+
sa_column=Column(DateTime(timezone=True)),
|
113
|
+
)
|
@@ -2,7 +2,6 @@
|
|
2
2
|
Definition of `/admin` routes.
|
3
3
|
"""
|
4
4
|
from datetime import datetime
|
5
|
-
from datetime import timezone
|
6
5
|
from pathlib import Path
|
7
6
|
from typing import Optional
|
8
7
|
|
@@ -15,8 +14,6 @@ from fastapi.responses import StreamingResponse
|
|
15
14
|
from sqlalchemy import func
|
16
15
|
from sqlmodel import select
|
17
16
|
|
18
|
-
from ....config import get_settings
|
19
|
-
from ....syringe import Inject
|
20
17
|
from ....utils import get_timestamp
|
21
18
|
from ....zip_tools import _zip_folder_to_byte_stream_iterator
|
22
19
|
from ...db import AsyncSession
|
@@ -36,27 +33,11 @@ from ..aux._job import _write_shutdown_file
|
|
36
33
|
from ..aux._runner import _check_shutdown_is_supported
|
37
34
|
from fractal_server.app.models import UserOAuth
|
38
35
|
from fractal_server.app.routes.auth import current_active_superuser
|
36
|
+
from fractal_server.app.routes.aux import _raise_if_naive_datetime
|
39
37
|
|
40
38
|
router_admin_v1 = APIRouter()
|
41
39
|
|
42
40
|
|
43
|
-
def _convert_to_db_timestamp(dt: datetime) -> datetime:
|
44
|
-
"""
|
45
|
-
This function takes a timezone-aware datetime and converts it to UTC.
|
46
|
-
If using SQLite, it also removes the timezone information in order to make
|
47
|
-
the datetime comparable with datetimes in the database.
|
48
|
-
"""
|
49
|
-
if dt.tzinfo is None:
|
50
|
-
raise HTTPException(
|
51
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
52
|
-
detail=f"The timestamp provided has no timezone information: {dt}",
|
53
|
-
)
|
54
|
-
_dt = dt.astimezone(timezone.utc)
|
55
|
-
if Inject(get_settings).DB_ENGINE == "sqlite":
|
56
|
-
return _dt.replace(tzinfo=None)
|
57
|
-
return _dt
|
58
|
-
|
59
|
-
|
60
41
|
@router_admin_v1.get("/project/", response_model=list[ProjectReadV1])
|
61
42
|
async def view_project(
|
62
43
|
id: Optional[int] = None,
|
@@ -73,6 +54,7 @@ async def view_project(
|
|
73
54
|
id: If not `None`, select a given `project.id`.
|
74
55
|
user_id: If not `None`, select a given `project.user_id`.
|
75
56
|
"""
|
57
|
+
_raise_if_naive_datetime(timestamp_created_min, timestamp_created_max)
|
76
58
|
|
77
59
|
stm = select(Project)
|
78
60
|
|
@@ -82,10 +64,8 @@ async def view_project(
|
|
82
64
|
if user_id is not None:
|
83
65
|
stm = stm.where(Project.user_list.any(UserOAuth.id == user_id))
|
84
66
|
if timestamp_created_min is not None:
|
85
|
-
timestamp_created_min = _convert_to_db_timestamp(timestamp_created_min)
|
86
67
|
stm = stm.where(Project.timestamp_created >= timestamp_created_min)
|
87
68
|
if timestamp_created_max is not None:
|
88
|
-
timestamp_created_max = _convert_to_db_timestamp(timestamp_created_max)
|
89
69
|
stm = stm.where(Project.timestamp_created <= timestamp_created_max)
|
90
70
|
|
91
71
|
res = await db.execute(stm)
|
@@ -115,6 +95,8 @@ async def view_workflow(
|
|
115
95
|
name_contains: If not `None`, select workflows such that their
|
116
96
|
`name` attribute contains `name_contains` (case-insensitive).
|
117
97
|
"""
|
98
|
+
_raise_if_naive_datetime(timestamp_created_min, timestamp_created_max)
|
99
|
+
|
118
100
|
stm = select(Workflow)
|
119
101
|
|
120
102
|
if user_id is not None:
|
@@ -131,10 +113,8 @@ async def view_workflow(
|
|
131
113
|
func.lower(Workflow.name).contains(name_contains.lower())
|
132
114
|
)
|
133
115
|
if timestamp_created_min is not None:
|
134
|
-
timestamp_created_min = _convert_to_db_timestamp(timestamp_created_min)
|
135
116
|
stm = stm.where(Workflow.timestamp_created >= timestamp_created_min)
|
136
117
|
if timestamp_created_max is not None:
|
137
|
-
timestamp_created_max = _convert_to_db_timestamp(timestamp_created_max)
|
138
118
|
stm = stm.where(Workflow.timestamp_created <= timestamp_created_max)
|
139
119
|
|
140
120
|
res = await db.execute(stm)
|
@@ -166,6 +146,8 @@ async def view_dataset(
|
|
166
146
|
`name` attribute contains `name_contains` (case-insensitive).
|
167
147
|
type: If not `None`, select a given `dataset.type`.
|
168
148
|
"""
|
149
|
+
_raise_if_naive_datetime(timestamp_created_min, timestamp_created_max)
|
150
|
+
|
169
151
|
stm = select(Dataset)
|
170
152
|
|
171
153
|
if user_id is not None:
|
@@ -184,10 +166,8 @@ async def view_dataset(
|
|
184
166
|
if type is not None:
|
185
167
|
stm = stm.where(Dataset.type == type)
|
186
168
|
if timestamp_created_min is not None:
|
187
|
-
timestamp_created_min = _convert_to_db_timestamp(timestamp_created_min)
|
188
169
|
stm = stm.where(Dataset.timestamp_created >= timestamp_created_min)
|
189
170
|
if timestamp_created_max is not None:
|
190
|
-
timestamp_created_max = _convert_to_db_timestamp(timestamp_created_max)
|
191
171
|
stm = stm.where(Dataset.timestamp_created <= timestamp_created_max)
|
192
172
|
|
193
173
|
res = await db.execute(stm)
|
@@ -237,6 +217,13 @@ async def view_job(
|
|
237
217
|
log: If `True`, include `job.log`, if `False`
|
238
218
|
`job.log` is set to `None`.
|
239
219
|
"""
|
220
|
+
_raise_if_naive_datetime(
|
221
|
+
start_timestamp_min,
|
222
|
+
start_timestamp_max,
|
223
|
+
end_timestamp_min,
|
224
|
+
end_timestamp_max,
|
225
|
+
)
|
226
|
+
|
240
227
|
stm = select(ApplyWorkflow)
|
241
228
|
|
242
229
|
if id is not None:
|
@@ -256,16 +243,12 @@ async def view_job(
|
|
256
243
|
if status is not None:
|
257
244
|
stm = stm.where(ApplyWorkflow.status == status)
|
258
245
|
if start_timestamp_min is not None:
|
259
|
-
start_timestamp_min = _convert_to_db_timestamp(start_timestamp_min)
|
260
246
|
stm = stm.where(ApplyWorkflow.start_timestamp >= start_timestamp_min)
|
261
247
|
if start_timestamp_max is not None:
|
262
|
-
start_timestamp_max = _convert_to_db_timestamp(start_timestamp_max)
|
263
248
|
stm = stm.where(ApplyWorkflow.start_timestamp <= start_timestamp_max)
|
264
249
|
if end_timestamp_min is not None:
|
265
|
-
end_timestamp_min = _convert_to_db_timestamp(end_timestamp_min)
|
266
250
|
stm = stm.where(ApplyWorkflow.end_timestamp >= end_timestamp_min)
|
267
251
|
if end_timestamp_max is not None:
|
268
|
-
end_timestamp_max = _convert_to_db_timestamp(end_timestamp_max)
|
269
252
|
stm = stm.where(ApplyWorkflow.end_timestamp <= end_timestamp_max)
|
270
253
|
|
271
254
|
res = await db.execute(stm)
|
{fractal_server-2.8.0 → fractal_server-2.9.0}/fractal_server/app/routes/admin/v2/__init__.py
RENAMED
@@ -7,6 +7,7 @@ from .job import router as job_router
|
|
7
7
|
from .project import router as project_router
|
8
8
|
from .task import router as task_router
|
9
9
|
from .task_group import router as task_group_router
|
10
|
+
from .task_group_lifecycle import router as task_group_lifecycle_router
|
10
11
|
|
11
12
|
router_admin_v2 = APIRouter()
|
12
13
|
|
@@ -14,3 +15,6 @@ router_admin_v2.include_router(job_router, prefix="/job")
|
|
14
15
|
router_admin_v2.include_router(project_router, prefix="/project")
|
15
16
|
router_admin_v2.include_router(task_router, prefix="/task")
|
16
17
|
router_admin_v2.include_router(task_group_router, prefix="/task-group")
|
18
|
+
router_admin_v2.include_router(
|
19
|
+
task_group_lifecycle_router, prefix="/task-group"
|
20
|
+
)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from datetime import timezone
|
3
2
|
from pathlib import Path
|
4
3
|
from typing import Optional
|
5
4
|
|
@@ -17,37 +16,19 @@ from fractal_server.app.models import UserOAuth
|
|
17
16
|
from fractal_server.app.models.v2 import JobV2
|
18
17
|
from fractal_server.app.models.v2 import ProjectV2
|
19
18
|
from fractal_server.app.routes.auth import current_active_superuser
|
19
|
+
from fractal_server.app.routes.aux import _raise_if_naive_datetime
|
20
20
|
from fractal_server.app.routes.aux._job import _write_shutdown_file
|
21
21
|
from fractal_server.app.routes.aux._runner import _check_shutdown_is_supported
|
22
22
|
from fractal_server.app.runner.filenames import WORKFLOW_LOG_FILENAME
|
23
23
|
from fractal_server.app.schemas.v2 import JobReadV2
|
24
24
|
from fractal_server.app.schemas.v2 import JobStatusTypeV2
|
25
25
|
from fractal_server.app.schemas.v2 import JobUpdateV2
|
26
|
-
from fractal_server.config import get_settings
|
27
|
-
from fractal_server.syringe import Inject
|
28
26
|
from fractal_server.utils import get_timestamp
|
29
27
|
from fractal_server.zip_tools import _zip_folder_to_byte_stream_iterator
|
30
28
|
|
31
29
|
router = APIRouter()
|
32
30
|
|
33
31
|
|
34
|
-
def _convert_to_db_timestamp(dt: datetime) -> datetime:
|
35
|
-
"""
|
36
|
-
This function takes a timezone-aware datetime and converts it to UTC.
|
37
|
-
If using SQLite, it also removes the timezone information in order to make
|
38
|
-
the datetime comparable with datetimes in the database.
|
39
|
-
"""
|
40
|
-
if dt.tzinfo is None:
|
41
|
-
raise HTTPException(
|
42
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
43
|
-
detail=f"The timestamp provided has no timezone information: {dt}",
|
44
|
-
)
|
45
|
-
_dt = dt.astimezone(timezone.utc)
|
46
|
-
if Inject(get_settings).DB_ENGINE == "sqlite":
|
47
|
-
return _dt.replace(tzinfo=None)
|
48
|
-
return _dt
|
49
|
-
|
50
|
-
|
51
32
|
@router.get("/", response_model=list[JobReadV2])
|
52
33
|
async def view_job(
|
53
34
|
id: Optional[int] = None,
|
@@ -85,6 +66,14 @@ async def view_job(
|
|
85
66
|
log: If `True`, include `job.log`, if `False`
|
86
67
|
`job.log` is set to `None`.
|
87
68
|
"""
|
69
|
+
|
70
|
+
_raise_if_naive_datetime(
|
71
|
+
start_timestamp_min,
|
72
|
+
start_timestamp_max,
|
73
|
+
end_timestamp_min,
|
74
|
+
end_timestamp_max,
|
75
|
+
)
|
76
|
+
|
88
77
|
stm = select(JobV2)
|
89
78
|
|
90
79
|
if id is not None:
|
@@ -102,16 +91,16 @@ async def view_job(
|
|
102
91
|
if status is not None:
|
103
92
|
stm = stm.where(JobV2.status == status)
|
104
93
|
if start_timestamp_min is not None:
|
105
|
-
start_timestamp_min =
|
94
|
+
start_timestamp_min = start_timestamp_min
|
106
95
|
stm = stm.where(JobV2.start_timestamp >= start_timestamp_min)
|
107
96
|
if start_timestamp_max is not None:
|
108
|
-
start_timestamp_max =
|
97
|
+
start_timestamp_max = start_timestamp_max
|
109
98
|
stm = stm.where(JobV2.start_timestamp <= start_timestamp_max)
|
110
99
|
if end_timestamp_min is not None:
|
111
|
-
end_timestamp_min =
|
100
|
+
end_timestamp_min = end_timestamp_min
|
112
101
|
stm = stm.where(JobV2.end_timestamp >= end_timestamp_min)
|
113
102
|
if end_timestamp_max is not None:
|
114
|
-
end_timestamp_max =
|
103
|
+
end_timestamp_max = end_timestamp_max
|
115
104
|
stm = stm.where(JobV2.end_timestamp <= end_timestamp_max)
|
116
105
|
|
117
106
|
res = await db.execute(stm)
|
@@ -7,6 +7,7 @@ from fastapi import status
|
|
7
7
|
from pydantic import BaseModel
|
8
8
|
from pydantic import EmailStr
|
9
9
|
from pydantic import Field
|
10
|
+
from sqlmodel import func
|
10
11
|
from sqlmodel import select
|
11
12
|
|
12
13
|
from fractal_server.app.db import AsyncSession
|
@@ -60,6 +61,9 @@ async def query_tasks(
|
|
60
61
|
version: Optional[str] = None,
|
61
62
|
name: Optional[str] = None,
|
62
63
|
max_number_of_results: int = 25,
|
64
|
+
category: Optional[str] = None,
|
65
|
+
modality: Optional[str] = None,
|
66
|
+
author: Optional[str] = None,
|
63
67
|
user: UserOAuth = Depends(current_active_superuser),
|
64
68
|
db: AsyncSession = Depends(get_async_db),
|
65
69
|
) -> list[TaskV2Info]:
|
@@ -74,6 +78,9 @@ async def query_tasks(
|
|
74
78
|
version: If not `None`, query for matching `task.version`.
|
75
79
|
name: If not `None`, query for contained case insensitive `task.name`.
|
76
80
|
max_number_of_results: The maximum length of the response.
|
81
|
+
category:
|
82
|
+
modality:
|
83
|
+
author:
|
77
84
|
"""
|
78
85
|
|
79
86
|
stm = select(TaskV2)
|
@@ -86,6 +93,12 @@ async def query_tasks(
|
|
86
93
|
stm = stm.where(TaskV2.version == version)
|
87
94
|
if name is not None:
|
88
95
|
stm = stm.where(TaskV2.name.icontains(name))
|
96
|
+
if category is not None:
|
97
|
+
stm = stm.where(func.lower(TaskV2.category) == category.lower())
|
98
|
+
if modality is not None:
|
99
|
+
stm = stm.where(func.lower(TaskV2.modality) == modality.lower())
|
100
|
+
if author is not None:
|
101
|
+
stm = stm.where(TaskV2.authors.icontains(author))
|
89
102
|
|
90
103
|
res = await db.execute(stm)
|
91
104
|
task_list = res.scalars().all()
|