fractal-server 2.17.1a1__py3-none-any.whl → 2.18.0__py3-none-any.whl
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/__init__.py +1 -1
- fractal_server/__main__.py +21 -19
- fractal_server/app/db/__init__.py +3 -3
- fractal_server/app/models/__init__.py +1 -0
- fractal_server/app/models/linkuserproject.py +43 -1
- fractal_server/app/models/security.py +28 -8
- fractal_server/app/models/v2/__init__.py +3 -1
- fractal_server/app/models/v2/accounting.py +9 -1
- fractal_server/app/models/v2/dataset.py +5 -1
- fractal_server/app/models/v2/history.py +15 -1
- fractal_server/app/models/v2/job.py +17 -2
- fractal_server/app/models/v2/profile.py +29 -0
- fractal_server/app/models/v2/project.py +4 -10
- fractal_server/app/models/v2/resource.py +17 -0
- fractal_server/app/models/v2/task_group.py +4 -3
- fractal_server/app/models/v2/workflow.py +2 -1
- fractal_server/app/routes/admin/v2/__init__.py +12 -13
- fractal_server/app/routes/admin/v2/accounting.py +3 -3
- fractal_server/app/routes/admin/v2/job.py +35 -24
- fractal_server/app/routes/admin/v2/profile.py +3 -2
- fractal_server/app/routes/admin/v2/resource.py +5 -5
- fractal_server/app/routes/admin/v2/sharing.py +103 -0
- fractal_server/app/routes/admin/v2/task.py +37 -26
- fractal_server/app/routes/admin/v2/task_group.py +94 -17
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +21 -22
- fractal_server/app/routes/api/__init__.py +1 -9
- fractal_server/app/routes/api/v2/__init__.py +49 -50
- fractal_server/app/routes/api/v2/_aux_functions.py +132 -124
- fractal_server/app/routes/api/v2/_aux_functions_history.py +51 -23
- fractal_server/app/routes/api/v2/_aux_functions_sharing.py +97 -0
- fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +6 -8
- fractal_server/app/routes/api/v2/_aux_functions_tasks.py +7 -9
- fractal_server/app/routes/api/v2/_aux_task_group_disambiguation.py +1 -2
- fractal_server/app/routes/api/v2/dataset.py +95 -102
- fractal_server/app/routes/api/v2/history.py +59 -33
- fractal_server/app/routes/api/v2/images.py +24 -9
- fractal_server/app/routes/api/v2/job.py +52 -33
- fractal_server/app/routes/api/v2/pre_submission_checks.py +16 -8
- fractal_server/app/routes/api/v2/project.py +65 -37
- fractal_server/app/routes/api/v2/sharing.py +311 -0
- fractal_server/app/routes/api/v2/status_legacy.py +31 -41
- fractal_server/app/routes/api/v2/submit.py +82 -78
- fractal_server/app/routes/api/v2/task.py +19 -20
- fractal_server/app/routes/api/v2/task_collection.py +41 -43
- fractal_server/app/routes/api/v2/task_collection_custom.py +19 -20
- fractal_server/app/routes/api/v2/task_collection_pixi.py +10 -11
- fractal_server/app/routes/api/v2/task_group.py +25 -24
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +32 -32
- fractal_server/app/routes/api/v2/task_version_update.py +23 -19
- fractal_server/app/routes/api/v2/workflow.py +50 -55
- fractal_server/app/routes/api/v2/workflow_import.py +37 -37
- fractal_server/app/routes/api/v2/workflowtask.py +32 -26
- fractal_server/app/routes/auth/__init__.py +1 -3
- fractal_server/app/routes/auth/_aux_auth.py +101 -2
- fractal_server/app/routes/auth/current_user.py +2 -66
- fractal_server/app/routes/auth/group.py +8 -35
- fractal_server/app/routes/auth/login.py +1 -0
- fractal_server/app/routes/auth/oauth.py +4 -3
- fractal_server/app/routes/auth/register.py +4 -2
- fractal_server/app/routes/auth/router.py +2 -0
- fractal_server/app/routes/auth/users.py +19 -10
- fractal_server/app/routes/auth/viewer_paths.py +43 -0
- fractal_server/app/routes/aux/_job.py +1 -1
- fractal_server/app/routes/aux/_runner.py +2 -2
- fractal_server/app/routes/pagination.py +1 -1
- fractal_server/app/schemas/user.py +29 -12
- fractal_server/app/schemas/user_group.py +0 -15
- fractal_server/app/schemas/v2/__init__.py +55 -48
- fractal_server/app/schemas/v2/accounting.py +11 -0
- fractal_server/app/schemas/v2/dataset.py +57 -11
- fractal_server/app/schemas/v2/dumps.py +10 -9
- fractal_server/app/schemas/v2/job.py +11 -11
- fractal_server/app/schemas/v2/manifest.py +4 -3
- fractal_server/app/schemas/v2/profile.py +53 -2
- fractal_server/app/schemas/v2/project.py +3 -3
- fractal_server/app/schemas/v2/resource.py +121 -16
- fractal_server/app/schemas/v2/sharing.py +99 -0
- fractal_server/app/schemas/v2/status_legacy.py +3 -3
- fractal_server/app/schemas/v2/task.py +6 -7
- fractal_server/app/schemas/v2/task_collection.py +5 -5
- fractal_server/app/schemas/v2/task_group.py +16 -16
- fractal_server/app/schemas/v2/workflow.py +16 -16
- fractal_server/app/schemas/v2/workflowtask.py +16 -15
- fractal_server/app/security/__init__.py +5 -8
- fractal_server/app/security/signup_email.py +4 -5
- fractal_server/app/shutdown.py +6 -6
- fractal_server/config/__init__.py +0 -6
- fractal_server/config/_data.py +0 -68
- fractal_server/config/_database.py +19 -20
- fractal_server/config/_email.py +30 -38
- fractal_server/config/_main.py +38 -52
- fractal_server/config/_oauth.py +17 -21
- fractal_server/data_migrations/2_18_0.py +30 -0
- fractal_server/exceptions.py +4 -0
- fractal_server/images/models.py +4 -5
- fractal_server/images/status_tools.py +4 -2
- fractal_server/logger.py +1 -1
- fractal_server/main.py +75 -13
- fractal_server/migrations/versions/034a469ec2eb_task_groups.py +4 -8
- fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +1 -1
- fractal_server/migrations/versions/0f5f85bb2ae7_add_pre_pinned_packages.py +1 -0
- fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +1 -1
- fractal_server/migrations/versions/1a83a5260664_rename.py +1 -1
- fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +1 -0
- fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +1 -1
- fractal_server/migrations/versions/40d6d6511b20_add_index_to_history_models.py +47 -0
- fractal_server/migrations/versions/45fbb391d7af_make_resource_id_fk_non_nullable.py +1 -1
- fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +1 -0
- fractal_server/migrations/versions/49d0856e9569_drop_table.py +2 -3
- fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +1 -1
- fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +1 -1
- fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +2 -1
- fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +7 -19
- fractal_server/migrations/versions/5bf02391cfef_v2.py +4 -10
- fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +1 -0
- fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +1 -1
- fractal_server/migrations/versions/7673fe18c05d_remove_project_dir_server_default.py +1 -1
- fractal_server/migrations/versions/7910eed4cf97_user_project_dirs_and_usergroup_viewer_.py +60 -0
- fractal_server/migrations/versions/791ce783d3d8_add_indices.py +1 -1
- fractal_server/migrations/versions/83bc2ad3ffcc_2_17_0.py +1 -0
- fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +1 -0
- fractal_server/migrations/versions/88270f589c9b_add_prevent_new_submissions.py +39 -0
- fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +2 -4
- fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +1 -1
- fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +1 -0
- fractal_server/migrations/versions/969d84257cac_add_historyrun_task_id.py +1 -1
- fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +1 -1
- fractal_server/migrations/versions/981d588fe248_add_executor_error_log.py +1 -1
- fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +2 -4
- fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +1 -1
- fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +1 -1
- fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +1 -1
- fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +1 -1
- fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +1 -0
- fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +1 -0
- fractal_server/migrations/versions/b1e7f7a1ff71_task_group_for_pixi.py +1 -1
- fractal_server/migrations/versions/b3ffb095f973_json_to_jsonb.py +1 -0
- fractal_server/migrations/versions/bc0e8b3327a7_project_sharing.py +72 -0
- fractal_server/migrations/versions/c90a7c76e996_job_id_in_history_run.py +1 -1
- fractal_server/migrations/versions/caba9fb1ea5e_drop_useroauth_user_settings_id.py +1 -1
- fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +4 -9
- fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +1 -0
- fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +1 -1
- fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +1 -0
- fractal_server/migrations/versions/e0e717ae2f26_delete_linkuserproject_ondelete_project.py +50 -0
- fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +1 -0
- fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +1 -1
- fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +1 -0
- fractal_server/migrations/versions/f0702066b007_one_submitted_job_per_dataset.py +40 -0
- fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +1 -1
- fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +1 -0
- fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +4 -9
- fractal_server/runner/config/_local.py +8 -5
- fractal_server/runner/config/_slurm.py +39 -33
- fractal_server/runner/config/slurm_mem_to_MB.py +0 -1
- fractal_server/runner/executors/base_runner.py +29 -4
- fractal_server/runner/executors/local/get_local_config.py +1 -0
- fractal_server/runner/executors/local/runner.py +14 -13
- fractal_server/runner/executors/slurm_common/_batching.py +9 -20
- fractal_server/runner/executors/slurm_common/base_slurm_runner.py +53 -27
- fractal_server/runner/executors/slurm_common/get_slurm_config.py +14 -7
- fractal_server/runner/executors/slurm_common/remote.py +3 -1
- fractal_server/runner/executors/slurm_common/slurm_config.py +2 -0
- fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +1 -3
- fractal_server/runner/executors/slurm_ssh/runner.py +16 -11
- fractal_server/runner/executors/slurm_ssh/tar_commands.py +1 -0
- fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -0
- fractal_server/runner/executors/slurm_sudo/runner.py +16 -11
- fractal_server/runner/task_files.py +9 -3
- fractal_server/runner/v2/_local.py +12 -6
- fractal_server/runner/v2/_slurm_ssh.py +14 -7
- fractal_server/runner/v2/_slurm_sudo.py +14 -7
- fractal_server/runner/v2/db_tools.py +0 -1
- fractal_server/runner/v2/deduplicate_list.py +2 -1
- fractal_server/runner/v2/runner.py +44 -28
- fractal_server/runner/v2/runner_functions.py +22 -28
- fractal_server/runner/v2/submit_workflow.py +29 -15
- fractal_server/ssh/_fabric.py +6 -13
- fractal_server/string_tools.py +0 -1
- fractal_server/syringe.py +1 -1
- fractal_server/tasks/config/_pixi.py +1 -1
- fractal_server/tasks/config/_python.py +16 -9
- fractal_server/tasks/utils.py +0 -1
- fractal_server/tasks/v2/local/_utils.py +3 -3
- fractal_server/tasks/v2/local/collect.py +15 -18
- fractal_server/tasks/v2/local/collect_pixi.py +14 -16
- fractal_server/tasks/v2/local/deactivate.py +14 -15
- fractal_server/tasks/v2/local/deactivate_pixi.py +7 -7
- fractal_server/tasks/v2/local/delete.py +6 -8
- fractal_server/tasks/v2/local/reactivate.py +12 -12
- fractal_server/tasks/v2/local/reactivate_pixi.py +12 -12
- fractal_server/tasks/v2/ssh/_utils.py +3 -3
- fractal_server/tasks/v2/ssh/collect.py +19 -24
- fractal_server/tasks/v2/ssh/collect_pixi.py +22 -24
- fractal_server/tasks/v2/ssh/deactivate.py +17 -15
- fractal_server/tasks/v2/ssh/deactivate_pixi.py +8 -7
- fractal_server/tasks/v2/ssh/delete.py +12 -10
- fractal_server/tasks/v2/ssh/reactivate.py +16 -16
- fractal_server/tasks/v2/ssh/reactivate_pixi.py +13 -14
- fractal_server/tasks/v2/templates/1_create_venv.sh +2 -0
- fractal_server/tasks/v2/templates/2_pip_install.sh +2 -0
- fractal_server/tasks/v2/templates/3_pip_freeze.sh +2 -0
- fractal_server/tasks/v2/templates/4_pip_show.sh +2 -0
- fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +3 -1
- fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +2 -0
- fractal_server/tasks/v2/templates/pixi_1_extract.sh +2 -0
- fractal_server/tasks/v2/templates/pixi_2_install.sh +2 -0
- fractal_server/tasks/v2/templates/pixi_3_post_install.sh +2 -0
- fractal_server/tasks/v2/utils_background.py +10 -10
- fractal_server/tasks/v2/utils_database.py +5 -5
- fractal_server/tasks/v2/utils_package_names.py +1 -2
- fractal_server/tasks/v2/utils_pixi.py +1 -3
- fractal_server/types/__init__.py +98 -1
- fractal_server/types/validators/__init__.py +3 -0
- fractal_server/types/validators/_common_validators.py +33 -3
- fractal_server/types/validators/_workflow_task_arguments_validators.py +1 -2
- fractal_server/utils.py +1 -0
- fractal_server/zip_tools.py +34 -0
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/METADATA +3 -2
- fractal_server-2.18.0.dist-info/RECORD +275 -0
- fractal_server/app/routes/admin/v2/project.py +0 -41
- fractal_server-2.17.1a1.dist-info/RECORD +0 -264
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/WHEEL +0 -0
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/entry_points.txt +0 -0
- {fractal_server-2.17.1a1.dist-info → fractal_server-2.18.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -8,45 +8,49 @@ from fastapi import status
|
|
|
8
8
|
from pydantic import BaseModel
|
|
9
9
|
from sqlmodel import select
|
|
10
10
|
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
from ....models.v2 import JobV2
|
|
14
|
-
from ....models.v2 import ProjectV2
|
|
15
|
-
from ....models.v2 import WorkflowV2
|
|
16
|
-
from ....schemas.v2 import WorkflowCreateV2
|
|
17
|
-
from ....schemas.v2 import WorkflowExportV2
|
|
18
|
-
from ....schemas.v2 import WorkflowReadV2
|
|
19
|
-
from ....schemas.v2 import WorkflowReadV2WithWarnings
|
|
20
|
-
from ....schemas.v2 import WorkflowUpdateV2
|
|
21
|
-
from ._aux_functions import _check_workflow_exists
|
|
22
|
-
from ._aux_functions import _get_project_check_owner
|
|
23
|
-
from ._aux_functions import _get_submitted_jobs_statement
|
|
24
|
-
from ._aux_functions import _get_workflow_check_owner
|
|
25
|
-
from ._aux_functions import _workflow_has_submitted_job
|
|
26
|
-
from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
|
|
11
|
+
from fractal_server.app.db import AsyncSession
|
|
12
|
+
from fractal_server.app.db import get_async_db
|
|
27
13
|
from fractal_server.app.models import UserOAuth
|
|
14
|
+
from fractal_server.app.models.v2 import JobV2
|
|
28
15
|
from fractal_server.app.models.v2 import TaskGroupV2
|
|
16
|
+
from fractal_server.app.models.v2 import WorkflowV2
|
|
29
17
|
from fractal_server.app.routes.auth import current_user_act_ver_prof
|
|
18
|
+
from fractal_server.app.schemas.v2 import WorkflowCreate
|
|
19
|
+
from fractal_server.app.schemas.v2 import WorkflowExport
|
|
20
|
+
from fractal_server.app.schemas.v2 import WorkflowRead
|
|
21
|
+
from fractal_server.app.schemas.v2 import WorkflowReadWithWarnings
|
|
22
|
+
from fractal_server.app.schemas.v2 import WorkflowUpdate
|
|
23
|
+
from fractal_server.app.schemas.v2.sharing import ProjectPermissions
|
|
30
24
|
from fractal_server.images.tools import merge_type_filters
|
|
31
25
|
|
|
26
|
+
from ._aux_functions import _check_workflow_exists
|
|
27
|
+
from ._aux_functions import _get_project_check_access
|
|
28
|
+
from ._aux_functions import _get_submitted_jobs_statement
|
|
29
|
+
from ._aux_functions import _get_workflow_check_access
|
|
30
|
+
from ._aux_functions import _workflow_has_submitted_job
|
|
31
|
+
from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
|
|
32
|
+
|
|
32
33
|
router = APIRouter()
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
@router.get(
|
|
36
37
|
"/project/{project_id}/workflow/",
|
|
37
|
-
response_model=list[
|
|
38
|
+
response_model=list[WorkflowRead],
|
|
38
39
|
)
|
|
39
40
|
async def get_workflow_list(
|
|
40
41
|
project_id: int,
|
|
41
42
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
42
43
|
db: AsyncSession = Depends(get_async_db),
|
|
43
|
-
) -> list[
|
|
44
|
+
) -> list[WorkflowRead] | None:
|
|
44
45
|
"""
|
|
45
46
|
Get workflow list for given project
|
|
46
47
|
"""
|
|
47
48
|
# Access control
|
|
48
|
-
project = await
|
|
49
|
-
project_id=project_id,
|
|
49
|
+
project = await _get_project_check_access(
|
|
50
|
+
project_id=project_id,
|
|
51
|
+
user_id=user.id,
|
|
52
|
+
required_permissions=ProjectPermissions.READ,
|
|
53
|
+
db=db,
|
|
50
54
|
)
|
|
51
55
|
# Find workflows of the current project. Note: this select/where approach
|
|
52
56
|
# has much better scaling than refreshing all elements of
|
|
@@ -59,20 +63,23 @@ async def get_workflow_list(
|
|
|
59
63
|
|
|
60
64
|
@router.post(
|
|
61
65
|
"/project/{project_id}/workflow/",
|
|
62
|
-
response_model=
|
|
66
|
+
response_model=WorkflowRead,
|
|
63
67
|
status_code=status.HTTP_201_CREATED,
|
|
64
68
|
)
|
|
65
69
|
async def create_workflow(
|
|
66
70
|
project_id: int,
|
|
67
|
-
workflow:
|
|
71
|
+
workflow: WorkflowCreate,
|
|
68
72
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
69
73
|
db: AsyncSession = Depends(get_async_db),
|
|
70
|
-
) ->
|
|
74
|
+
) -> WorkflowRead | None:
|
|
71
75
|
"""
|
|
72
76
|
Create a workflow, associate to a project
|
|
73
77
|
"""
|
|
74
|
-
await
|
|
75
|
-
project_id=project_id,
|
|
78
|
+
await _get_project_check_access(
|
|
79
|
+
project_id=project_id,
|
|
80
|
+
user_id=user.id,
|
|
81
|
+
required_permissions=ProjectPermissions.WRITE,
|
|
82
|
+
db=db,
|
|
76
83
|
)
|
|
77
84
|
await _check_workflow_exists(
|
|
78
85
|
name=workflow.name, project_id=project_id, db=db
|
|
@@ -88,22 +95,23 @@ async def create_workflow(
|
|
|
88
95
|
|
|
89
96
|
@router.get(
|
|
90
97
|
"/project/{project_id}/workflow/{workflow_id}/",
|
|
91
|
-
response_model=
|
|
98
|
+
response_model=WorkflowReadWithWarnings,
|
|
92
99
|
)
|
|
93
100
|
async def read_workflow(
|
|
94
101
|
project_id: int,
|
|
95
102
|
workflow_id: int,
|
|
96
103
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
97
104
|
db: AsyncSession = Depends(get_async_db),
|
|
98
|
-
) ->
|
|
105
|
+
) -> WorkflowReadWithWarnings | None:
|
|
99
106
|
"""
|
|
100
107
|
Get info on an existing workflow
|
|
101
108
|
"""
|
|
102
109
|
|
|
103
|
-
workflow = await
|
|
110
|
+
workflow = await _get_workflow_check_access(
|
|
104
111
|
project_id=project_id,
|
|
105
112
|
workflow_id=workflow_id,
|
|
106
113
|
user_id=user.id,
|
|
114
|
+
required_permissions=ProjectPermissions.READ,
|
|
107
115
|
db=db,
|
|
108
116
|
)
|
|
109
117
|
|
|
@@ -121,22 +129,23 @@ async def read_workflow(
|
|
|
121
129
|
|
|
122
130
|
@router.patch(
|
|
123
131
|
"/project/{project_id}/workflow/{workflow_id}/",
|
|
124
|
-
response_model=
|
|
132
|
+
response_model=WorkflowReadWithWarnings,
|
|
125
133
|
)
|
|
126
134
|
async def update_workflow(
|
|
127
135
|
project_id: int,
|
|
128
136
|
workflow_id: int,
|
|
129
|
-
patch:
|
|
137
|
+
patch: WorkflowUpdate,
|
|
130
138
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
131
139
|
db: AsyncSession = Depends(get_async_db),
|
|
132
|
-
) ->
|
|
140
|
+
) -> WorkflowReadWithWarnings | None:
|
|
133
141
|
"""
|
|
134
142
|
Edit a workflow
|
|
135
143
|
"""
|
|
136
|
-
workflow = await
|
|
144
|
+
workflow = await _get_workflow_check_access(
|
|
137
145
|
project_id=project_id,
|
|
138
146
|
workflow_id=workflow_id,
|
|
139
147
|
user_id=user.id,
|
|
148
|
+
required_permissions=ProjectPermissions.WRITE,
|
|
140
149
|
db=db,
|
|
141
150
|
)
|
|
142
151
|
|
|
@@ -208,10 +217,11 @@ async def delete_workflow(
|
|
|
208
217
|
Delete a workflow
|
|
209
218
|
"""
|
|
210
219
|
|
|
211
|
-
workflow = await
|
|
220
|
+
workflow = await _get_workflow_check_access(
|
|
212
221
|
project_id=project_id,
|
|
213
222
|
workflow_id=workflow_id,
|
|
214
223
|
user_id=user.id,
|
|
224
|
+
required_permissions=ProjectPermissions.WRITE,
|
|
215
225
|
db=db,
|
|
216
226
|
)
|
|
217
227
|
|
|
@@ -241,21 +251,22 @@ async def delete_workflow(
|
|
|
241
251
|
|
|
242
252
|
@router.get(
|
|
243
253
|
"/project/{project_id}/workflow/{workflow_id}/export/",
|
|
244
|
-
response_model=
|
|
254
|
+
response_model=WorkflowExport,
|
|
245
255
|
)
|
|
246
256
|
async def export_workflow(
|
|
247
257
|
project_id: int,
|
|
248
258
|
workflow_id: int,
|
|
249
259
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
250
260
|
db: AsyncSession = Depends(get_async_db),
|
|
251
|
-
) ->
|
|
261
|
+
) -> WorkflowExport | None:
|
|
252
262
|
"""
|
|
253
263
|
Export an existing workflow, after stripping all IDs
|
|
254
264
|
"""
|
|
255
|
-
workflow = await
|
|
265
|
+
workflow = await _get_workflow_check_access(
|
|
256
266
|
project_id=project_id,
|
|
257
267
|
workflow_id=workflow_id,
|
|
258
268
|
user_id=user.id,
|
|
269
|
+
required_permissions=ProjectPermissions.READ,
|
|
259
270
|
db=db,
|
|
260
271
|
)
|
|
261
272
|
wf_task_list = []
|
|
@@ -268,30 +279,13 @@ async def export_workflow(
|
|
|
268
279
|
name=wftask.task.name,
|
|
269
280
|
)
|
|
270
281
|
|
|
271
|
-
wf =
|
|
282
|
+
wf = WorkflowExport(
|
|
272
283
|
**workflow.model_dump(),
|
|
273
284
|
task_list=wf_task_list,
|
|
274
285
|
)
|
|
275
286
|
return wf
|
|
276
287
|
|
|
277
288
|
|
|
278
|
-
@router.get("/workflow/", response_model=list[WorkflowReadV2])
|
|
279
|
-
async def get_user_workflows(
|
|
280
|
-
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
281
|
-
db: AsyncSession = Depends(get_async_db),
|
|
282
|
-
) -> list[WorkflowReadV2]:
|
|
283
|
-
"""
|
|
284
|
-
Returns all the workflows of the current user
|
|
285
|
-
"""
|
|
286
|
-
stm = select(WorkflowV2)
|
|
287
|
-
stm = stm.join(ProjectV2).where(
|
|
288
|
-
ProjectV2.user_list.any(UserOAuth.id == user.id)
|
|
289
|
-
)
|
|
290
|
-
res = await db.execute(stm)
|
|
291
|
-
workflow_list = res.scalars().all()
|
|
292
|
-
return workflow_list
|
|
293
|
-
|
|
294
|
-
|
|
295
289
|
class WorkflowTaskTypeFiltersInfo(BaseModel):
|
|
296
290
|
workflowtask_id: int
|
|
297
291
|
current_type_filters: dict[str, bool]
|
|
@@ -310,10 +304,11 @@ async def get_workflow_type_filters(
|
|
|
310
304
|
Get info on type/type-filters flow for a workflow.
|
|
311
305
|
"""
|
|
312
306
|
|
|
313
|
-
workflow = await
|
|
307
|
+
workflow = await _get_workflow_check_access(
|
|
314
308
|
project_id=project_id,
|
|
315
309
|
workflow_id=workflow_id,
|
|
316
310
|
user_id=user.id,
|
|
311
|
+
required_permissions=ProjectPermissions.READ,
|
|
317
312
|
db=db,
|
|
318
313
|
)
|
|
319
314
|
|
|
@@ -5,23 +5,13 @@ from fastapi import status
|
|
|
5
5
|
from sqlmodel import or_
|
|
6
6
|
from sqlmodel import select
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from ....models.v2 import TaskV2
|
|
11
|
-
from ....models.v2 import WorkflowV2
|
|
12
|
-
from ....schemas.v2 import TaskImportV2Legacy
|
|
13
|
-
from ....schemas.v2 import WorkflowImportV2
|
|
14
|
-
from ....schemas.v2 import WorkflowReadV2WithWarnings
|
|
15
|
-
from ....schemas.v2 import WorkflowTaskCreateV2
|
|
16
|
-
from ._aux_functions import _check_workflow_exists
|
|
17
|
-
from ._aux_functions import _get_project_check_owner
|
|
18
|
-
from ._aux_functions import _get_user_resource_id
|
|
19
|
-
from ._aux_functions import _workflow_insert_task
|
|
20
|
-
from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
|
|
21
|
-
from ._aux_functions_tasks import _check_type_filters_compatibility
|
|
8
|
+
from fractal_server.app.db import AsyncSession
|
|
9
|
+
from fractal_server.app.db import get_async_db
|
|
22
10
|
from fractal_server.app.models import LinkUserGroup
|
|
23
11
|
from fractal_server.app.models import UserOAuth
|
|
24
12
|
from fractal_server.app.models.v2 import TaskGroupV2
|
|
13
|
+
from fractal_server.app.models.v2 import TaskV2
|
|
14
|
+
from fractal_server.app.models.v2 import WorkflowV2
|
|
25
15
|
from fractal_server.app.routes.api.v2._aux_task_group_disambiguation import (
|
|
26
16
|
_disambiguate_task_groups,
|
|
27
17
|
)
|
|
@@ -29,9 +19,21 @@ from fractal_server.app.routes.auth import current_user_act_ver_prof
|
|
|
29
19
|
from fractal_server.app.routes.auth._aux_auth import (
|
|
30
20
|
_get_default_usergroup_id_or_none,
|
|
31
21
|
)
|
|
32
|
-
from fractal_server.app.schemas.v2 import
|
|
22
|
+
from fractal_server.app.schemas.v2 import TaskImport
|
|
23
|
+
from fractal_server.app.schemas.v2 import TaskImportLegacy
|
|
24
|
+
from fractal_server.app.schemas.v2 import WorkflowImport
|
|
25
|
+
from fractal_server.app.schemas.v2 import WorkflowReadWithWarnings
|
|
26
|
+
from fractal_server.app.schemas.v2 import WorkflowTaskCreate
|
|
27
|
+
from fractal_server.app.schemas.v2.sharing import ProjectPermissions
|
|
33
28
|
from fractal_server.logger import set_logger
|
|
34
29
|
|
|
30
|
+
from ._aux_functions import _check_workflow_exists
|
|
31
|
+
from ._aux_functions import _get_project_check_access
|
|
32
|
+
from ._aux_functions import _get_user_resource_id
|
|
33
|
+
from ._aux_functions import _workflow_insert_task
|
|
34
|
+
from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
|
|
35
|
+
from ._aux_functions_tasks import _check_type_filters_compatibility
|
|
36
|
+
|
|
35
37
|
router = APIRouter()
|
|
36
38
|
|
|
37
39
|
|
|
@@ -64,7 +66,7 @@ async def _get_user_accessible_taskgroups(
|
|
|
64
66
|
)
|
|
65
67
|
res = await db.execute(stm)
|
|
66
68
|
accessible_task_groups = res.scalars().all()
|
|
67
|
-
logger.
|
|
69
|
+
logger.debug(
|
|
68
70
|
f"Found {len(accessible_task_groups)} accessible "
|
|
69
71
|
f"task groups for {user_id=}."
|
|
70
72
|
)
|
|
@@ -99,7 +101,7 @@ async def _get_task_by_source(
|
|
|
99
101
|
|
|
100
102
|
async def _get_task_by_taskimport(
|
|
101
103
|
*,
|
|
102
|
-
task_import:
|
|
104
|
+
task_import: TaskImport,
|
|
103
105
|
task_groups_list: list[TaskGroupV2],
|
|
104
106
|
user_id: int,
|
|
105
107
|
default_group_id: int | None,
|
|
@@ -119,7 +121,7 @@ async def _get_task_by_taskimport(
|
|
|
119
121
|
`id` of the matching task, or `None`.
|
|
120
122
|
"""
|
|
121
123
|
|
|
122
|
-
logger.
|
|
124
|
+
logger.debug(f"[_get_task_by_taskimport] START, {task_import=}")
|
|
123
125
|
|
|
124
126
|
# Filter by `pkg_name` and by presence of a task with given `name`.
|
|
125
127
|
matching_task_groups = [
|
|
@@ -127,12 +129,11 @@ async def _get_task_by_taskimport(
|
|
|
127
129
|
for task_group in task_groups_list
|
|
128
130
|
if (
|
|
129
131
|
task_group.pkg_name == task_import.pkg_name
|
|
130
|
-
and task_import.name
|
|
131
|
-
in [task.name for task in task_group.task_list]
|
|
132
|
+
and task_import.name in [task.name for task in task_group.task_list]
|
|
132
133
|
)
|
|
133
134
|
]
|
|
134
135
|
if len(matching_task_groups) < 1:
|
|
135
|
-
logger.
|
|
136
|
+
logger.debug(
|
|
136
137
|
"[_get_task_by_taskimport] "
|
|
137
138
|
f"No task group with {task_import.pkg_name=} "
|
|
138
139
|
f"and a task with {task_import.name=}."
|
|
@@ -142,15 +143,13 @@ async def _get_task_by_taskimport(
|
|
|
142
143
|
# Determine target `version`
|
|
143
144
|
# Note that task_import.version cannot be "", due to a validator
|
|
144
145
|
if task_import.version is None:
|
|
145
|
-
logger.
|
|
146
|
+
logger.debug(
|
|
146
147
|
"[_get_task_by_taskimport] "
|
|
147
148
|
"No version requested, looking for latest."
|
|
148
149
|
)
|
|
149
|
-
latest_task = max(
|
|
150
|
-
matching_task_groups, key=lambda tg: tg.version or ""
|
|
151
|
-
)
|
|
150
|
+
latest_task = max(matching_task_groups, key=lambda tg: tg.version or "")
|
|
152
151
|
version = latest_task.version
|
|
153
|
-
logger.
|
|
152
|
+
logger.debug(
|
|
154
153
|
f"[_get_task_by_taskimport] Latest version set to {version}."
|
|
155
154
|
)
|
|
156
155
|
else:
|
|
@@ -162,19 +161,19 @@ async def _get_task_by_taskimport(
|
|
|
162
161
|
)
|
|
163
162
|
|
|
164
163
|
if len(final_matching_task_groups) < 1:
|
|
165
|
-
logger.
|
|
164
|
+
logger.debug(
|
|
166
165
|
"[_get_task_by_taskimport] "
|
|
167
166
|
"No task group left after filtering by version."
|
|
168
167
|
)
|
|
169
168
|
return None
|
|
170
169
|
elif len(final_matching_task_groups) == 1:
|
|
171
170
|
final_task_group = final_matching_task_groups[0]
|
|
172
|
-
logger.
|
|
171
|
+
logger.debug(
|
|
173
172
|
"[_get_task_by_taskimport] "
|
|
174
173
|
"Found a single task group, after filtering by version."
|
|
175
174
|
)
|
|
176
175
|
else:
|
|
177
|
-
logger.
|
|
176
|
+
logger.debug(
|
|
178
177
|
"[_get_task_by_taskimport] "
|
|
179
178
|
f"Found {len(final_matching_task_groups)} task groups, "
|
|
180
179
|
"after filtering by version."
|
|
@@ -186,7 +185,7 @@ async def _get_task_by_taskimport(
|
|
|
186
185
|
default_group_id=default_group_id,
|
|
187
186
|
)
|
|
188
187
|
if final_task_group is None:
|
|
189
|
-
logger.
|
|
188
|
+
logger.debug(
|
|
190
189
|
"[_get_task_by_taskimport] Disambiguation returned None."
|
|
191
190
|
)
|
|
192
191
|
return None
|
|
@@ -201,22 +200,22 @@ async def _get_task_by_taskimport(
|
|
|
201
200
|
None,
|
|
202
201
|
)
|
|
203
202
|
|
|
204
|
-
logger.
|
|
203
|
+
logger.debug(f"[_get_task_by_taskimport] END, {task_import=}, {task_id=}.")
|
|
205
204
|
|
|
206
205
|
return task_id
|
|
207
206
|
|
|
208
207
|
|
|
209
208
|
@router.post(
|
|
210
209
|
"/project/{project_id}/workflow/import/",
|
|
211
|
-
response_model=
|
|
210
|
+
response_model=WorkflowReadWithWarnings,
|
|
212
211
|
status_code=status.HTTP_201_CREATED,
|
|
213
212
|
)
|
|
214
213
|
async def import_workflow(
|
|
215
214
|
project_id: int,
|
|
216
|
-
workflow_import:
|
|
215
|
+
workflow_import: WorkflowImport,
|
|
217
216
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
218
217
|
db: AsyncSession = Depends(get_async_db),
|
|
219
|
-
) ->
|
|
218
|
+
) -> WorkflowReadWithWarnings:
|
|
220
219
|
"""
|
|
221
220
|
Import an existing workflow into a project and create required objects.
|
|
222
221
|
"""
|
|
@@ -224,9 +223,10 @@ async def import_workflow(
|
|
|
224
223
|
user_resource_id = await _get_user_resource_id(user_id=user.id, db=db)
|
|
225
224
|
|
|
226
225
|
# Preliminary checks
|
|
227
|
-
await
|
|
226
|
+
await _get_project_check_access(
|
|
228
227
|
project_id=project_id,
|
|
229
228
|
user_id=user.id,
|
|
229
|
+
required_permissions=ProjectPermissions.WRITE,
|
|
230
230
|
db=db,
|
|
231
231
|
)
|
|
232
232
|
await _check_workflow_exists(
|
|
@@ -246,7 +246,7 @@ async def import_workflow(
|
|
|
246
246
|
list_task_ids = []
|
|
247
247
|
for wf_task in workflow_import.task_list:
|
|
248
248
|
task_import = wf_task.task
|
|
249
|
-
if isinstance(task_import,
|
|
249
|
+
if isinstance(task_import, TaskImportLegacy):
|
|
250
250
|
task_id = await _get_task_by_source(
|
|
251
251
|
source=task_import.source,
|
|
252
252
|
task_groups_list=task_group_list,
|
|
@@ -264,7 +264,7 @@ async def import_workflow(
|
|
|
264
264
|
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
|
|
265
265
|
detail=f"Could not find a task matching with {wf_task.task}.",
|
|
266
266
|
)
|
|
267
|
-
new_wf_task =
|
|
267
|
+
new_wf_task = WorkflowTaskCreate(
|
|
268
268
|
**wf_task.model_dump(exclude_none=True, exclude={"task"})
|
|
269
269
|
)
|
|
270
270
|
list_wf_tasks.append(new_wf_task)
|
|
@@ -6,43 +6,49 @@ from fastapi import HTTPException
|
|
|
6
6
|
from fastapi import Response
|
|
7
7
|
from fastapi import status
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
9
|
+
from fractal_server.app.db import AsyncSession
|
|
10
|
+
from fractal_server.app.db import get_async_db
|
|
11
|
+
from fractal_server.app.models import UserOAuth
|
|
12
|
+
from fractal_server.app.routes.auth import current_user_act_ver_prof
|
|
13
|
+
from fractal_server.app.schemas.v2 import TaskType
|
|
14
|
+
from fractal_server.app.schemas.v2 import WorkflowTaskCreate
|
|
15
|
+
from fractal_server.app.schemas.v2 import WorkflowTaskRead
|
|
16
|
+
from fractal_server.app.schemas.v2 import WorkflowTaskUpdate
|
|
17
|
+
from fractal_server.app.schemas.v2.sharing import ProjectPermissions
|
|
18
|
+
|
|
19
|
+
from ._aux_functions import _get_workflow_check_access
|
|
20
|
+
from ._aux_functions import _get_workflow_task_check_access
|
|
13
21
|
from ._aux_functions import _workflow_has_submitted_job
|
|
14
22
|
from ._aux_functions import _workflow_insert_task
|
|
15
23
|
from ._aux_functions_tasks import _check_type_filters_compatibility
|
|
16
24
|
from ._aux_functions_tasks import _get_task_read_access
|
|
17
|
-
from fractal_server.app.models import UserOAuth
|
|
18
|
-
from fractal_server.app.routes.auth import current_user_act_ver_prof
|
|
19
|
-
from fractal_server.app.schemas.v2 import TaskType
|
|
20
|
-
from fractal_server.app.schemas.v2 import WorkflowTaskCreateV2
|
|
21
|
-
from fractal_server.app.schemas.v2 import WorkflowTaskReadV2
|
|
22
|
-
from fractal_server.app.schemas.v2 import WorkflowTaskUpdateV2
|
|
23
25
|
|
|
24
26
|
router = APIRouter()
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
@router.post(
|
|
28
30
|
"/project/{project_id}/workflow/{workflow_id}/wftask/",
|
|
29
|
-
response_model=
|
|
31
|
+
response_model=WorkflowTaskRead,
|
|
30
32
|
status_code=status.HTTP_201_CREATED,
|
|
31
33
|
)
|
|
32
34
|
async def create_workflowtask(
|
|
33
35
|
project_id: int,
|
|
34
36
|
workflow_id: int,
|
|
35
37
|
task_id: int,
|
|
36
|
-
wftask:
|
|
38
|
+
wftask: WorkflowTaskCreate,
|
|
37
39
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
38
40
|
db: AsyncSession = Depends(get_async_db),
|
|
39
|
-
) ->
|
|
41
|
+
) -> WorkflowTaskRead | None:
|
|
40
42
|
"""
|
|
41
43
|
Add a WorkflowTask to a Workflow
|
|
42
44
|
"""
|
|
43
45
|
|
|
44
|
-
workflow = await
|
|
45
|
-
project_id=project_id,
|
|
46
|
+
workflow = await _get_workflow_check_access(
|
|
47
|
+
project_id=project_id,
|
|
48
|
+
workflow_id=workflow_id,
|
|
49
|
+
user_id=user.id,
|
|
50
|
+
required_permissions=ProjectPermissions.WRITE,
|
|
51
|
+
db=db,
|
|
46
52
|
)
|
|
47
53
|
|
|
48
54
|
task = await _get_task_read_access(
|
|
@@ -63,10 +69,7 @@ async def create_workflowtask(
|
|
|
63
69
|
),
|
|
64
70
|
)
|
|
65
71
|
elif task.type == TaskType.NON_PARALLEL:
|
|
66
|
-
if
|
|
67
|
-
wftask.meta_parallel is not None
|
|
68
|
-
or wftask.args_parallel is not None
|
|
69
|
-
):
|
|
72
|
+
if wftask.meta_parallel is not None or wftask.args_parallel is not None:
|
|
70
73
|
raise HTTPException(
|
|
71
74
|
status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
|
|
72
75
|
detail=(
|
|
@@ -97,7 +100,7 @@ async def create_workflowtask(
|
|
|
97
100
|
|
|
98
101
|
@router.get(
|
|
99
102
|
"/project/{project_id}/workflow/{workflow_id}/wftask/{workflow_task_id}/",
|
|
100
|
-
response_model=
|
|
103
|
+
response_model=WorkflowTaskRead,
|
|
101
104
|
)
|
|
102
105
|
async def read_workflowtask(
|
|
103
106
|
project_id: int,
|
|
@@ -106,11 +109,12 @@ async def read_workflowtask(
|
|
|
106
109
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
107
110
|
db: AsyncSession = Depends(get_async_db),
|
|
108
111
|
):
|
|
109
|
-
workflow_task, _ = await
|
|
112
|
+
workflow_task, _ = await _get_workflow_task_check_access(
|
|
110
113
|
project_id=project_id,
|
|
111
114
|
workflow_task_id=workflow_task_id,
|
|
112
115
|
workflow_id=workflow_id,
|
|
113
116
|
user_id=user.id,
|
|
117
|
+
required_permissions=ProjectPermissions.READ,
|
|
114
118
|
db=db,
|
|
115
119
|
)
|
|
116
120
|
return workflow_task
|
|
@@ -118,25 +122,26 @@ async def read_workflowtask(
|
|
|
118
122
|
|
|
119
123
|
@router.patch(
|
|
120
124
|
"/project/{project_id}/workflow/{workflow_id}/wftask/{workflow_task_id}/",
|
|
121
|
-
response_model=
|
|
125
|
+
response_model=WorkflowTaskRead,
|
|
122
126
|
)
|
|
123
127
|
async def update_workflowtask(
|
|
124
128
|
project_id: int,
|
|
125
129
|
workflow_id: int,
|
|
126
130
|
workflow_task_id: int,
|
|
127
|
-
workflow_task_update:
|
|
131
|
+
workflow_task_update: WorkflowTaskUpdate,
|
|
128
132
|
user: UserOAuth = Depends(current_user_act_ver_prof),
|
|
129
133
|
db: AsyncSession = Depends(get_async_db),
|
|
130
|
-
) ->
|
|
134
|
+
) -> WorkflowTaskRead | None:
|
|
131
135
|
"""
|
|
132
136
|
Edit a WorkflowTask of a Workflow
|
|
133
137
|
"""
|
|
134
138
|
|
|
135
|
-
db_wf_task, db_workflow = await
|
|
139
|
+
db_wf_task, db_workflow = await _get_workflow_task_check_access(
|
|
136
140
|
project_id=project_id,
|
|
137
141
|
workflow_task_id=workflow_task_id,
|
|
138
142
|
workflow_id=workflow_id,
|
|
139
143
|
user_id=user.id,
|
|
144
|
+
required_permissions=ProjectPermissions.WRITE,
|
|
140
145
|
db=db,
|
|
141
146
|
)
|
|
142
147
|
if workflow_task_update.type_filters is not None:
|
|
@@ -217,11 +222,12 @@ async def delete_workflowtask(
|
|
|
217
222
|
Delete a WorkflowTask of a Workflow
|
|
218
223
|
"""
|
|
219
224
|
|
|
220
|
-
db_workflow_task, db_workflow = await
|
|
225
|
+
db_workflow_task, db_workflow = await _get_workflow_task_check_access(
|
|
221
226
|
project_id=project_id,
|
|
222
227
|
workflow_task_id=workflow_task_id,
|
|
223
228
|
workflow_id=workflow_id,
|
|
224
229
|
user_id=user.id,
|
|
230
|
+
required_permissions=ProjectPermissions.WRITE,
|
|
225
231
|
db=db,
|
|
226
232
|
)
|
|
227
233
|
|
|
@@ -12,7 +12,6 @@ from fractal_server.app.security import get_user_manager
|
|
|
12
12
|
from fractal_server.config import get_settings
|
|
13
13
|
from fractal_server.syringe import Inject
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
bearer_transport = BearerTransport(tokenUrl="/auth/token/login")
|
|
17
16
|
cookie_transport = CookieTransport(cookie_samesite="none")
|
|
18
17
|
|
|
@@ -71,8 +70,7 @@ async def current_user_act_ver_prof(
|
|
|
71
70
|
raise HTTPException(
|
|
72
71
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
73
72
|
detail=(
|
|
74
|
-
f"Forbidden access "
|
|
75
|
-
f"({user.is_verified=} {user.profile_id=})."
|
|
73
|
+
f"Forbidden access ({user.is_verified=} {user.profile_id=})."
|
|
76
74
|
),
|
|
77
75
|
)
|
|
78
76
|
return user
|