fractal-server 2.17.1a1__tar.gz → 2.18.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.17.1a1 → fractal_server-2.18.0}/PKG-INFO +3 -2
- fractal_server-2.18.0/fractal_server/__init__.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/__main__.py +21 -19
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/db/__init__.py +3 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/__init__.py +1 -0
- fractal_server-2.18.0/fractal_server/app/models/linkuserproject.py +53 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/security.py +28 -8
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/__init__.py +3 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/accounting.py +9 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/dataset.py +5 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/history.py +15 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/job.py +17 -2
- fractal_server-2.18.0/fractal_server/app/models/v2/profile.py +45 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/project.py +4 -10
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/resource.py +17 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/task_group.py +4 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/workflow.py +2 -1
- fractal_server-2.18.0/fractal_server/app/routes/admin/v2/__init__.py +27 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/accounting.py +3 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/job.py +35 -24
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/profile.py +3 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/resource.py +5 -5
- fractal_server-2.18.0/fractal_server/app/routes/admin/v2/sharing.py +103 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/task.py +37 -26
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/task_group.py +94 -17
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +21 -22
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/__init__.py +1 -9
- fractal_server-2.18.0/fractal_server/app/routes/api/v2/__init__.py +72 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/_aux_functions.py +132 -124
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/_aux_functions_history.py +51 -23
- fractal_server-2.18.0/fractal_server/app/routes/api/v2/_aux_functions_sharing.py +97 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +6 -8
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +7 -9
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +1 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/dataset.py +95 -102
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/history.py +59 -33
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/images.py +24 -9
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/job.py +52 -33
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/pre_submission_checks.py +16 -8
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/project.py +65 -37
- fractal_server-2.18.0/fractal_server/app/routes/api/v2/sharing.py +311 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/status_legacy.py +31 -41
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/submit.py +82 -78
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/task.py +19 -20
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/task_collection.py +41 -43
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/task_collection_custom.py +19 -20
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/task_collection_pixi.py +10 -11
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/task_group.py +25 -24
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +32 -32
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/task_version_update.py +23 -19
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/workflow.py +50 -55
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/workflow_import.py +37 -37
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/workflowtask.py +32 -26
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/__init__.py +1 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/_aux_auth.py +101 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/current_user.py +2 -66
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/group.py +8 -35
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/login.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/oauth.py +4 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/register.py +4 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/router.py +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/auth/users.py +19 -10
- fractal_server-2.18.0/fractal_server/app/routes/auth/viewer_paths.py +43 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/aux/_job.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/aux/_runner.py +2 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/user.py +29 -12
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/user_group.py +0 -15
- fractal_server-2.18.0/fractal_server/app/schemas/v2/__init__.py +78 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/accounting.py +11 -0
- fractal_server-2.18.0/fractal_server/app/schemas/v2/dataset.py +126 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/dumps.py +10 -9
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/job.py +11 -11
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/manifest.py +4 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/profile.py +53 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/project.py +3 -3
- fractal_server-2.18.0/fractal_server/app/schemas/v2/resource.py +242 -0
- fractal_server-2.18.0/fractal_server/app/schemas/v2/sharing.py +99 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/status_legacy.py +3 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/task.py +6 -7
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/task_collection.py +5 -5
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/task_group.py +16 -16
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/workflow.py +16 -16
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/workflowtask.py +16 -15
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/security/__init__.py +5 -8
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/security/signup_email.py +4 -5
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/shutdown.py +6 -6
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/config/__init__.py +0 -6
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/config/_database.py +19 -20
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/config/_email.py +30 -38
- fractal_server-2.18.0/fractal_server/config/_main.py +64 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/config/_oauth.py +17 -21
- fractal_server-2.18.0/fractal_server/data_migrations/2_18_0.py +30 -0
- fractal_server-2.18.0/fractal_server/exceptions.py +6 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/images/models.py +4 -5
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/images/status_tools.py +4 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/main.py +75 -13
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +4 -8
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +1 -0
- fractal_server-2.18.0/fractal_server/migrations/versions/40d6d6511b20_add_index_to_history_models.py +47 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/49d0856e9569_drop_table.py +2 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +2 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +7 -19
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/5bf02391cfef_v2.py +4 -10
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +1 -0
- fractal_server-2.18.0/fractal_server/migrations/versions/7910eed4cf97_user_project_dirs_and_usergroup_viewer_.py +60 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +1 -0
- fractal_server-2.18.0/fractal_server/migrations/versions/88270f589c9b_add_prevent_new_submissions.py +39 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +2 -4
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +2 -4
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +1 -0
- fractal_server-2.18.0/fractal_server/migrations/versions/bc0e8b3327a7_project_sharing.py +72 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +4 -9
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +1 -0
- fractal_server-2.18.0/fractal_server/migrations/versions/e0e717ae2f26_delete_linkuserproject_ondelete_project.py +50 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +1 -0
- fractal_server-2.18.0/fractal_server/migrations/versions/f0702066b007_one_submitted_job_per_dataset.py +40 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +4 -9
- fractal_server-2.18.0/fractal_server/runner/config/_local.py +24 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/config/_slurm.py +39 -33
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/config/slurm_mem_to_MB.py +0 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/base_runner.py +29 -4
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/local/get_local_config.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/local/runner.py +14 -13
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_common/_batching.py +9 -20
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_common/base_slurm_runner.py +53 -27
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_common/get_slurm_config.py +14 -7
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_common/remote.py +3 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_common/slurm_config.py +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +1 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_ssh/runner.py +16 -11
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_ssh/tar_commands.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_sudo/runner.py +16 -11
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/task_files.py +9 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/_local.py +12 -6
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/_slurm_ssh.py +14 -7
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/_slurm_sudo.py +14 -7
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/db_tools.py +0 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/deduplicate_list.py +2 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/runner.py +44 -28
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/runner_functions.py +22 -28
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/submit_workflow.py +29 -15
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/ssh/_fabric.py +6 -13
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/string_tools.py +0 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/config/_python.py +16 -9
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/utils.py +0 -1
- fractal_server-2.18.0/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/_utils.py +3 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/collect.py +15 -18
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/collect_pixi.py +14 -16
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/deactivate.py +14 -15
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/deactivate_pixi.py +7 -7
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/delete.py +6 -8
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/reactivate.py +12 -12
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/reactivate_pixi.py +12 -12
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/_utils.py +3 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/collect.py +19 -24
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/collect_pixi.py +22 -24
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/deactivate.py +17 -15
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/deactivate_pixi.py +8 -7
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/delete.py +12 -10
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/reactivate.py +16 -16
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/reactivate_pixi.py +13 -14
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/1_create_venv.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/2_pip_install.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/4_pip_show.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +3 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/pixi_1_extract.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/pixi_2_install.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/templates/pixi_3_post_install.sh +2 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/utils_background.py +10 -10
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/utils_database.py +5 -5
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/utils_package_names.py +1 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/utils_pixi.py +1 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/types/__init__.py +98 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/types/validators/__init__.py +3 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/types/validators/_common_validators.py +33 -3
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/types/validators/_workflow_task_arguments_validators.py +1 -2
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/utils.py +1 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/zip_tools.py +34 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/pyproject.toml +19 -5
- fractal_server-2.17.1a1/fractal_server/__init__.py +0 -1
- fractal_server-2.17.1a1/fractal_server/app/models/linkuserproject.py +0 -11
- fractal_server-2.17.1a1/fractal_server/app/models/v2/profile.py +0 -16
- fractal_server-2.17.1a1/fractal_server/app/routes/admin/v2/__init__.py +0 -28
- fractal_server-2.17.1a1/fractal_server/app/routes/admin/v2/project.py +0 -41
- fractal_server-2.17.1a1/fractal_server/app/routes/api/v2/__init__.py +0 -73
- fractal_server-2.17.1a1/fractal_server/app/schemas/v2/__init__.py +0 -71
- fractal_server-2.17.1a1/fractal_server/app/schemas/v2/dataset.py +0 -80
- fractal_server-2.17.1a1/fractal_server/app/schemas/v2/resource.py +0 -137
- fractal_server-2.17.1a1/fractal_server/config/_data.py +0 -68
- fractal_server-2.17.1a1/fractal_server/config/_main.py +0 -78
- fractal_server-2.17.1a1/fractal_server/exceptions.py +0 -2
- fractal_server-2.17.1a1/fractal_server/runner/config/_local.py +0 -21
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/LICENSE +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/README.md +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/task.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/_aux_functions.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/aux/validate_user_profile.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/pagination.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/schemas/v2/history.py +0 -0
- fractal_server-2.17.1a1/fractal_server/py.typed → fractal_server-2.18.0/fractal_server/config/_data.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/config/_settings_config.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/logger.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/1a83a5260664_rename.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/45fbb391d7af_make_resource_id_fk_non_nullable.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/7673fe18c05d_remove_project_dir_server_default.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/791ce783d3d8_add_indices.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/caba9fb1ea5e_drop_useroauth_user_settings_id.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +1 -1
- fractal_server-2.17.1a1/fractal_server/runner/__init__.py → fractal_server-2.18.0/fractal_server/py.typed +0 -0
- {fractal_server-2.17.1a1/fractal_server/runner/executors → fractal_server-2.18.0/fractal_server/runner}/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/components.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/config/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/exceptions.py +0 -0
- {fractal_server-2.17.1a1/fractal_server/runner/executors/local → fractal_server-2.18.0/fractal_server/runner/executors}/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/call_command_wrapper.py +0 -0
- {fractal_server-2.17.1a1/fractal_server/runner/executors/slurm_common → fractal_server-2.18.0/fractal_server/runner/executors/local}/__init__.py +0 -0
- {fractal_server-2.17.1a1/fractal_server/runner/executors/slurm_ssh → fractal_server-2.18.0/fractal_server/runner/executors/slurm_common}/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_common/_job_states.py +0 -0
- {fractal_server-2.17.1a1/fractal_server/runner/executors/slurm_sudo → fractal_server-2.18.0/fractal_server/runner/executors/slurm_ssh}/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/executors/slurm_ssh/run_subprocess.py +0 -0
- {fractal_server-2.17.1a1/fractal_server/runner/v2 → fractal_server-2.18.0/fractal_server/runner/executors/slurm_sudo}/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/filenames.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.17.1a1/fractal_server/tasks → fractal_server-2.18.0/fractal_server/runner}/v2/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/v2/task_interface.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/runner/versions.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/syringe.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/config/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/config/_pixi.py +1 -1
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/local/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/tasks/v2/utils_templates.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/types/validators/_filter_validators.py +0 -0
- {fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/urls.py +0 -0
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fractal-server
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.18.0
|
|
4
4
|
Summary: Backend component of the Fractal analytics platform
|
|
5
5
|
License-Expression: BSD-3-Clause
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Author: Tommaso Comparin
|
|
8
8
|
Author-email: tommaso.comparin@exact-lab.it
|
|
9
|
-
Requires-Python: >=3.11,<3.
|
|
9
|
+
Requires-Python: >=3.11,<3.15
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
15
|
Requires-Dist: alembic (>=1.13.1,<2.0.0)
|
|
15
16
|
Requires-Dist: fabric (>=3.2.2,<3.3.0)
|
|
16
17
|
Requires-Dist: fastapi (>=0.120.0,<0.121.0)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__VERSION__ = "2.18.0"
|
|
@@ -7,7 +7,6 @@ from pathlib import Path
|
|
|
7
7
|
import uvicorn
|
|
8
8
|
from pydantic import ValidationError
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
parser = ap.ArgumentParser(description="fractal-server commands")
|
|
12
11
|
|
|
13
12
|
subparsers = parser.add_subparsers(title="Commands", dest="cmd", required=True)
|
|
@@ -48,9 +47,7 @@ openapi_parser.add_argument(
|
|
|
48
47
|
# fractalctl set-db
|
|
49
48
|
set_db_parser = subparsers.add_parser(
|
|
50
49
|
"set-db",
|
|
51
|
-
description=
|
|
52
|
-
"Initialise/upgrade database schemas and create first group&user."
|
|
53
|
-
),
|
|
50
|
+
description="Initialise/upgrade database schemas.",
|
|
54
51
|
)
|
|
55
52
|
|
|
56
53
|
# fractalctl init-db-data
|
|
@@ -114,12 +111,13 @@ def set_db():
|
|
|
114
111
|
Call alembic to upgrade to the latest migration.
|
|
115
112
|
Ref: https://stackoverflow.com/a/56683030/283972
|
|
116
113
|
"""
|
|
117
|
-
from
|
|
118
|
-
from fractal_server.config import get_db_settings
|
|
114
|
+
from pathlib import Path
|
|
119
115
|
|
|
120
116
|
import alembic.config
|
|
121
|
-
|
|
117
|
+
|
|
122
118
|
import fractal_server
|
|
119
|
+
from fractal_server.config import get_db_settings
|
|
120
|
+
from fractal_server.syringe import Inject
|
|
123
121
|
|
|
124
122
|
# Validate DB settings
|
|
125
123
|
Inject(get_db_settings)
|
|
@@ -140,15 +138,18 @@ def init_db_data(
|
|
|
140
138
|
admin_password: str | None = None,
|
|
141
139
|
admin_project_dir: str | None = None,
|
|
142
140
|
) -> None:
|
|
143
|
-
from
|
|
144
|
-
from
|
|
141
|
+
from sqlalchemy import func
|
|
142
|
+
from sqlalchemy import select
|
|
143
|
+
|
|
145
144
|
from fractal_server.app.db import get_sync_db
|
|
146
|
-
from
|
|
145
|
+
from fractal_server.app.models import Profile
|
|
146
|
+
from fractal_server.app.models import Resource
|
|
147
147
|
from fractal_server.app.models.security import UserOAuth
|
|
148
|
-
from fractal_server.app.models import Resource, Profile
|
|
149
|
-
from fractal_server.app.schemas.v2.resource import cast_serialize_resource
|
|
150
|
-
from fractal_server.app.schemas.v2.profile import cast_serialize_profile
|
|
151
148
|
from fractal_server.app.schemas.v2 import ResourceType
|
|
149
|
+
from fractal_server.app.schemas.v2.profile import cast_serialize_profile
|
|
150
|
+
from fractal_server.app.schemas.v2.resource import cast_serialize_resource
|
|
151
|
+
from fractal_server.app.security import _create_first_group
|
|
152
|
+
from fractal_server.app.security import _create_first_user
|
|
152
153
|
|
|
153
154
|
# Create default group and user
|
|
154
155
|
print()
|
|
@@ -166,7 +167,8 @@ def init_db_data(
|
|
|
166
167
|
"`--admin-pwd` and `--admin-project-dir`. Exit."
|
|
167
168
|
)
|
|
168
169
|
sys.exit(1)
|
|
169
|
-
|
|
170
|
+
|
|
171
|
+
if admin_email:
|
|
170
172
|
asyncio.run(
|
|
171
173
|
_create_first_user(
|
|
172
174
|
email=admin_email,
|
|
@@ -185,9 +187,7 @@ def init_db_data(
|
|
|
185
187
|
if resource and profile:
|
|
186
188
|
with next(get_sync_db()) as db:
|
|
187
189
|
# Preliminary check
|
|
188
|
-
num_resources = db.execute(
|
|
189
|
-
select(func.count(Resource.id))
|
|
190
|
-
).scalar()
|
|
190
|
+
num_resources = db.execute(select(func.count(Resource.id))).scalar()
|
|
191
191
|
if num_resources != 0:
|
|
192
192
|
print(f"There exist already {num_resources=} resources. Exit.")
|
|
193
193
|
sys.exit(1)
|
|
@@ -270,10 +270,12 @@ def update_db_data():
|
|
|
270
270
|
Apply data migrations.
|
|
271
271
|
"""
|
|
272
272
|
|
|
273
|
-
import
|
|
273
|
+
import os
|
|
274
274
|
from importlib import import_module
|
|
275
|
+
|
|
275
276
|
from packaging.version import parse
|
|
276
|
-
|
|
277
|
+
|
|
278
|
+
import fractal_server
|
|
277
279
|
|
|
278
280
|
def _slugify_version(raw_version: str) -> str:
|
|
279
281
|
v = parse(raw_version)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
`db` module, loosely adapted from
|
|
3
3
|
https://testdriven.io/blog/fastapi-sqlmodel/#async-sqlmodel
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
from collections.abc import AsyncGenerator
|
|
6
7
|
from collections.abc import Generator
|
|
7
8
|
|
|
@@ -15,7 +16,6 @@ from fractal_server.config import get_db_settings
|
|
|
15
16
|
from fractal_server.logger import set_logger
|
|
16
17
|
from fractal_server.syringe import Inject
|
|
17
18
|
|
|
18
|
-
|
|
19
19
|
logger = set_logger(__name__)
|
|
20
20
|
|
|
21
21
|
|
|
@@ -46,7 +46,7 @@ class DB:
|
|
|
46
46
|
|
|
47
47
|
cls._engine_async = create_async_engine(
|
|
48
48
|
db_settings.DATABASE_URL,
|
|
49
|
-
echo=db_settings.DB_ECHO,
|
|
49
|
+
echo=(db_settings.DB_ECHO == "true"),
|
|
50
50
|
future=True,
|
|
51
51
|
pool_pre_ping=True,
|
|
52
52
|
)
|
|
@@ -63,7 +63,7 @@ class DB:
|
|
|
63
63
|
|
|
64
64
|
cls._engine_sync = create_engine(
|
|
65
65
|
db_settings.DATABASE_URL,
|
|
66
|
-
echo=db_settings.DB_ECHO,
|
|
66
|
+
echo=(db_settings.DB_ECHO == "true"),
|
|
67
67
|
future=True,
|
|
68
68
|
pool_pre_ping=True,
|
|
69
69
|
)
|
|
@@ -3,6 +3,7 @@ Note that this module is imported from `fractal_server/migrations/env.py`,
|
|
|
3
3
|
thus we should always export all relevant database models from here or they
|
|
4
4
|
will not be picked up by alembic.
|
|
5
5
|
"""
|
|
6
|
+
|
|
6
7
|
from .linkusergroup import LinkUserGroup # noqa: F401
|
|
7
8
|
from .linkuserproject import LinkUserProjectV2 # noqa: F401
|
|
8
9
|
from .security import * # noqa
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from sqlmodel import BOOLEAN
|
|
2
|
+
from sqlmodel import CheckConstraint
|
|
3
|
+
from sqlmodel import Column
|
|
4
|
+
from sqlmodel import Field
|
|
5
|
+
from sqlmodel import Index
|
|
6
|
+
from sqlmodel import SQLModel
|
|
7
|
+
from sqlmodel import String
|
|
8
|
+
from sqlmodel import column
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class LinkUserProjectV2(SQLModel, table=True):
|
|
12
|
+
"""
|
|
13
|
+
Crossing table between User and ProjectV2
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
project_id: int = Field(
|
|
17
|
+
foreign_key="projectv2.id", primary_key=True, ondelete="CASCADE"
|
|
18
|
+
)
|
|
19
|
+
user_id: int = Field(foreign_key="user_oauth.id", primary_key=True)
|
|
20
|
+
|
|
21
|
+
# TODO-2.18.1 drop server_default
|
|
22
|
+
is_owner: bool = Field(
|
|
23
|
+
sa_column=Column(BOOLEAN, server_default="true", nullable=False)
|
|
24
|
+
)
|
|
25
|
+
# TODO-2.18.1 drop server_default
|
|
26
|
+
is_verified: bool = Field(
|
|
27
|
+
sa_column=Column(BOOLEAN, server_default="true", nullable=False)
|
|
28
|
+
)
|
|
29
|
+
# TODO-2.18.1 drop server_default
|
|
30
|
+
permissions: str = Field(
|
|
31
|
+
sa_column=Column(String, server_default="'rwx'", nullable=False)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__table_args__ = (
|
|
35
|
+
Index(
|
|
36
|
+
"ix_linkuserprojectv2_one_owner_per_project",
|
|
37
|
+
"project_id",
|
|
38
|
+
unique=True,
|
|
39
|
+
postgresql_where=column("is_owner").is_(True),
|
|
40
|
+
),
|
|
41
|
+
CheckConstraint(
|
|
42
|
+
"NOT (is_owner AND NOT is_verified)",
|
|
43
|
+
name="owner_is_verified",
|
|
44
|
+
),
|
|
45
|
+
CheckConstraint(
|
|
46
|
+
"NOT (is_owner AND permissions <> 'rwx')",
|
|
47
|
+
name="owner_full_permissions",
|
|
48
|
+
),
|
|
49
|
+
CheckConstraint(
|
|
50
|
+
"permissions IN ('r', 'rw', 'rwx')",
|
|
51
|
+
name="valid_permissions",
|
|
52
|
+
),
|
|
53
|
+
)
|
|
@@ -6,7 +6,6 @@ from pydantic import EmailStr
|
|
|
6
6
|
from sqlalchemy import Column
|
|
7
7
|
from sqlalchemy import String
|
|
8
8
|
from sqlalchemy.dialects.postgresql import ARRAY
|
|
9
|
-
from sqlalchemy.dialects.postgresql import JSONB
|
|
10
9
|
from sqlalchemy.types import DateTime
|
|
11
10
|
from sqlmodel import Field
|
|
12
11
|
from sqlmodel import Relationship
|
|
@@ -52,21 +51,39 @@ class UserOAuth(SQLModel, table=True):
|
|
|
52
51
|
"""
|
|
53
52
|
ORM model for the `user_oauth` database table.
|
|
54
53
|
|
|
55
|
-
This class is a modification of
|
|
56
|
-
fastapi_users_db_sqlmodel.
|
|
57
|
-
|
|
54
|
+
This class is a modification of
|
|
55
|
+
[`SQLModelBaseUserDB`](https://github.com/fastapi-users/fastapi-users-db-sqlmodel/blob/83980d7f20886120f4636a102ab1822b4c366f63/fastapi_users_db_sqlmodel/__init__.py#L15-L32)
|
|
56
|
+
from `fastapi_users_db_sqlmodel`.
|
|
57
|
+
Original Copyright: 2022 François Voron, released under MIT licence.
|
|
58
|
+
|
|
59
|
+
Note that several class attributes are
|
|
60
|
+
[the default ones from `fastapi-users`
|
|
61
|
+
](https://fastapi-users.github.io/fastapi-users/latest/configuration/schemas/).
|
|
58
62
|
|
|
59
63
|
Attributes:
|
|
60
64
|
id:
|
|
61
65
|
email:
|
|
62
66
|
hashed_password:
|
|
63
67
|
is_active:
|
|
68
|
+
If this is `False`, the user has no access to the `/api/v2/`
|
|
69
|
+
endpoints.
|
|
64
70
|
is_superuser:
|
|
65
71
|
is_verified:
|
|
72
|
+
If this is `False`, the user has no access to the `/api/v2/`
|
|
73
|
+
endpoints.
|
|
66
74
|
oauth_accounts:
|
|
67
75
|
profile_id:
|
|
76
|
+
Foreign key linking the user to a `Profile`. If this is unset,
|
|
77
|
+
the user has no access to the `/api/v2/` endpoints.
|
|
68
78
|
project_dir:
|
|
79
|
+
Absolute path of the user's project directory. This is used (A) as
|
|
80
|
+
a default base folder for the `zarr_dir` of new datasets (where
|
|
81
|
+
the output Zarr are located), and (B) as a folder which is included
|
|
82
|
+
by default in the paths that a user is allowed to stream (if the
|
|
83
|
+
`fractal-data` integration is set up).
|
|
84
|
+
two goals:
|
|
69
85
|
slurm_accounts:
|
|
86
|
+
List of SLURM accounts that the user can select upon running a job.
|
|
70
87
|
"""
|
|
71
88
|
|
|
72
89
|
model_config = ConfigDict(from_attributes=True)
|
|
@@ -95,7 +112,13 @@ class UserOAuth(SQLModel, table=True):
|
|
|
95
112
|
ondelete="RESTRICT",
|
|
96
113
|
)
|
|
97
114
|
|
|
98
|
-
|
|
115
|
+
# TODO-2.18.1: drop `project_dir`
|
|
116
|
+
project_dir: str | None = Field(default=None, nullable=True)
|
|
117
|
+
# TODO-2.18.1: `project_dirs: list[str] = Field(min_length=1)`
|
|
118
|
+
project_dirs: list[str] = Field(
|
|
119
|
+
sa_column=Column(ARRAY(String), nullable=False, server_default="{}"),
|
|
120
|
+
)
|
|
121
|
+
|
|
99
122
|
slurm_accounts: list[str] = Field(
|
|
100
123
|
sa_column=Column(ARRAY(String), server_default="{}"),
|
|
101
124
|
)
|
|
@@ -117,6 +140,3 @@ class UserGroup(SQLModel, table=True):
|
|
|
117
140
|
default_factory=get_timestamp,
|
|
118
141
|
sa_column=Column(DateTime(timezone=True), nullable=False),
|
|
119
142
|
)
|
|
120
|
-
viewer_paths: list[str] = Field(
|
|
121
|
-
sa_column=Column(JSONB, server_default="[]", nullable=False)
|
|
122
|
-
)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""
|
|
2
2
|
v2 `models` module
|
|
3
3
|
"""
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
from fractal_server.app.models.linkuserproject import LinkUserProjectV2
|
|
6
|
+
|
|
5
7
|
from .accounting import AccountingRecord
|
|
6
8
|
from .accounting import AccountingRecordSlurm
|
|
7
9
|
from .dataset import DatasetV2
|
{fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/accounting.py
RENAMED
|
@@ -7,10 +7,14 @@ from sqlalchemy.types import DateTime
|
|
|
7
7
|
from sqlmodel import Field
|
|
8
8
|
from sqlmodel import SQLModel
|
|
9
9
|
|
|
10
|
-
from
|
|
10
|
+
from fractal_server.utils import get_timestamp
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class AccountingRecord(SQLModel, table=True):
|
|
14
|
+
"""
|
|
15
|
+
AccountingRecord table.
|
|
16
|
+
"""
|
|
17
|
+
|
|
14
18
|
id: int | None = Field(default=None, primary_key=True)
|
|
15
19
|
user_id: int = Field(foreign_key="user_oauth.id", nullable=False)
|
|
16
20
|
timestamp: datetime = Field(
|
|
@@ -22,6 +26,10 @@ class AccountingRecord(SQLModel, table=True):
|
|
|
22
26
|
|
|
23
27
|
|
|
24
28
|
class AccountingRecordSlurm(SQLModel, table=True):
|
|
29
|
+
"""
|
|
30
|
+
AccountingRecordSlurm table.
|
|
31
|
+
"""
|
|
32
|
+
|
|
25
33
|
id: int | None = Field(default=None, primary_key=True)
|
|
26
34
|
user_id: int = Field(foreign_key="user_oauth.id", nullable=False)
|
|
27
35
|
timestamp: datetime = Field(
|
|
@@ -9,10 +9,14 @@ from sqlmodel import Field
|
|
|
9
9
|
from sqlmodel import Relationship
|
|
10
10
|
from sqlmodel import SQLModel
|
|
11
11
|
|
|
12
|
-
from
|
|
12
|
+
from fractal_server.utils import get_timestamp
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class DatasetV2(SQLModel, table=True):
|
|
16
|
+
"""
|
|
17
|
+
Dataset table.
|
|
18
|
+
"""
|
|
19
|
+
|
|
16
20
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
17
21
|
|
|
18
22
|
id: int | None = Field(default=None, primary_key=True)
|
|
@@ -10,10 +10,14 @@ from sqlalchemy.types import DateTime
|
|
|
10
10
|
from sqlmodel import Field
|
|
11
11
|
from sqlmodel import SQLModel
|
|
12
12
|
|
|
13
|
-
from
|
|
13
|
+
from fractal_server.utils import get_timestamp
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class HistoryRun(SQLModel, table=True):
|
|
17
|
+
"""
|
|
18
|
+
HistoryRun table.
|
|
19
|
+
"""
|
|
20
|
+
|
|
17
21
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
18
22
|
|
|
19
23
|
id: int | None = Field(default=None, primary_key=True)
|
|
@@ -45,10 +49,15 @@ class HistoryRun(SQLModel, table=True):
|
|
|
45
49
|
|
|
46
50
|
|
|
47
51
|
class HistoryUnit(SQLModel, table=True):
|
|
52
|
+
"""
|
|
53
|
+
HistoryUnit table.
|
|
54
|
+
"""
|
|
55
|
+
|
|
48
56
|
id: int | None = Field(default=None, primary_key=True)
|
|
49
57
|
history_run_id: int = Field(
|
|
50
58
|
foreign_key="historyrun.id",
|
|
51
59
|
ondelete="CASCADE",
|
|
60
|
+
index=True,
|
|
52
61
|
)
|
|
53
62
|
|
|
54
63
|
logfile: str
|
|
@@ -60,6 +69,10 @@ class HistoryUnit(SQLModel, table=True):
|
|
|
60
69
|
|
|
61
70
|
|
|
62
71
|
class HistoryImageCache(SQLModel, table=True):
|
|
72
|
+
"""
|
|
73
|
+
HistoryImageCache table.
|
|
74
|
+
"""
|
|
75
|
+
|
|
63
76
|
zarr_url: str = Field(primary_key=True)
|
|
64
77
|
dataset_id: int = Field(
|
|
65
78
|
primary_key=True,
|
|
@@ -77,4 +90,5 @@ class HistoryImageCache(SQLModel, table=True):
|
|
|
77
90
|
latest_history_unit_id: int = Field(
|
|
78
91
|
foreign_key="historyunit.id",
|
|
79
92
|
ondelete="CASCADE",
|
|
93
|
+
index=True,
|
|
80
94
|
)
|
|
@@ -6,13 +6,19 @@ from sqlalchemy import Column
|
|
|
6
6
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
7
7
|
from sqlalchemy.types import DateTime
|
|
8
8
|
from sqlmodel import Field
|
|
9
|
+
from sqlmodel import Index
|
|
9
10
|
from sqlmodel import SQLModel
|
|
11
|
+
from sqlmodel import text
|
|
10
12
|
|
|
11
|
-
from fractal_server.app.schemas.v2 import
|
|
13
|
+
from fractal_server.app.schemas.v2 import JobStatusType
|
|
12
14
|
from fractal_server.utils import get_timestamp
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class JobV2(SQLModel, table=True):
|
|
18
|
+
"""
|
|
19
|
+
Job table.
|
|
20
|
+
"""
|
|
21
|
+
|
|
16
22
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
|
17
23
|
|
|
18
24
|
id: int | None = Field(default=None, primary_key=True)
|
|
@@ -52,7 +58,7 @@ class JobV2(SQLModel, table=True):
|
|
|
52
58
|
end_timestamp: datetime | None = Field(
|
|
53
59
|
default=None, sa_column=Column(DateTime(timezone=True))
|
|
54
60
|
)
|
|
55
|
-
status: str =
|
|
61
|
+
status: str = JobStatusType.SUBMITTED
|
|
56
62
|
log: str | None = None
|
|
57
63
|
executor_error_log: str | None = None
|
|
58
64
|
|
|
@@ -62,3 +68,12 @@ class JobV2(SQLModel, table=True):
|
|
|
62
68
|
type_filters: dict[str, bool] = Field(
|
|
63
69
|
sa_column=Column(JSONB, nullable=False, server_default="{}")
|
|
64
70
|
)
|
|
71
|
+
|
|
72
|
+
__table_args__ = (
|
|
73
|
+
Index(
|
|
74
|
+
"ix_jobv2_one_submitted_job_per_dataset",
|
|
75
|
+
"dataset_id",
|
|
76
|
+
unique=True,
|
|
77
|
+
postgresql_where=text(f"status = '{JobStatusType.SUBMITTED}'"),
|
|
78
|
+
),
|
|
79
|
+
)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from sqlmodel import Field
|
|
2
|
+
from sqlmodel import SQLModel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Profile(SQLModel, table=True):
|
|
6
|
+
"""
|
|
7
|
+
Profile table.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
id: int | None = Field(default=None, primary_key=True)
|
|
11
|
+
|
|
12
|
+
resource_id: int = Field(foreign_key="resource.id", ondelete="RESTRICT")
|
|
13
|
+
|
|
14
|
+
resource_type: str
|
|
15
|
+
"""
|
|
16
|
+
Type of resource (either `local`, `slurm_sudo` or `slurm_ssh`).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
name: str = Field(unique=True)
|
|
20
|
+
"""
|
|
21
|
+
Profile name.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
username: str | None = None
|
|
25
|
+
"""
|
|
26
|
+
Username to be impersonated, either via `sudo -u` or via `ssh`.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
ssh_key_path: str | None = None
|
|
30
|
+
"""
|
|
31
|
+
Path to the private SSH key of user `username` (only relevant if
|
|
32
|
+
`resource_type="slurm_ssh"`).
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
jobs_remote_dir: str | None = None
|
|
36
|
+
"""
|
|
37
|
+
Remote path of the job folder (only relevant if
|
|
38
|
+
`resource_type="slurm_ssh"`).
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
tasks_remote_dir: str | None = None
|
|
42
|
+
"""
|
|
43
|
+
Remote path of the task folder (only relevant if
|
|
44
|
+
`resource_type="slurm_ssh"`).
|
|
45
|
+
"""
|
|
@@ -3,15 +3,16 @@ from datetime import datetime
|
|
|
3
3
|
from sqlalchemy import Column
|
|
4
4
|
from sqlalchemy.types import DateTime
|
|
5
5
|
from sqlmodel import Field
|
|
6
|
-
from sqlmodel import Relationship
|
|
7
6
|
from sqlmodel import SQLModel
|
|
8
7
|
|
|
9
|
-
from .. import LinkUserProjectV2
|
|
10
|
-
from fractal_server.app.models import UserOAuth
|
|
11
8
|
from fractal_server.utils import get_timestamp
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
class ProjectV2(SQLModel, table=True):
|
|
12
|
+
"""
|
|
13
|
+
Project table.
|
|
14
|
+
"""
|
|
15
|
+
|
|
15
16
|
id: int | None = Field(default=None, primary_key=True)
|
|
16
17
|
name: str
|
|
17
18
|
|
|
@@ -20,10 +21,3 @@ class ProjectV2(SQLModel, table=True):
|
|
|
20
21
|
default_factory=get_timestamp,
|
|
21
22
|
sa_column=Column(DateTime(timezone=True), nullable=False),
|
|
22
23
|
)
|
|
23
|
-
|
|
24
|
-
user_list: list[UserOAuth] = Relationship(
|
|
25
|
-
link_model=LinkUserProjectV2,
|
|
26
|
-
sa_relationship_kwargs={
|
|
27
|
-
"lazy": "selectin",
|
|
28
|
-
},
|
|
29
|
-
)
|
|
@@ -5,6 +5,7 @@ from typing import Self
|
|
|
5
5
|
from sqlalchemy import Column
|
|
6
6
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
7
7
|
from sqlalchemy.types import DateTime
|
|
8
|
+
from sqlmodel import BOOLEAN
|
|
8
9
|
from sqlmodel import CheckConstraint
|
|
9
10
|
from sqlmodel import Field
|
|
10
11
|
from sqlmodel import SQLModel
|
|
@@ -13,6 +14,10 @@ from fractal_server.utils import get_timestamp
|
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class Resource(SQLModel, table=True):
|
|
17
|
+
"""
|
|
18
|
+
Resource table.
|
|
19
|
+
"""
|
|
20
|
+
|
|
16
21
|
id: int | None = Field(default=None, primary_key=True)
|
|
17
22
|
|
|
18
23
|
type: str
|
|
@@ -39,6 +44,18 @@ class Resource(SQLModel, table=True):
|
|
|
39
44
|
Address for ssh connections, when `type="slurm_ssh"`.
|
|
40
45
|
"""
|
|
41
46
|
|
|
47
|
+
prevent_new_submissions: bool = Field(
|
|
48
|
+
sa_column=Column(
|
|
49
|
+
BOOLEAN,
|
|
50
|
+
server_default="false",
|
|
51
|
+
nullable=False,
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
"""
|
|
55
|
+
When set to true: Prevent new job submissions and stop execution of
|
|
56
|
+
ongoing jobs as soon as the current task is complete.
|
|
57
|
+
"""
|
|
58
|
+
|
|
42
59
|
jobs_local_dir: str
|
|
43
60
|
"""
|
|
44
61
|
Base local folder for job subfolders (containing artifacts and logs).
|
{fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/models/v2/task_group.py
RENAMED
|
@@ -8,9 +8,10 @@ from sqlmodel import Field
|
|
|
8
8
|
from sqlmodel import Relationship
|
|
9
9
|
from sqlmodel import SQLModel
|
|
10
10
|
|
|
11
|
-
from .task import TaskV2
|
|
12
11
|
from fractal_server.utils import get_timestamp
|
|
13
12
|
|
|
13
|
+
from .task import TaskV2
|
|
14
|
+
|
|
14
15
|
|
|
15
16
|
def _check_origin_not_pixi(origin: str):
|
|
16
17
|
"""
|
|
@@ -22,10 +23,10 @@ def _check_origin_not_pixi(origin: str):
|
|
|
22
23
|
|
|
23
24
|
def _create_dependency_string(pinned_versions: dict[str, str]) -> str:
|
|
24
25
|
"""
|
|
25
|
-
Expand e.g. `{"a": "1.2", "b": "3"}` into `"a==1.2 b==3"`.
|
|
26
|
+
Expand e.g. `{"a": "1.2", "b": "3"}` into `'"a==1.2" "b==3"'`.
|
|
26
27
|
"""
|
|
27
28
|
output = " ".join(
|
|
28
|
-
[f"{key}=={value}" for key, value in pinned_versions.items()]
|
|
29
|
+
[f'"{key}=={value}"' for key, value in pinned_versions.items()]
|
|
29
30
|
)
|
|
30
31
|
return output
|
|
31
32
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
`admin/v2` module
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from fastapi import APIRouter
|
|
6
|
+
|
|
7
|
+
from .accounting import router as accounting_router
|
|
8
|
+
from .impersonate import router as impersonate_router
|
|
9
|
+
from .job import router as job_router
|
|
10
|
+
from .profile import router as profile_router
|
|
11
|
+
from .resource import router as resource_router
|
|
12
|
+
from .sharing import router as sharing_router
|
|
13
|
+
from .task import router as task_router
|
|
14
|
+
from .task_group import router as task_group_router
|
|
15
|
+
from .task_group_lifecycle import router as task_group_lifecycle_router
|
|
16
|
+
|
|
17
|
+
router_admin = APIRouter()
|
|
18
|
+
|
|
19
|
+
router_admin.include_router(accounting_router, prefix="/accounting")
|
|
20
|
+
router_admin.include_router(job_router, prefix="/job")
|
|
21
|
+
router_admin.include_router(task_router, prefix="/task")
|
|
22
|
+
router_admin.include_router(task_group_router, prefix="/task-group")
|
|
23
|
+
router_admin.include_router(task_group_lifecycle_router, prefix="/task-group")
|
|
24
|
+
router_admin.include_router(impersonate_router, prefix="/impersonate")
|
|
25
|
+
router_admin.include_router(resource_router, prefix="/resource")
|
|
26
|
+
router_admin.include_router(profile_router, prefix="/profile")
|
|
27
|
+
router_admin.include_router(sharing_router, prefix="/linkuserproject")
|
{fractal_server-2.17.1a1 → fractal_server-2.18.0}/fractal_server/app/routes/admin/v2/accounting.py
RENAMED
|
@@ -14,9 +14,9 @@ from fractal_server.app.models import UserOAuth
|
|
|
14
14
|
from fractal_server.app.models.v2 import AccountingRecord
|
|
15
15
|
from fractal_server.app.models.v2 import AccountingRecordSlurm
|
|
16
16
|
from fractal_server.app.routes.auth import current_superuser_act
|
|
17
|
-
from fractal_server.app.routes.pagination import get_pagination_params
|
|
18
17
|
from fractal_server.app.routes.pagination import PaginationRequest
|
|
19
18
|
from fractal_server.app.routes.pagination import PaginationResponse
|
|
19
|
+
from fractal_server.app.routes.pagination import get_pagination_params
|
|
20
20
|
from fractal_server.app.schemas.v2 import AccountingRecordRead
|
|
21
21
|
|
|
22
22
|
|
|
@@ -67,11 +67,11 @@ async def query_accounting(
|
|
|
67
67
|
res = await db.execute(stm)
|
|
68
68
|
records = res.scalars().all()
|
|
69
69
|
|
|
70
|
-
return
|
|
70
|
+
return dict(
|
|
71
71
|
total_count=total_count,
|
|
72
72
|
page_size=page_size,
|
|
73
73
|
current_page=page,
|
|
74
|
-
items=
|
|
74
|
+
items=records,
|
|
75
75
|
)
|
|
76
76
|
|
|
77
77
|
|