fractal-server 2.17.0a0__tar.gz → 2.17.0a2__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.0a0 → fractal_server-2.17.0a2}/PKG-INFO +1 -1
- fractal_server-2.17.0a2/fractal_server/__init__.py +1 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/__main__.py +10 -8
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/__init__.py +9 -0
- fractal_server-2.17.0a2/fractal_server/app/routes/auth/oauth.py +72 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/router.py +4 -2
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/aux/validate_user_profile.py +4 -4
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/profile.py +8 -2
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/resource.py +32 -12
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/config/__init__.py +5 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/config/_main.py +0 -95
- fractal_server-2.17.0a2/fractal_server/config/_oauth.py +69 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/pyproject.toml +2 -2
- fractal_server-2.17.0a0/fractal_server/__init__.py +0 -1
- fractal_server-2.17.0a0/fractal_server/app/routes/auth/oauth.py +0 -65
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/LICENSE +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/README.md +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/accounting.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/history.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/profile.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/resource.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/task.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/task_group.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/_aux_functions.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/job.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/profile.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/resource.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/task.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/history.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/pre_submission_checks.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/status_legacy.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/task_collection_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/task_group.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/task_version_update.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/workflow.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/pagination.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/accounting.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/dataset.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/history.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/task_collection.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/task_group.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/security/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/security/signup_email.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/shutdown.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/config/_database.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/config/_email.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/config/_init_data.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/config/_settings_config.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/data_migrations/2_14_10.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/exceptions.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/images/models.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/images/status_tools.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/logger.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/main.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/1a83a5260664_rename.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/791ce783d3d8_add_indices.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/90f6508c6379_drop_useroauth_username.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/a80ac5a352bf_resource_profile.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/py.typed +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/components.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/config/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/config/_local.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/config/_slurm.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/config/slurm_mem_to_MB.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/exceptions.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/base_runner.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/call_command_wrapper.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/local/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/local/get_local_config.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/local/runner.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/_batching.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/_job_states.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/base_slurm_runner.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/get_slurm_config.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/remote.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/slurm_config.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_ssh/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_ssh/run_subprocess.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_ssh/runner.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_ssh/tar_commands.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_sudo/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/executors/slurm_sudo/runner.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/filenames.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/task_files.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/_local.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/_slurm_ssh.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/_slurm_sudo.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/db_tools.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/runner.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/runner_functions.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/submit_workflow.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/v2/task_interface.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/runner/versions.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/ssh/_fabric.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/string_tools.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/syringe.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/config/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/config/_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/config/_python.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/utils.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/_utils.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/collect.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/collect_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/deactivate.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/deactivate_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/delete.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/reactivate.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/local/reactivate_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/collect.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/collect_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/deactivate_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/delete.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/ssh/reactivate_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/pixi_1_extract.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/pixi_2_install.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/templates/pixi_3_post_install.sh +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/utils_background.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/utils_database.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/utils_package_names.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/utils_pixi.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/tasks/v2/utils_templates.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/types/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/types/validators/__init__.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/types/validators/_common_validators.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/types/validators/_filter_validators.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/types/validators/_workflow_task_arguments_validators.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/urls.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/utils.py +0 -0
- {fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/zip_tools.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__VERSION__ = "2.17.0a2"
|
|
@@ -136,8 +136,8 @@ def init_db_data(
|
|
|
136
136
|
from sqlalchemy import select, func
|
|
137
137
|
from fractal_server.app.models.security import UserOAuth
|
|
138
138
|
from fractal_server.app.models import Resource, Profile
|
|
139
|
-
from fractal_server.app.schemas.v2.resource import
|
|
140
|
-
from fractal_server.app.schemas.v2.profile import
|
|
139
|
+
from fractal_server.app.schemas.v2.resource import cast_serialize_resource
|
|
140
|
+
from fractal_server.app.schemas.v2.profile import cast_serialize_profile
|
|
141
141
|
|
|
142
142
|
init_data_settings = Inject(get_init_data_settings)
|
|
143
143
|
|
|
@@ -203,15 +203,17 @@ def init_db_data(
|
|
|
203
203
|
|
|
204
204
|
# Validate resource/profile data
|
|
205
205
|
try:
|
|
206
|
-
|
|
206
|
+
resource_data = cast_serialize_resource(resource_data)
|
|
207
207
|
except ValidationError as e:
|
|
208
|
-
|
|
209
|
-
|
|
208
|
+
sys.exit(
|
|
209
|
+
f"ERROR: Invalid resource data.\nOriginal error:\n{str(e)}"
|
|
210
|
+
)
|
|
210
211
|
try:
|
|
211
|
-
|
|
212
|
+
profile_data = cast_serialize_profile(profile_data)
|
|
212
213
|
except ValidationError as e:
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
sys.exit(
|
|
215
|
+
f"ERROR: Invalid profile data.\nOriginal error:\n{str(e)}"
|
|
216
|
+
)
|
|
215
217
|
|
|
216
218
|
# Create resource/profile db objects
|
|
217
219
|
resource_obj = Resource(**resource_data)
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/api/__init__.py
RENAMED
|
@@ -9,6 +9,7 @@ from fractal_server.app.models import UserOAuth
|
|
|
9
9
|
from fractal_server.app.routes.auth import current_active_superuser
|
|
10
10
|
from fractal_server.config import get_db_settings
|
|
11
11
|
from fractal_server.config import get_email_settings
|
|
12
|
+
from fractal_server.config import get_oauth_settings
|
|
12
13
|
from fractal_server.config import get_settings
|
|
13
14
|
from fractal_server.syringe import Inject
|
|
14
15
|
|
|
@@ -45,3 +46,11 @@ async def view_email_settings(
|
|
|
45
46
|
):
|
|
46
47
|
settings = Inject(get_email_settings)
|
|
47
48
|
return settings.model_dump()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@router_api.get("/settings/oauth/")
|
|
52
|
+
async def view_oauth_settings(
|
|
53
|
+
user: UserOAuth = Depends(current_active_superuser),
|
|
54
|
+
):
|
|
55
|
+
settings = Inject(get_oauth_settings)
|
|
56
|
+
return settings.model_dump()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from fastapi import APIRouter
|
|
2
|
+
from httpx_oauth.clients.github import GitHubOAuth2
|
|
3
|
+
from httpx_oauth.clients.google import GoogleOAuth2
|
|
4
|
+
from httpx_oauth.clients.openid import OpenID
|
|
5
|
+
|
|
6
|
+
from . import cookie_backend
|
|
7
|
+
from . import fastapi_users
|
|
8
|
+
from fractal_server.config import get_oauth_settings
|
|
9
|
+
from fractal_server.config import get_settings
|
|
10
|
+
from fractal_server.config import OAuthSettings
|
|
11
|
+
from fractal_server.syringe import Inject
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _create_client_github(cfg: OAuthSettings) -> GitHubOAuth2:
|
|
15
|
+
return GitHubOAuth2(
|
|
16
|
+
client_id=cfg.OAUTH_CLIENT_ID.get_secret_value(),
|
|
17
|
+
client_secret=cfg.OAUTH_CLIENT_SECRET.get_secret_value(),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _create_client_google(cfg: OAuthSettings) -> GoogleOAuth2:
|
|
22
|
+
return GoogleOAuth2(
|
|
23
|
+
client_id=cfg.OAUTH_CLIENT_ID.get_secret_value(),
|
|
24
|
+
client_secret=cfg.OAUTH_CLIENT_SECRET.get_secret_value(),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _create_client_oidc(cfg: OAuthSettings) -> OpenID:
|
|
29
|
+
return OpenID(
|
|
30
|
+
client_id=cfg.OAUTH_CLIENT_ID.get_secret_value(),
|
|
31
|
+
client_secret=cfg.OAUTH_CLIENT_SECRET.get_secret_value(),
|
|
32
|
+
openid_configuration_endpoint=cfg.OAUTH_OIDC_CONFIG_ENDPOINT,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_oauth_router() -> APIRouter | None:
|
|
37
|
+
"""
|
|
38
|
+
Get the `APIRouter` object for OAuth endpoints.
|
|
39
|
+
"""
|
|
40
|
+
router_oauth = APIRouter()
|
|
41
|
+
settings = Inject(get_settings)
|
|
42
|
+
oauth_settings = Inject(get_oauth_settings)
|
|
43
|
+
if not oauth_settings.is_set:
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
client_name = oauth_settings.OAUTH_CLIENT_NAME
|
|
47
|
+
|
|
48
|
+
if client_name == "google":
|
|
49
|
+
client = _create_client_google(oauth_settings)
|
|
50
|
+
elif client_name == "github":
|
|
51
|
+
client = _create_client_github(oauth_settings)
|
|
52
|
+
else:
|
|
53
|
+
client = _create_client_oidc(oauth_settings)
|
|
54
|
+
|
|
55
|
+
router_oauth.include_router(
|
|
56
|
+
fastapi_users.get_oauth_router(
|
|
57
|
+
client,
|
|
58
|
+
cookie_backend,
|
|
59
|
+
settings.JWT_SECRET_KEY,
|
|
60
|
+
is_verified_by_default=False,
|
|
61
|
+
associate_by_email=True,
|
|
62
|
+
redirect_url=oauth_settings.OAUTH_REDIRECT_URL,
|
|
63
|
+
),
|
|
64
|
+
prefix=f"/{client_name}",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Add trailing slash to all routes' paths
|
|
68
|
+
for route in router_oauth.routes:
|
|
69
|
+
if not route.path.endswith("/"):
|
|
70
|
+
route.path = f"{route.path}/"
|
|
71
|
+
|
|
72
|
+
return router_oauth
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/auth/router.py
RENAMED
|
@@ -3,7 +3,7 @@ from fastapi import APIRouter
|
|
|
3
3
|
from .current_user import router_current_user
|
|
4
4
|
from .group import router_group
|
|
5
5
|
from .login import router_login
|
|
6
|
-
from .oauth import
|
|
6
|
+
from .oauth import get_oauth_router
|
|
7
7
|
from .register import router_register
|
|
8
8
|
from .users import router_users
|
|
9
9
|
|
|
@@ -14,4 +14,6 @@ router_auth.include_router(router_current_user)
|
|
|
14
14
|
router_auth.include_router(router_login)
|
|
15
15
|
router_auth.include_router(router_users)
|
|
16
16
|
router_auth.include_router(router_group)
|
|
17
|
-
|
|
17
|
+
router_oauth = get_oauth_router()
|
|
18
|
+
if router_oauth is not None:
|
|
19
|
+
router_auth.include_router(router_oauth)
|
|
@@ -6,8 +6,8 @@ from fractal_server.app.db import AsyncSession
|
|
|
6
6
|
from fractal_server.app.models import Profile
|
|
7
7
|
from fractal_server.app.models import Resource
|
|
8
8
|
from fractal_server.app.models import UserOAuth
|
|
9
|
-
from fractal_server.app.schemas.v2.profile import
|
|
10
|
-
from fractal_server.app.schemas.v2.resource import
|
|
9
|
+
from fractal_server.app.schemas.v2.profile import cast_serialize_profile
|
|
10
|
+
from fractal_server.app.schemas.v2.resource import cast_serialize_resource
|
|
11
11
|
from fractal_server.logger import set_logger
|
|
12
12
|
|
|
13
13
|
logger = set_logger(__name__)
|
|
@@ -38,10 +38,10 @@ async def validate_user_profile(
|
|
|
38
38
|
profile = await db.get(Profile, user.profile_id)
|
|
39
39
|
resource = await db.get(Resource, profile.resource_id)
|
|
40
40
|
try:
|
|
41
|
-
|
|
41
|
+
cast_serialize_resource(
|
|
42
42
|
resource.model_dump(exclude={"id", "timestamp_created"}),
|
|
43
43
|
)
|
|
44
|
-
|
|
44
|
+
cast_serialize_profile(
|
|
45
45
|
profile.model_dump(exclude={"resource_id", "id"}),
|
|
46
46
|
)
|
|
47
47
|
db.expunge(resource)
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/profile.py
RENAMED
|
@@ -65,8 +65,14 @@ class ProfileRead(BaseModel):
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
@validate_call
|
|
68
|
-
def
|
|
68
|
+
def cast_serialize_profile(_data: ProfileCreate) -> dict[str, Any]:
|
|
69
69
|
"""
|
|
70
|
-
|
|
70
|
+
Cast/serialize round-trip for `Profile` data.
|
|
71
|
+
|
|
72
|
+
We use `@validate_call` because `ProfileeCreate` is a `Union` type and it
|
|
71
73
|
cannot be instantiated directly.
|
|
74
|
+
|
|
75
|
+
Return:
|
|
76
|
+
Serialized version of a valid profile object.
|
|
72
77
|
"""
|
|
78
|
+
return _data.model_dump()
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/schemas/v2/resource.py
RENAMED
|
@@ -4,6 +4,7 @@ from typing import Any
|
|
|
4
4
|
from typing import Literal
|
|
5
5
|
from typing import Self
|
|
6
6
|
|
|
7
|
+
from pydantic import AfterValidator
|
|
7
8
|
from pydantic import BaseModel
|
|
8
9
|
from pydantic import Discriminator
|
|
9
10
|
from pydantic import model_validator
|
|
@@ -25,13 +26,27 @@ class ResourceType(StrEnum):
|
|
|
25
26
|
LOCAL = "local"
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
def cast_serialize_pixi_settings(
|
|
30
|
+
v: dict[NonEmptyStr, Any],
|
|
31
|
+
) -> dict[NonEmptyStr, Any]:
|
|
32
|
+
"""
|
|
33
|
+
Validate current value, and enrich it with default values.
|
|
34
|
+
"""
|
|
35
|
+
if v != {}:
|
|
36
|
+
v = TasksPixiSettings(**v).model_dump()
|
|
37
|
+
return v
|
|
38
|
+
|
|
39
|
+
|
|
28
40
|
class _ValidResourceBase(BaseModel):
|
|
29
41
|
type: ResourceType
|
|
30
42
|
name: NonEmptyStr
|
|
31
43
|
|
|
32
44
|
# Tasks
|
|
33
45
|
tasks_python_config: TasksPythonSettings
|
|
34
|
-
tasks_pixi_config:
|
|
46
|
+
tasks_pixi_config: Annotated[
|
|
47
|
+
dict[NonEmptyStr, Any],
|
|
48
|
+
AfterValidator(cast_serialize_pixi_settings),
|
|
49
|
+
]
|
|
35
50
|
tasks_local_dir: AbsolutePathStr
|
|
36
51
|
|
|
37
52
|
# Jobs
|
|
@@ -40,16 +55,15 @@ class _ValidResourceBase(BaseModel):
|
|
|
40
55
|
jobs_poll_interval: int = 5
|
|
41
56
|
|
|
42
57
|
@model_validator(mode="after")
|
|
43
|
-
def
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
)
|
|
58
|
+
def _pixi_slurm_config(self) -> Self:
|
|
59
|
+
if (
|
|
60
|
+
self.tasks_pixi_config != {}
|
|
61
|
+
and self.type == ResourceType.SLURM_SSH
|
|
62
|
+
and self.tasks_pixi_config["SLURM_CONFIG"] is None
|
|
63
|
+
):
|
|
64
|
+
raise ValueError(
|
|
65
|
+
"`tasks_pixi_config` must include `SLURM_CONFIG`."
|
|
66
|
+
)
|
|
53
67
|
return self
|
|
54
68
|
|
|
55
69
|
|
|
@@ -110,8 +124,14 @@ class ResourceRead(BaseModel):
|
|
|
110
124
|
|
|
111
125
|
|
|
112
126
|
@validate_call
|
|
113
|
-
def
|
|
127
|
+
def cast_serialize_resource(_data: ResourceCreate) -> dict[str, Any]:
|
|
114
128
|
"""
|
|
129
|
+
Cast/serialize round-trip for `Resource` data.
|
|
130
|
+
|
|
115
131
|
We use `@validate_call` because `ResourceCreate` is a `Union` type and it
|
|
116
132
|
cannot be instantiated directly.
|
|
133
|
+
|
|
134
|
+
Return:
|
|
135
|
+
Serialized version of a valid resource object.
|
|
117
136
|
"""
|
|
137
|
+
return _data.model_dump()
|
|
@@ -3,6 +3,7 @@ from ._email import EmailSettings
|
|
|
3
3
|
from ._email import PublicEmailSettings # noqa F401
|
|
4
4
|
from ._init_data import InitDataSettings
|
|
5
5
|
from ._main import Settings
|
|
6
|
+
from ._oauth import OAuthSettings
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
def get_db_settings(db_settings=DatabaseSettings()) -> DatabaseSettings:
|
|
@@ -21,3 +22,7 @@ def get_init_data_settings(
|
|
|
21
22
|
init_data_settings=InitDataSettings(),
|
|
22
23
|
) -> InitDataSettings:
|
|
23
24
|
return init_data_settings
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_oauth_settings(oauth_settings=OAuthSettings()) -> OAuthSettings:
|
|
28
|
+
return oauth_settings
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from os import environ
|
|
3
|
-
from os import getenv
|
|
4
2
|
from typing import Literal
|
|
5
3
|
from typing import TypeVar
|
|
6
4
|
|
|
7
|
-
from pydantic import BaseModel
|
|
8
|
-
from pydantic import Field
|
|
9
|
-
from pydantic import model_validator
|
|
10
5
|
from pydantic import SecretStr
|
|
11
6
|
from pydantic_settings import BaseSettings
|
|
12
7
|
from pydantic_settings import SettingsConfigDict
|
|
@@ -22,48 +17,6 @@ class FractalConfigurationError(ValueError):
|
|
|
22
17
|
T = TypeVar("T")
|
|
23
18
|
|
|
24
19
|
|
|
25
|
-
class OAuthClientConfig(BaseModel):
|
|
26
|
-
"""
|
|
27
|
-
OAuth Client Config Model
|
|
28
|
-
|
|
29
|
-
This model wraps the variables that define a client against an Identity
|
|
30
|
-
Provider. As some providers are supported by the libraries used within the
|
|
31
|
-
server, some attributes are optional.
|
|
32
|
-
|
|
33
|
-
Attributes:
|
|
34
|
-
CLIENT_NAME:
|
|
35
|
-
The name of the client
|
|
36
|
-
CLIENT_ID:
|
|
37
|
-
ID of client
|
|
38
|
-
CLIENT_SECRET:
|
|
39
|
-
Secret to authorise against the identity provider
|
|
40
|
-
OIDC_CONFIGURATION_ENDPOINT:
|
|
41
|
-
OpenID configuration endpoint,
|
|
42
|
-
allowing to discover the required endpoints automatically
|
|
43
|
-
REDIRECT_URL:
|
|
44
|
-
String to be used as `redirect_url` argument for
|
|
45
|
-
`fastapi_users.get_oauth_router`, and then in
|
|
46
|
-
`httpx_oauth.integrations.fastapi.OAuth2AuthorizeCallback`.
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
CLIENT_NAME: str
|
|
50
|
-
CLIENT_ID: str
|
|
51
|
-
CLIENT_SECRET: SecretStr
|
|
52
|
-
OIDC_CONFIGURATION_ENDPOINT: str | None = None
|
|
53
|
-
REDIRECT_URL: str | None = None
|
|
54
|
-
|
|
55
|
-
@model_validator(mode="before")
|
|
56
|
-
@classmethod
|
|
57
|
-
def check_configuration(cls, values):
|
|
58
|
-
if values.get("CLIENT_NAME") not in ["GOOGLE", "GITHUB"]:
|
|
59
|
-
if not values.get("OIDC_CONFIGURATION_ENDPOINT"):
|
|
60
|
-
raise FractalConfigurationError(
|
|
61
|
-
f"Missing OAUTH_{values.get('CLIENT_NAME')}"
|
|
62
|
-
"_OIDC_CONFIGURATION_ENDPOINT"
|
|
63
|
-
)
|
|
64
|
-
return values
|
|
65
|
-
|
|
66
|
-
|
|
67
20
|
class Settings(BaseSettings):
|
|
68
21
|
"""
|
|
69
22
|
Contains all the configuration variables for Fractal Server
|
|
@@ -73,8 +26,6 @@ class Settings(BaseSettings):
|
|
|
73
26
|
|
|
74
27
|
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
75
28
|
|
|
76
|
-
OAUTH_CLIENTS_CONFIG: list[OAuthClientConfig] = Field(default_factory=list)
|
|
77
|
-
|
|
78
29
|
# JWT TOKEN
|
|
79
30
|
JWT_EXPIRE_SECONDS: int = 180
|
|
80
31
|
"""
|
|
@@ -95,52 +46,6 @@ class Settings(BaseSettings):
|
|
|
95
46
|
Cookie token lifetime, in seconds.
|
|
96
47
|
"""
|
|
97
48
|
|
|
98
|
-
@model_validator(mode="before")
|
|
99
|
-
@classmethod
|
|
100
|
-
def collect_oauth_clients(cls, values):
|
|
101
|
-
"""
|
|
102
|
-
Automatic collection of OAuth Clients
|
|
103
|
-
|
|
104
|
-
This method collects the environment variables relative to a single
|
|
105
|
-
OAuth client and saves them within the `Settings` object in the form
|
|
106
|
-
of an `OAuthClientConfig` instance.
|
|
107
|
-
|
|
108
|
-
Fractal can support an arbitrary number of OAuth providers, which are
|
|
109
|
-
automatically detected by parsing the environment variable names. In
|
|
110
|
-
particular, to set the provider `FOO`, one must specify the variables
|
|
111
|
-
|
|
112
|
-
OAUTH_FOO_CLIENT_ID
|
|
113
|
-
OAUTH_FOO_CLIENT_SECRET
|
|
114
|
-
...
|
|
115
|
-
|
|
116
|
-
etc (cf. OAuthClientConfig).
|
|
117
|
-
"""
|
|
118
|
-
oauth_env_variable_keys = [
|
|
119
|
-
key for key in environ.keys() if key.startswith("OAUTH_")
|
|
120
|
-
]
|
|
121
|
-
clients_available = {
|
|
122
|
-
var.split("_")[1] for var in oauth_env_variable_keys
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
values["OAUTH_CLIENTS_CONFIG"] = []
|
|
126
|
-
for client in clients_available:
|
|
127
|
-
prefix = f"OAUTH_{client}"
|
|
128
|
-
oauth_client_config = OAuthClientConfig(
|
|
129
|
-
CLIENT_NAME=client,
|
|
130
|
-
CLIENT_ID=getenv(f"{prefix}_CLIENT_ID", None),
|
|
131
|
-
CLIENT_SECRET=getenv(f"{prefix}_CLIENT_SECRET", None),
|
|
132
|
-
OIDC_CONFIGURATION_ENDPOINT=getenv(
|
|
133
|
-
f"{prefix}_OIDC_CONFIGURATION_ENDPOINT", None
|
|
134
|
-
),
|
|
135
|
-
REDIRECT_URL=getenv(f"{prefix}_REDIRECT_URL", None),
|
|
136
|
-
)
|
|
137
|
-
values["OAUTH_CLIENTS_CONFIG"].append(oauth_client_config)
|
|
138
|
-
return values
|
|
139
|
-
|
|
140
|
-
###########################################################################
|
|
141
|
-
# FRACTAL SPECIFIC
|
|
142
|
-
###########################################################################
|
|
143
|
-
|
|
144
49
|
# Note: we do not use ResourceType here to avoid circular imports
|
|
145
50
|
FRACTAL_RUNNER_BACKEND: Literal[
|
|
146
51
|
"local", "slurm_ssh", "slurm_sudo"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
from typing import Self
|
|
3
|
+
|
|
4
|
+
from pydantic import model_validator
|
|
5
|
+
from pydantic import SecretStr
|
|
6
|
+
from pydantic import StringConstraints
|
|
7
|
+
from pydantic_settings import BaseSettings
|
|
8
|
+
from pydantic_settings import SettingsConfigDict
|
|
9
|
+
|
|
10
|
+
from ._settings_config import SETTINGS_CONFIG_DICT
|
|
11
|
+
from fractal_server.types import NonEmptyStr
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class OAuthSettings(BaseSettings):
|
|
15
|
+
"""
|
|
16
|
+
Minimal set of configurations needed for operating on the database (e.g
|
|
17
|
+
for schema migrations).
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
model_config = SettingsConfigDict(**SETTINGS_CONFIG_DICT)
|
|
21
|
+
|
|
22
|
+
OAUTH_CLIENT_NAME: (
|
|
23
|
+
Annotated[
|
|
24
|
+
NonEmptyStr,
|
|
25
|
+
StringConstraints(to_lower=True),
|
|
26
|
+
]
|
|
27
|
+
| None
|
|
28
|
+
) = None
|
|
29
|
+
"""
|
|
30
|
+
The name of the client.
|
|
31
|
+
"""
|
|
32
|
+
OAUTH_CLIENT_ID: SecretStr | None = None
|
|
33
|
+
"""
|
|
34
|
+
ID of client.
|
|
35
|
+
"""
|
|
36
|
+
OAUTH_CLIENT_SECRET: SecretStr | None = None
|
|
37
|
+
"""
|
|
38
|
+
Secret to authorise against the identity provider.
|
|
39
|
+
"""
|
|
40
|
+
OAUTH_OIDC_CONFIG_ENDPOINT: str | None = None
|
|
41
|
+
"""
|
|
42
|
+
OpenID configuration endpoint, for autodiscovery of relevant endpoints.
|
|
43
|
+
"""
|
|
44
|
+
OAUTH_REDIRECT_URL: str | None = None
|
|
45
|
+
"""
|
|
46
|
+
String to be used as `redirect_url` argument in
|
|
47
|
+
`fastapi_users.get_oauth_router`, and then in
|
|
48
|
+
`httpx_oauth.integrations.fastapi.OAuth2AuthorizeCallback`
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
@model_validator(mode="after")
|
|
52
|
+
def check_configuration(self: Self) -> Self:
|
|
53
|
+
if (
|
|
54
|
+
self.OAUTH_CLIENT_NAME not in ["google", "github", None]
|
|
55
|
+
and self.OAUTH_OIDC_CONFIG_ENDPOINT is None
|
|
56
|
+
):
|
|
57
|
+
raise ValueError(
|
|
58
|
+
f"{self.OAUTH_OIDC_CONFIG_ENDPOINT=} but "
|
|
59
|
+
f"{self.OAUTH_CLIENT_NAME=}"
|
|
60
|
+
)
|
|
61
|
+
return self
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def is_set(self) -> bool:
|
|
65
|
+
return None not in (
|
|
66
|
+
self.OAUTH_CLIENT_NAME,
|
|
67
|
+
self.OAUTH_CLIENT_ID,
|
|
68
|
+
self.OAUTH_CLIENT_SECRET,
|
|
69
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "fractal-server"
|
|
3
|
-
version = "2.17.
|
|
3
|
+
version = "2.17.0a2"
|
|
4
4
|
description = "Backend component of the Fractal analytics platform"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name="Tommaso Comparin", email="tommaso.comparin@exact-lab.it" },
|
|
@@ -96,7 +96,7 @@ filterwarnings = [
|
|
|
96
96
|
markers = ["container", "ssh", "fails_on_macos"]
|
|
97
97
|
|
|
98
98
|
[tool.bumpver]
|
|
99
|
-
current_version = "2.17.
|
|
99
|
+
current_version = "2.17.0a2"
|
|
100
100
|
version_pattern = "MAJOR.MINOR.PATCH[PYTAGNUM]"
|
|
101
101
|
commit_message = "bump version {old_version} -> {new_version}"
|
|
102
102
|
commit = true
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__VERSION__ = "2.17.0a0"
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
from fastapi import APIRouter
|
|
2
|
-
|
|
3
|
-
from . import cookie_backend
|
|
4
|
-
from . import fastapi_users
|
|
5
|
-
from ....config import get_settings
|
|
6
|
-
from ....syringe import Inject
|
|
7
|
-
|
|
8
|
-
router_oauth = APIRouter()
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# OAUTH CLIENTS
|
|
12
|
-
|
|
13
|
-
# NOTE: settings.OAUTH_CLIENTS are collected by
|
|
14
|
-
# Settings.collect_oauth_clients(). If no specific client is specified in the
|
|
15
|
-
# environment variables (e.g. by setting OAUTH_FOO_CLIENT_ID and
|
|
16
|
-
# OAUTH_FOO_CLIENT_SECRET), this list is empty
|
|
17
|
-
|
|
18
|
-
# Note: dependency injection should be wrapped within a function call to make
|
|
19
|
-
# it truly lazy. This function could then be called on startup of the FastAPI
|
|
20
|
-
# app (cf. fractal_server.main)
|
|
21
|
-
settings = Inject(get_settings)
|
|
22
|
-
|
|
23
|
-
for client_config in settings.OAUTH_CLIENTS_CONFIG:
|
|
24
|
-
client_name = client_config.CLIENT_NAME.lower()
|
|
25
|
-
|
|
26
|
-
if client_name == "google":
|
|
27
|
-
from httpx_oauth.clients.google import GoogleOAuth2
|
|
28
|
-
|
|
29
|
-
client = GoogleOAuth2(
|
|
30
|
-
client_config.CLIENT_ID,
|
|
31
|
-
client_config.CLIENT_SECRET.get_secret_value(),
|
|
32
|
-
)
|
|
33
|
-
elif client_name == "github":
|
|
34
|
-
from httpx_oauth.clients.github import GitHubOAuth2
|
|
35
|
-
|
|
36
|
-
client = GitHubOAuth2(
|
|
37
|
-
client_config.CLIENT_ID,
|
|
38
|
-
client_config.CLIENT_SECRET.get_secret_value(),
|
|
39
|
-
)
|
|
40
|
-
else:
|
|
41
|
-
from httpx_oauth.clients.openid import OpenID
|
|
42
|
-
|
|
43
|
-
client = OpenID(
|
|
44
|
-
client_config.CLIENT_ID,
|
|
45
|
-
client_config.CLIENT_SECRET.get_secret_value(),
|
|
46
|
-
client_config.OIDC_CONFIGURATION_ENDPOINT,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
router_oauth.include_router(
|
|
50
|
-
fastapi_users.get_oauth_router(
|
|
51
|
-
client,
|
|
52
|
-
cookie_backend,
|
|
53
|
-
settings.JWT_SECRET_KEY,
|
|
54
|
-
is_verified_by_default=False,
|
|
55
|
-
associate_by_email=True,
|
|
56
|
-
redirect_url=client_config.REDIRECT_URL,
|
|
57
|
-
),
|
|
58
|
-
prefix=f"/{client_name}",
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# Add trailing slash to all routes' paths
|
|
63
|
-
for route in router_oauth.routes:
|
|
64
|
-
if not route.path.endswith("/"):
|
|
65
|
-
route.path = f"{route.path}/"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/linkusergroup.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/linkuserproject.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/user_settings.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/__init__.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/accounting.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/resource.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/task_group.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/workflow.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/models/v2/workflowtask.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/__init__.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/accounting.py
RENAMED
|
File without changes
|
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/job.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/profile.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/project.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/resource.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/task.py
RENAMED
|
File without changes
|
{fractal_server-2.17.0a0 → fractal_server-2.17.0a2}/fractal_server/app/routes/admin/v2/task_group.py
RENAMED
|
File without changes
|
|
File without changes
|