fractal-server 2.14.0a1__tar.gz → 2.14.0a3__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.14.0a1 → fractal_server-2.14.0a3}/PKG-INFO +1 -1
- fractal_server-2.14.0a3/fractal_server/__init__.py +1 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/history/image_updates.py +2 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/history.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/accounting.py +18 -28
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/task.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/_aux_functions.py +2 -4
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/history.py +109 -51
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/images.py +11 -28
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/project.py +1 -1
- fractal_server-2.14.0a3/fractal_server/app/routes/pagination.py +47 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/base_runner.py +2 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/local/_submit_setup.py +5 -13
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/_slurm_config.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/remote.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/__init__.py +2 -2
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/_slurm_ssh.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/_slurm_sudo.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/runner.py +3 -2
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/runner_functions.py +21 -47
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/manifest.py +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/security/__init__.py +3 -3
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/config.py +2 -10
- fractal_server-2.14.0a1/fractal_server/migrations/versions/8223fcef886c_image_status.py → fractal_server-2.14.0a3/fractal_server/migrations/versions/954ddc64425a_image_status.py +4 -4
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/templates/4_pip_show.sh +1 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/pyproject.toml +2 -2
- fractal_server-2.14.0a1/fractal_server/__init__.py +0 -1
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/LICENSE +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/README.md +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/__main__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/history/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/history/status_enum.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/accounting.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/task.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/task_group.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/job.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/task_group.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/workflow.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/compress_folder.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/local/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/local/_local_config.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/local/runner.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/_batching.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/_job_states.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/_submit_setup.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_common/utils_executors.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_ssh/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_ssh/_executor_wait_thread.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_ssh/_slurm_job.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_ssh/executor.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_sudo/_check_jobs_status.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_sudo/_executor_wait_thread.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/executors/slurm_sudo/runner.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/extract_archive.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/run_subprocess.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/task_files.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/_local.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/_filter_validators.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/_validators.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/accounting.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/dataset.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/history.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/status.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/task_collection.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/task_group.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/security/signup_email.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/images/models.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/logger.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/main.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/87cd72a537a2_add_historyitem_table.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/py.typed +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/ssh/_fabric.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/string_tools.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/syringe.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/utils.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/local/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/local/_utils.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/local/collect.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/local/deactivate.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/local/reactivate.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/ssh/collect.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/utils_background.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/utils_database.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/utils_package_names.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/tasks/v2/utils_templates.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/urls.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/utils.py +0 -0
- {fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/zip_tools.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "2.14.0a3"
|
{fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/history/image_updates.py
RENAMED
@@ -83,7 +83,8 @@ def update_single_image_logfile(
|
|
83
83
|
) -> None:
|
84
84
|
|
85
85
|
logger.debug(
|
86
|
-
|
86
|
+
"[update_single_image_logfile] "
|
87
|
+
f"{history_item_id=}, {logfile=}, {zarr_url=}"
|
87
88
|
)
|
88
89
|
|
89
90
|
with next(get_sync_db()) as db:
|
{fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/accounting.py
RENAMED
@@ -3,9 +3,6 @@ from typing import Optional
|
|
3
3
|
|
4
4
|
from fastapi import APIRouter
|
5
5
|
from fastapi import Depends
|
6
|
-
from fastapi import HTTPException
|
7
|
-
from fastapi import Query
|
8
|
-
from fastapi import status
|
9
6
|
from fastapi.responses import JSONResponse
|
10
7
|
from pydantic import BaseModel
|
11
8
|
from pydantic.types import AwareDatetime
|
@@ -18,6 +15,9 @@ from fractal_server.app.models import UserOAuth
|
|
18
15
|
from fractal_server.app.models.v2 import AccountingRecord
|
19
16
|
from fractal_server.app.models.v2 import AccountingRecordSlurm
|
20
17
|
from fractal_server.app.routes.auth import current_active_superuser
|
18
|
+
from fractal_server.app.routes.pagination import get_pagination_params
|
19
|
+
from fractal_server.app.routes.pagination import PaginationRequest
|
20
|
+
from fractal_server.app.routes.pagination import PaginationResponse
|
21
21
|
from fractal_server.app.schemas.v2 import AccountingRecordRead
|
22
22
|
|
23
23
|
|
@@ -27,32 +27,19 @@ class AccountingQuery(BaseModel):
|
|
27
27
|
timestamp_max: Optional[AwareDatetime] = None
|
28
28
|
|
29
29
|
|
30
|
-
class AccountingPage(BaseModel):
|
31
|
-
total_count: int
|
32
|
-
page_size: int
|
33
|
-
current_page: int
|
34
|
-
records: list[AccountingRecordRead]
|
35
|
-
|
36
|
-
|
37
30
|
router = APIRouter()
|
38
31
|
|
39
32
|
|
40
|
-
@router.post("/", response_model=
|
33
|
+
@router.post("/", response_model=PaginationResponse[AccountingRecordRead])
|
41
34
|
async def query_accounting(
|
42
35
|
query: AccountingQuery,
|
43
|
-
#
|
44
|
-
|
45
|
-
page_size: Optional[int] = Query(default=None, ge=1),
|
46
|
-
# dependencies
|
36
|
+
# Dependencies
|
37
|
+
pagination: PaginationRequest = Depends(get_pagination_params),
|
47
38
|
superuser: UserOAuth = Depends(current_active_superuser),
|
48
39
|
db: AsyncSession = Depends(get_async_db),
|
49
|
-
) ->
|
50
|
-
|
51
|
-
|
52
|
-
raise HTTPException(
|
53
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
54
|
-
detail=(f"Invalid pagination parameters: {page=}, {page_size=}."),
|
55
|
-
)
|
40
|
+
) -> PaginationResponse[AccountingRecordRead]:
|
41
|
+
page = pagination.page
|
42
|
+
page_size = pagination.page_size
|
56
43
|
|
57
44
|
stm = select(AccountingRecord).order_by(AccountingRecord.id)
|
58
45
|
stm_count = select(func.count(AccountingRecord.id))
|
@@ -69,20 +56,23 @@ async def query_accounting(
|
|
69
56
|
stm_count = stm_count.where(
|
70
57
|
AccountingRecord.timestamp <= query.timestamp_max
|
71
58
|
)
|
59
|
+
|
60
|
+
res_total_count = await db.execute(stm_count)
|
61
|
+
total_count = res_total_count.scalar()
|
62
|
+
|
72
63
|
if page_size is not None:
|
73
64
|
stm = stm.offset((page - 1) * page_size).limit(page_size)
|
65
|
+
else:
|
66
|
+
page_size = total_count
|
74
67
|
|
75
68
|
res = await db.execute(stm)
|
76
69
|
records = res.scalars().all()
|
77
|
-
res_total_count = await db.execute(stm_count)
|
78
|
-
total_count = res_total_count.scalar()
|
79
70
|
|
80
|
-
|
81
|
-
return AccountingPage(
|
71
|
+
return PaginationResponse[AccountingRecordRead](
|
82
72
|
total_count=total_count,
|
83
|
-
page_size=
|
73
|
+
page_size=page_size,
|
84
74
|
current_page=page,
|
85
|
-
|
75
|
+
items=[record.model_dump() for record in records],
|
86
76
|
)
|
87
77
|
|
88
78
|
|
{fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/admin/v2/task.py
RENAMED
@@ -68,7 +68,7 @@ async def query_tasks(
|
|
68
68
|
db: AsyncSession = Depends(get_async_db),
|
69
69
|
) -> list[TaskV2Info]:
|
70
70
|
"""
|
71
|
-
Query `TaskV2` table and get
|
71
|
+
Query `TaskV2` table and get information about related items
|
72
72
|
(WorkflowV2s and ProjectV2s)
|
73
73
|
|
74
74
|
Args:
|
@@ -470,7 +470,7 @@ async def _get_workflowtask_check_history_owner(
|
|
470
470
|
dataset_id: int,
|
471
471
|
user_id: int,
|
472
472
|
db: AsyncSession,
|
473
|
-
) ->
|
473
|
+
) -> WorkflowTaskV2:
|
474
474
|
"""
|
475
475
|
Verify user access for the history of this dataset and workflowtask.
|
476
476
|
|
@@ -479,9 +479,6 @@ async def _get_workflowtask_check_history_owner(
|
|
479
479
|
workflow_task_id:
|
480
480
|
user_id:
|
481
481
|
db:
|
482
|
-
|
483
|
-
Returns:
|
484
|
-
List of WorkflowTask IDs
|
485
482
|
"""
|
486
483
|
workflowtask = await db.get(WorkflowTaskV2, workflowtask_id)
|
487
484
|
if workflowtask is None:
|
@@ -495,3 +492,4 @@ async def _get_workflowtask_check_history_owner(
|
|
495
492
|
user_id=user_id,
|
496
493
|
db=db,
|
497
494
|
)
|
495
|
+
return workflowtask
|
{fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/history.py
RENAMED
@@ -1,25 +1,28 @@
|
|
1
|
+
from pathlib import Path
|
1
2
|
from typing import Optional
|
2
3
|
|
3
4
|
from fastapi import APIRouter
|
4
5
|
from fastapi import Depends
|
5
6
|
from fastapi import HTTPException
|
6
|
-
from fastapi import Query
|
7
7
|
from fastapi import status
|
8
8
|
from fastapi.responses import JSONResponse
|
9
|
+
from pydantic import BaseModel
|
9
10
|
from sqlmodel import func
|
10
11
|
from sqlmodel import select
|
11
12
|
|
12
13
|
from ._aux_functions import _get_dataset_check_owner
|
13
14
|
from ._aux_functions import _get_workflow_check_owner
|
14
|
-
from ._aux_functions import
|
15
|
+
from ._aux_functions import _get_workflowtask_check_history_owner
|
15
16
|
from fractal_server.app.db import AsyncSession
|
16
17
|
from fractal_server.app.db import get_async_db
|
17
18
|
from fractal_server.app.history.status_enum import HistoryItemImageStatus
|
18
19
|
from fractal_server.app.models import UserOAuth
|
19
20
|
from fractal_server.app.models.v2 import HistoryItemV2
|
20
21
|
from fractal_server.app.models.v2 import ImageStatus
|
21
|
-
from fractal_server.app.models.v2 import WorkflowTaskV2
|
22
22
|
from fractal_server.app.routes.auth import current_active_user
|
23
|
+
from fractal_server.app.routes.pagination import get_pagination_params
|
24
|
+
from fractal_server.app.routes.pagination import PaginationRequest
|
25
|
+
from fractal_server.app.routes.pagination import PaginationResponse
|
23
26
|
from fractal_server.app.schemas.v2.history import HistoryItemV2Read
|
24
27
|
|
25
28
|
router = APIRouter()
|
@@ -122,16 +125,10 @@ async def get_per_workflowtask_subsets_aggregated_info(
|
|
122
125
|
user: UserOAuth = Depends(current_active_user),
|
123
126
|
db: AsyncSession = Depends(get_async_db),
|
124
127
|
) -> JSONResponse:
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
detail="WorkflowTask not found",
|
130
|
-
)
|
131
|
-
await _get_workflow_task_check_owner(
|
132
|
-
project_id=project_id,
|
133
|
-
workflow_id=wftask.workflow_id,
|
134
|
-
workflow_task_id=workflowtask_id,
|
128
|
+
|
129
|
+
await _get_workflowtask_check_history_owner(
|
130
|
+
dataset_id=dataset_id,
|
131
|
+
workflowtask_id=workflowtask_id,
|
135
132
|
user_id=user.id,
|
136
133
|
db=db,
|
137
134
|
)
|
@@ -143,20 +140,27 @@ async def get_per_workflowtask_subsets_aggregated_info(
|
|
143
140
|
.group_by(ImageStatus.parameters_hash)
|
144
141
|
)
|
145
142
|
res = await db.execute(stm)
|
146
|
-
|
143
|
+
hash_to_statuses = res.all()
|
147
144
|
|
148
|
-
|
149
|
-
for
|
150
|
-
|
151
|
-
|
145
|
+
subsets = []
|
146
|
+
for parameters_hash, statuses in hash_to_statuses:
|
147
|
+
# Get the oldest HistoryItemV2 matching with `parameters_hash`
|
148
|
+
stm = (
|
149
|
+
select(HistoryItemV2)
|
152
150
|
.where(HistoryItemV2.workflowtask_id == workflowtask_id)
|
153
151
|
.where(HistoryItemV2.dataset_id == dataset_id)
|
154
|
-
.where(HistoryItemV2.parameters_hash ==
|
152
|
+
.where(HistoryItemV2.parameters_hash == parameters_hash)
|
153
|
+
.order_by(HistoryItemV2.timestamp_started)
|
154
|
+
.limit(1)
|
155
155
|
)
|
156
|
-
|
156
|
+
res = await db.execute(stm)
|
157
|
+
oldest_history_item = res.scalar_one()
|
158
|
+
|
159
|
+
subsets.append(
|
157
160
|
{
|
158
|
-
"
|
159
|
-
"
|
161
|
+
"_timestamp": oldest_history_item.timestamp_started,
|
162
|
+
"workflowtask_dump": oldest_history_item.workflowtask_dump,
|
163
|
+
"parameters_hash": parameters_hash,
|
160
164
|
"info": {
|
161
165
|
"num_done_images": statuses.count(
|
162
166
|
HistoryItemImageStatus.DONE
|
@@ -171,7 +175,11 @@ async def get_per_workflowtask_subsets_aggregated_info(
|
|
171
175
|
}
|
172
176
|
)
|
173
177
|
|
174
|
-
|
178
|
+
# Use `_timestamp` values for sorting, and then drop them from the response
|
179
|
+
sorted_results = sorted(subsets, key=lambda obj: obj["_timestamp"])
|
180
|
+
[item.pop("_timestamp") for item in sorted_results]
|
181
|
+
|
182
|
+
return JSONResponse(content=sorted_results, status_code=200)
|
175
183
|
|
176
184
|
|
177
185
|
@router.get("/project/{project_id}/status/images/")
|
@@ -181,30 +189,18 @@ async def get_per_workflowtask_images(
|
|
181
189
|
dataset_id: int,
|
182
190
|
status: HistoryItemImageStatus,
|
183
191
|
parameters_hash: Optional[str] = None,
|
184
|
-
# Pagination
|
185
|
-
page: int = Query(default=1, ge=1),
|
186
|
-
page_size: Optional[int] = Query(default=None, ge=1),
|
187
192
|
# Dependencies
|
193
|
+
pagination: PaginationRequest = Depends(get_pagination_params),
|
188
194
|
user: UserOAuth = Depends(current_active_user),
|
189
195
|
db: AsyncSession = Depends(get_async_db),
|
190
|
-
) ->
|
196
|
+
) -> PaginationResponse[str]:
|
191
197
|
|
192
|
-
|
193
|
-
|
194
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
195
|
-
detail=(f"Invalid pagination parameters: {page=}, {page_size=}."),
|
196
|
-
)
|
198
|
+
page = pagination.page
|
199
|
+
page_size = pagination.page_size
|
197
200
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
202
|
-
detail="WorkflowTask not found",
|
203
|
-
)
|
204
|
-
await _get_workflow_task_check_owner(
|
205
|
-
project_id=project_id,
|
206
|
-
workflow_id=wftask.workflow_id,
|
207
|
-
workflow_task_id=workflowtask_id,
|
201
|
+
await _get_workflowtask_check_history_owner(
|
202
|
+
dataset_id=dataset_id,
|
203
|
+
workflowtask_id=workflowtask_id,
|
208
204
|
user_id=user.id,
|
209
205
|
db=db,
|
210
206
|
)
|
@@ -228,20 +224,82 @@ async def get_per_workflowtask_images(
|
|
228
224
|
)
|
229
225
|
query = query.where(ImageStatus.parameters_hash == parameters_hash)
|
230
226
|
|
227
|
+
res_total_count = await db.execute(total_count_stm)
|
228
|
+
total_count = res_total_count.scalar()
|
229
|
+
|
231
230
|
if page_size is not None:
|
232
231
|
query = query.limit(page_size)
|
232
|
+
else:
|
233
|
+
page_size = total_count
|
234
|
+
|
233
235
|
if page > 1:
|
234
236
|
query = query.offset((page - 1) * page_size)
|
235
237
|
|
236
|
-
res_total_count = await db.execute(total_count_stm)
|
237
|
-
total_count = res_total_count.scalar()
|
238
|
-
|
239
238
|
res = await db.execute(query)
|
240
239
|
images = res.scalars().all()
|
241
240
|
|
242
|
-
return
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
241
|
+
return PaginationResponse[str](
|
242
|
+
total_count=total_count,
|
243
|
+
page_size=page_size,
|
244
|
+
current_page=page,
|
245
|
+
items=images,
|
246
|
+
)
|
247
|
+
|
248
|
+
|
249
|
+
class ImageLogsRequest(BaseModel):
|
250
|
+
workflowtask_id: int
|
251
|
+
dataset_id: int
|
252
|
+
zarr_url: str
|
253
|
+
|
254
|
+
|
255
|
+
@router.post("/project/{project_id}/status/image-logs/")
|
256
|
+
async def get_image_logs(
|
257
|
+
project_id: int,
|
258
|
+
request_data: ImageLogsRequest,
|
259
|
+
user: UserOAuth = Depends(current_active_user),
|
260
|
+
db: AsyncSession = Depends(get_async_db),
|
261
|
+
) -> JSONResponse:
|
262
|
+
|
263
|
+
wftask = await _get_workflowtask_check_history_owner(
|
264
|
+
dataset_id=request_data.dataset_id,
|
265
|
+
workflowtask_id=request_data.workflowtask_id,
|
266
|
+
user_id=user.id,
|
267
|
+
db=db,
|
268
|
+
)
|
269
|
+
|
270
|
+
image_status = await db.get(
|
271
|
+
ImageStatus,
|
272
|
+
(
|
273
|
+
request_data.zarr_url,
|
274
|
+
request_data.workflowtask_id,
|
275
|
+
request_data.dataset_id,
|
276
|
+
),
|
277
|
+
)
|
278
|
+
if image_status is None:
|
279
|
+
raise HTTPException(
|
280
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
281
|
+
detail="ImageStatus not found",
|
282
|
+
)
|
283
|
+
|
284
|
+
if image_status.logfile is None:
|
285
|
+
return JSONResponse(
|
286
|
+
content=(
|
287
|
+
f"Logs for task '{wftask.task.name}' in dataset "
|
288
|
+
f"{request_data.dataset_id} are not yet available."
|
289
|
+
)
|
290
|
+
)
|
291
|
+
|
292
|
+
logfile = Path(image_status.logfile)
|
293
|
+
if not logfile.exists():
|
294
|
+
return JSONResponse(
|
295
|
+
content=(
|
296
|
+
f"Error while retrieving logs for task '{wftask.task.name}' "
|
297
|
+
f"in dataset {request_data.dataset_id}: "
|
298
|
+
f"file '{logfile}' is not available."
|
299
|
+
)
|
300
|
+
)
|
301
|
+
|
302
|
+
with logfile.open("r") as f:
|
303
|
+
file_contents = f.read()
|
304
|
+
|
305
|
+
return JSONResponse(content=file_contents)
|
{fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/routes/api/v2/images.py
RENAMED
@@ -17,6 +17,9 @@ from fractal_server.app.db import AsyncSession
|
|
17
17
|
from fractal_server.app.db import get_async_db
|
18
18
|
from fractal_server.app.models import UserOAuth
|
19
19
|
from fractal_server.app.routes.auth import current_active_user
|
20
|
+
from fractal_server.app.routes.pagination import get_pagination_params
|
21
|
+
from fractal_server.app.routes.pagination import PaginationRequest
|
22
|
+
from fractal_server.app.routes.pagination import PaginationResponse
|
20
23
|
from fractal_server.app.schemas._filter_validators import (
|
21
24
|
validate_attribute_filters,
|
22
25
|
)
|
@@ -31,17 +34,11 @@ from fractal_server.images.tools import match_filter
|
|
31
34
|
router = APIRouter()
|
32
35
|
|
33
36
|
|
34
|
-
class ImagePage(
|
35
|
-
|
36
|
-
total_count: int
|
37
|
-
page_size: int
|
38
|
-
current_page: int
|
37
|
+
class ImagePage(PaginationResponse[SingleImage]):
|
39
38
|
|
40
39
|
attributes: dict[str, list[Any]]
|
41
40
|
types: list[str]
|
42
41
|
|
43
|
-
images: list[SingleImage]
|
44
|
-
|
45
42
|
|
46
43
|
class ImageQuery(BaseModel):
|
47
44
|
zarr_url: Optional[str] = None
|
@@ -118,18 +115,14 @@ async def post_new_image(
|
|
118
115
|
async def query_dataset_images(
|
119
116
|
project_id: int,
|
120
117
|
dataset_id: int,
|
121
|
-
|
122
|
-
|
123
|
-
query: Optional[ImageQuery] = None, # body
|
118
|
+
query: Optional[ImageQuery] = None,
|
119
|
+
pagination: PaginationRequest = Depends(get_pagination_params),
|
124
120
|
user: UserOAuth = Depends(current_active_user),
|
125
121
|
db: AsyncSession = Depends(get_async_db),
|
126
122
|
) -> ImagePage:
|
127
123
|
|
128
|
-
|
129
|
-
|
130
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
131
|
-
detail=f"Invalid pagination parameter: page={page} < 1",
|
132
|
-
)
|
124
|
+
page = pagination.page
|
125
|
+
page_size = pagination.page_size
|
133
126
|
|
134
127
|
output = await _get_dataset_check_owner(
|
135
128
|
project_id=project_id, dataset_id=dataset_id, user_id=user.id, db=db
|
@@ -177,20 +170,10 @@ async def query_dataset_images(
|
|
177
170
|
|
178
171
|
total_count = len(images)
|
179
172
|
|
180
|
-
if page_size is
|
181
|
-
if page_size <= 0:
|
182
|
-
raise HTTPException(
|
183
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
184
|
-
detail=(
|
185
|
-
f"Invalid pagination parameter: page_size={page_size} <= 0"
|
186
|
-
),
|
187
|
-
)
|
188
|
-
else:
|
173
|
+
if page_size is None:
|
189
174
|
page_size = total_count
|
190
175
|
|
191
|
-
if total_count
|
192
|
-
page = 1
|
193
|
-
else:
|
176
|
+
if total_count > 0:
|
194
177
|
last_page = (total_count // page_size) + (total_count % page_size > 0)
|
195
178
|
if page > last_page:
|
196
179
|
page = last_page
|
@@ -201,9 +184,9 @@ async def query_dataset_images(
|
|
201
184
|
total_count=total_count,
|
202
185
|
current_page=page,
|
203
186
|
page_size=page_size,
|
187
|
+
items=images,
|
204
188
|
attributes=attributes,
|
205
189
|
types=types,
|
206
|
-
images=images,
|
207
190
|
)
|
208
191
|
|
209
192
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
from typing import Generic
|
2
|
+
from typing import Optional
|
3
|
+
from typing import TypeVar
|
4
|
+
|
5
|
+
from fastapi import HTTPException
|
6
|
+
from pydantic import BaseModel
|
7
|
+
from pydantic import Field
|
8
|
+
from pydantic import model_validator
|
9
|
+
from pydantic import ValidationError
|
10
|
+
|
11
|
+
T = TypeVar("T")
|
12
|
+
|
13
|
+
|
14
|
+
class PaginationRequest(BaseModel):
|
15
|
+
|
16
|
+
page: int = Field(ge=1)
|
17
|
+
page_size: Optional[int] = Field(ge=1)
|
18
|
+
|
19
|
+
@model_validator(mode="after")
|
20
|
+
def valid_pagination_parameters(self):
|
21
|
+
if self.page_size is None and self.page > 1:
|
22
|
+
raise ValueError(
|
23
|
+
f"page_size is None but page={self.page} is greater than 1."
|
24
|
+
)
|
25
|
+
return self
|
26
|
+
|
27
|
+
|
28
|
+
def get_pagination_params(
|
29
|
+
page: int = 1, page_size: Optional[int] = None
|
30
|
+
) -> PaginationRequest:
|
31
|
+
try:
|
32
|
+
pagination = PaginationRequest(page=page, page_size=page_size)
|
33
|
+
except ValidationError as e:
|
34
|
+
raise HTTPException(
|
35
|
+
status_code=422,
|
36
|
+
detail=f"Invalid pagination parameters. Original error: '{e}'.",
|
37
|
+
)
|
38
|
+
return pagination
|
39
|
+
|
40
|
+
|
41
|
+
class PaginationResponse(BaseModel, Generic[T]):
|
42
|
+
|
43
|
+
current_page: int = Field(ge=1)
|
44
|
+
page_size: int = Field(ge=0)
|
45
|
+
total_count: int = Field(ge=0)
|
46
|
+
|
47
|
+
items: list[T]
|
@@ -106,7 +106,8 @@ class BaseRunner(object):
|
|
106
106
|
)
|
107
107
|
if _COMPONENT_KEY_ not in single_kwargs.keys():
|
108
108
|
raise ValueError(
|
109
|
-
f"No '{_COMPONENT_KEY_}' key
|
109
|
+
f"No '{_COMPONENT_KEY_}' key "
|
110
|
+
f"in {list(single_kwargs.keys())}"
|
110
111
|
)
|
111
112
|
if not in_compound_task:
|
112
113
|
zarr_urls = [kwargs["zarr_url"] for kwargs in list_parameters]
|
@@ -21,18 +21,10 @@ def _local_submit_setup(
|
|
21
21
|
FIXME
|
22
22
|
|
23
23
|
Arguments:
|
24
|
-
wftask:
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
workflow_dir_remote:
|
29
|
-
Not used in this function.
|
30
|
-
|
31
|
-
Returns:
|
32
|
-
submit_setup_dict:
|
33
|
-
A dictionary that will be passed on to
|
34
|
-
`FractalThreadPoolExecutor.submit` and
|
35
|
-
`FractalThreadPoolExecutor.map`, so as to set extra options.
|
24
|
+
wftask: WorkflowTask for which the configuration is to be assembled
|
25
|
+
root_dir_local:
|
26
|
+
root_dir_rempote: Not used in this function.
|
27
|
+
which_type: Whether it is a parallel or non-parallel task.
|
36
28
|
"""
|
37
29
|
|
38
30
|
local_backend_config = get_local_backend_config(
|
@@ -43,7 +35,7 @@ def _local_submit_setup(
|
|
43
35
|
# Get TaskFiles object
|
44
36
|
task_files = TaskFiles(
|
45
37
|
root_dir_local=root_dir_local,
|
46
|
-
root_dir_remote=
|
38
|
+
root_dir_remote=root_dir_local,
|
47
39
|
task_order=wftask.order,
|
48
40
|
task_name=wftask.task.name,
|
49
41
|
)
|
@@ -213,7 +213,7 @@ class SlurmConfig(BaseModel):
|
|
213
213
|
expected file content are defined in
|
214
214
|
[`SlurmConfigFile`](./#fractal_server.app.runner._slurm._slurm_config.SlurmConfigFile)).
|
215
215
|
|
216
|
-
Part of the attributes map directly to some of the SLURM
|
216
|
+
Part of the attributes map directly to some of the SLURM attributes (see
|
217
217
|
https://slurm.schedmd.com/sbatch.html), e.g. `partition`. Other attributes
|
218
218
|
are metaparameters which are needed in fractal-server to combine multiple
|
219
219
|
tasks in the same SLURM job (e.g. `parallel_tasks_per_job` or
|
@@ -19,7 +19,7 @@ def get_slurm_config(
|
|
19
19
|
Prepare a `SlurmConfig` configuration object
|
20
20
|
|
21
21
|
The argument `which_type` determines whether we use `wftask.meta_parallel`
|
22
|
-
or `wftask.meta_non_parallel`. In the following
|
22
|
+
or `wftask.meta_non_parallel`. In the following description, let us assume
|
23
23
|
that `which_type="parallel"`.
|
24
24
|
|
25
25
|
The sources for `SlurmConfig` attributes, in increasing priority order, are
|
@@ -134,7 +134,7 @@ def worker(
|
|
134
134
|
_extra_import_paths = extra_import_paths.split(":")
|
135
135
|
sys.path[:0] = _extra_import_paths
|
136
136
|
|
137
|
-
# Execute the job and
|
137
|
+
# Execute the job and capture exceptions
|
138
138
|
try:
|
139
139
|
with open(in_fname, "rb") as f:
|
140
140
|
indata = f.read()
|
{fractal_server-2.14.0a1 → fractal_server-2.14.0a3}/fractal_server/app/runner/v2/__init__.py
RENAMED
@@ -2,7 +2,7 @@
|
|
2
2
|
Runner backend subsystem root V2
|
3
3
|
|
4
4
|
This module is the single entry point to the runner backend subsystem V2.
|
5
|
-
Other
|
5
|
+
Other subsystems should only import this module and not its submodules or
|
6
6
|
the individual backends.
|
7
7
|
"""
|
8
8
|
import os
|
@@ -118,7 +118,7 @@ def submit_workflow(
|
|
118
118
|
)
|
119
119
|
except Exception as e:
|
120
120
|
logger.error(
|
121
|
-
f"Error
|
121
|
+
f"Error connecting to the database. Original error: {str(e)}"
|
122
122
|
)
|
123
123
|
reset_logger_handlers(logger)
|
124
124
|
return
|
@@ -127,7 +127,7 @@ def execute_tasks_v2(
|
|
127
127
|
dataset_id=dataset.id,
|
128
128
|
parameters_hash=parameters_hash,
|
129
129
|
status=HistoryItemImageStatus.SUBMITTED,
|
130
|
-
logfile=
|
130
|
+
logfile=None,
|
131
131
|
)
|
132
132
|
)
|
133
133
|
db.commit()
|
@@ -198,7 +198,8 @@ def execute_tasks_v2(
|
|
198
198
|
# Update image list
|
199
199
|
num_new_images = 0
|
200
200
|
current_task_output.check_zarr_urls_are_unique()
|
201
|
-
# FIXME: Introduce for loop over task outputs, and processe them
|
201
|
+
# FIXME: Introduce for loop over task outputs, and processe them
|
202
|
+
# sequentially
|
202
203
|
# each failure should lead to an update of the specific image status
|
203
204
|
for image_obj in current_task_output.image_list_updates:
|
204
205
|
image = image_obj.model_dump()
|