fractal-server 2.3.10__py3-none-any.whl → 2.4.0a0__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 +25 -2
- fractal_server/app/models/__init__.py +11 -5
- fractal_server/app/models/linkusergroup.py +11 -0
- fractal_server/app/models/security.py +24 -3
- fractal_server/app/models/v1/project.py +1 -1
- fractal_server/app/models/v2/project.py +3 -3
- fractal_server/app/routes/admin/v1.py +14 -14
- fractal_server/app/routes/admin/v2.py +12 -12
- fractal_server/app/routes/api/__init__.py +2 -2
- fractal_server/app/routes/api/v1/_aux_functions.py +2 -2
- fractal_server/app/routes/api/v1/dataset.py +17 -15
- fractal_server/app/routes/api/v1/job.py +11 -9
- fractal_server/app/routes/api/v1/project.py +9 -9
- fractal_server/app/routes/api/v1/task.py +8 -8
- fractal_server/app/routes/api/v1/task_collection.py +5 -5
- fractal_server/app/routes/api/v1/workflow.py +13 -11
- fractal_server/app/routes/api/v1/workflowtask.py +6 -6
- fractal_server/app/routes/api/v2/_aux_functions.py +2 -2
- fractal_server/app/routes/api/v2/dataset.py +11 -11
- fractal_server/app/routes/api/v2/images.py +6 -6
- fractal_server/app/routes/api/v2/job.py +9 -9
- fractal_server/app/routes/api/v2/project.py +7 -7
- fractal_server/app/routes/api/v2/status.py +3 -3
- fractal_server/app/routes/api/v2/submit.py +3 -3
- fractal_server/app/routes/api/v2/task.py +8 -8
- fractal_server/app/routes/api/v2/task_collection.py +5 -5
- fractal_server/app/routes/api/v2/task_collection_custom.py +3 -3
- fractal_server/app/routes/api/v2/task_legacy.py +9 -9
- fractal_server/app/routes/api/v2/workflow.py +11 -11
- fractal_server/app/routes/api/v2/workflowtask.py +6 -6
- fractal_server/app/routes/auth/__init__.py +55 -0
- fractal_server/app/routes/auth/_aux_auth.py +107 -0
- fractal_server/app/routes/auth/current_user.py +60 -0
- fractal_server/app/routes/auth/group.py +173 -0
- fractal_server/app/routes/auth/group_names.py +34 -0
- fractal_server/app/routes/auth/login.py +25 -0
- fractal_server/app/routes/auth/oauth.py +63 -0
- fractal_server/app/routes/auth/register.py +23 -0
- fractal_server/app/routes/auth/router.py +19 -0
- fractal_server/app/routes/auth/users.py +103 -0
- fractal_server/app/runner/v2/__init__.py +1 -5
- fractal_server/app/runner/v2/_slurm_ssh/__init__.py +17 -0
- fractal_server/app/schemas/user.py +2 -0
- fractal_server/app/schemas/user_group.py +57 -0
- fractal_server/app/security/__init__.py +72 -68
- fractal_server/data_migrations/2_4_0.py +61 -0
- fractal_server/main.py +1 -9
- fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +53 -0
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0a0.dist-info}/METADATA +1 -1
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0a0.dist-info}/RECORD +54 -41
- fractal_server/app/routes/auth.py +0 -165
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0a0.dist-info}/LICENSE +0 -0
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0a0.dist-info}/WHEEL +0 -0
- {fractal_server-2.3.10.dist-info → fractal_server-2.4.0a0.dist-info}/entry_points.txt +0 -0
fractal_server/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__VERSION__ = "2.
|
1
|
+
__VERSION__ = "2.4.0a0"
|
fractal_server/__main__.py
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
import argparse as ap
|
2
|
+
import asyncio
|
2
3
|
import sys
|
3
4
|
|
4
5
|
import uvicorn
|
5
6
|
|
7
|
+
|
6
8
|
parser = ap.ArgumentParser(description="fractal-server commands")
|
7
9
|
|
8
10
|
subparsers = parser.add_subparsers(title="Commands", dest="cmd", required=True)
|
@@ -75,12 +77,33 @@ def set_db():
|
|
75
77
|
import alembic.config
|
76
78
|
from pathlib import Path
|
77
79
|
import fractal_server
|
80
|
+
from fractal_server.app.security import _create_first_user
|
81
|
+
from fractal_server.app.security import _create_first_group
|
82
|
+
from fractal_server.syringe import Inject
|
83
|
+
from fractal_server.config import get_settings
|
78
84
|
|
79
85
|
alembic_ini = Path(fractal_server.__file__).parent / "alembic.ini"
|
80
86
|
alembic_args = ["-c", alembic_ini.as_posix(), "upgrade", "head"]
|
81
|
-
|
82
|
-
print(f"Run alembic.config, with argv={alembic_args}")
|
87
|
+
print(f"START: Run alembic.config, with argv={alembic_args}")
|
83
88
|
alembic.config.main(argv=alembic_args)
|
89
|
+
print("END: alembic.config")
|
90
|
+
# Insert default group
|
91
|
+
print("START: Default group creation")
|
92
|
+
_create_first_group()
|
93
|
+
print("END: Default group creation")
|
94
|
+
# NOTE: It will be fixed with #1739
|
95
|
+
settings = Inject(get_settings)
|
96
|
+
print("START: First user creation")
|
97
|
+
asyncio.run(
|
98
|
+
_create_first_user(
|
99
|
+
email=settings.FRACTAL_DEFAULT_ADMIN_EMAIL,
|
100
|
+
password=settings.FRACTAL_DEFAULT_ADMIN_PASSWORD,
|
101
|
+
username=settings.FRACTAL_DEFAULT_ADMIN_USERNAME,
|
102
|
+
is_superuser=True,
|
103
|
+
is_verified=True,
|
104
|
+
)
|
105
|
+
)
|
106
|
+
print("END: First user creation")
|
84
107
|
|
85
108
|
|
86
109
|
def update_db_data():
|
@@ -1,5 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
"""
|
2
|
+
Note that this module is imported from `fractal_server/migrations/env.py`,
|
3
|
+
thus we should always export all relevant database models from here or they
|
4
|
+
will not be picked up by alembic.
|
5
|
+
"""
|
6
|
+
from .linkusergroup import LinkUserGroup # noqa: F401
|
7
|
+
from .linkuserproject import LinkUserProject # noqa: F401
|
8
|
+
from .linkuserproject import LinkUserProjectV2 # noqa: F401
|
9
|
+
from .security import * # noqa
|
10
|
+
from .v1 import * # noqa
|
11
|
+
from .v2 import * # noqa
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from sqlmodel import Field
|
2
|
+
from sqlmodel import SQLModel
|
3
|
+
|
4
|
+
|
5
|
+
class LinkUserGroup(SQLModel, table=True):
|
6
|
+
"""
|
7
|
+
Crossing table between User and UserGroup
|
8
|
+
"""
|
9
|
+
|
10
|
+
group_id: int = Field(foreign_key="usergroup.id", primary_key=True)
|
11
|
+
user_id: int = Field(foreign_key="user_oauth.id", primary_key=True)
|
@@ -9,19 +9,23 @@
|
|
9
9
|
#
|
10
10
|
# Copyright 2022 (C) Friedrich Miescher Institute for Biomedical Research and
|
11
11
|
# University of Zurich
|
12
|
+
from datetime import datetime
|
12
13
|
from typing import Optional
|
13
14
|
|
14
15
|
from pydantic import EmailStr
|
15
16
|
from sqlalchemy import Column
|
17
|
+
from sqlalchemy.types import DateTime
|
16
18
|
from sqlalchemy.types import JSON
|
17
19
|
from sqlmodel import Field
|
18
20
|
from sqlmodel import Relationship
|
19
21
|
from sqlmodel import SQLModel
|
20
22
|
|
23
|
+
from fractal_server.utils import get_timestamp
|
24
|
+
|
21
25
|
|
22
26
|
class OAuthAccount(SQLModel, table=True):
|
23
27
|
"""
|
24
|
-
OAuth
|
28
|
+
ORM model for OAuth accounts (`oauthaccount` database table).
|
25
29
|
|
26
30
|
This class is based on fastapi_users_db_sqlmodel::SQLModelBaseOAuthAccount.
|
27
31
|
Original Copyright: 2021 François Voron, released under MIT licence.
|
@@ -56,7 +60,7 @@ class OAuthAccount(SQLModel, table=True):
|
|
56
60
|
|
57
61
|
class UserOAuth(SQLModel, table=True):
|
58
62
|
"""
|
59
|
-
|
63
|
+
ORM model for the `user_oauth` database table.
|
60
64
|
|
61
65
|
This class is a modification of SQLModelBaseUserDB from from
|
62
66
|
fastapi_users_db_sqlmodel. Original Copyright: 2022 François Voron,
|
@@ -74,7 +78,6 @@ class UserOAuth(SQLModel, table=True):
|
|
74
78
|
cache_dir:
|
75
79
|
username:
|
76
80
|
oauth_accounts:
|
77
|
-
project_list:
|
78
81
|
"""
|
79
82
|
|
80
83
|
__tablename__ = "user_oauth"
|
@@ -103,3 +106,21 @@ class UserOAuth(SQLModel, table=True):
|
|
103
106
|
|
104
107
|
class Config:
|
105
108
|
orm_mode = True
|
109
|
+
|
110
|
+
|
111
|
+
class UserGroup(SQLModel, table=True):
|
112
|
+
"""
|
113
|
+
ORM model for the `usergroup` database table.
|
114
|
+
|
115
|
+
Attributes:
|
116
|
+
id: ID of the group
|
117
|
+
name: Name of the group
|
118
|
+
timestamp_created: Time of creation
|
119
|
+
"""
|
120
|
+
|
121
|
+
id: Optional[int] = Field(default=None, primary_key=True)
|
122
|
+
name: str = Field(unique=True)
|
123
|
+
timestamp_created: datetime = Field(
|
124
|
+
default_factory=get_timestamp,
|
125
|
+
sa_column=Column(DateTime(timezone=True), nullable=False),
|
126
|
+
)
|
@@ -10,7 +10,7 @@ from sqlmodel import SQLModel
|
|
10
10
|
from . import LinkUserProject
|
11
11
|
from ....utils import get_timestamp
|
12
12
|
from ...schemas.v1.project import _ProjectBaseV1
|
13
|
-
from
|
13
|
+
from fractal_server.app.models import UserOAuth
|
14
14
|
|
15
15
|
|
16
16
|
class Project(_ProjectBaseV1, SQLModel, table=True):
|
@@ -7,9 +7,9 @@ from sqlmodel import Field
|
|
7
7
|
from sqlmodel import Relationship
|
8
8
|
from sqlmodel import SQLModel
|
9
9
|
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
10
|
+
from .. import LinkUserProjectV2
|
11
|
+
from fractal_server.app.models import UserOAuth
|
12
|
+
from fractal_server.utils import get_timestamp
|
13
13
|
|
14
14
|
|
15
15
|
class ProjectV2(SQLModel, table=True):
|
@@ -21,7 +21,6 @@ from ....utils import get_timestamp
|
|
21
21
|
from ....zip_tools import _zip_folder_to_byte_stream_iterator
|
22
22
|
from ...db import AsyncSession
|
23
23
|
from ...db import get_async_db
|
24
|
-
from ...models.security import UserOAuth as User
|
25
24
|
from ...models.v1 import ApplyWorkflow
|
26
25
|
from ...models.v1 import Dataset
|
27
26
|
from ...models.v1 import JobStatusTypeV1
|
@@ -33,9 +32,10 @@ from ...schemas.v1 import ApplyWorkflowUpdateV1
|
|
33
32
|
from ...schemas.v1 import DatasetReadV1
|
34
33
|
from ...schemas.v1 import ProjectReadV1
|
35
34
|
from ...schemas.v1 import WorkflowReadV1
|
36
|
-
from ...security import current_active_superuser
|
37
35
|
from ..aux._job import _write_shutdown_file
|
38
36
|
from ..aux._runner import _check_shutdown_is_supported
|
37
|
+
from fractal_server.app.models import UserOAuth
|
38
|
+
from fractal_server.app.routes.auth import current_active_superuser
|
39
39
|
|
40
40
|
router_admin_v1 = APIRouter()
|
41
41
|
|
@@ -63,7 +63,7 @@ async def view_project(
|
|
63
63
|
user_id: Optional[int] = None,
|
64
64
|
timestamp_created_min: Optional[datetime] = None,
|
65
65
|
timestamp_created_max: Optional[datetime] = None,
|
66
|
-
user:
|
66
|
+
user: UserOAuth = Depends(current_active_superuser),
|
67
67
|
db: AsyncSession = Depends(get_async_db),
|
68
68
|
) -> list[ProjectReadV1]:
|
69
69
|
"""
|
@@ -80,7 +80,7 @@ async def view_project(
|
|
80
80
|
stm = stm.where(Project.id == id)
|
81
81
|
|
82
82
|
if user_id is not None:
|
83
|
-
stm = stm.where(Project.user_list.any(
|
83
|
+
stm = stm.where(Project.user_list.any(UserOAuth.id == user_id))
|
84
84
|
if timestamp_created_min is not None:
|
85
85
|
timestamp_created_min = _convert_to_db_timestamp(timestamp_created_min)
|
86
86
|
stm = stm.where(Project.timestamp_created >= timestamp_created_min)
|
@@ -103,7 +103,7 @@ async def view_workflow(
|
|
103
103
|
name_contains: Optional[str] = None,
|
104
104
|
timestamp_created_min: Optional[datetime] = None,
|
105
105
|
timestamp_created_max: Optional[datetime] = None,
|
106
|
-
user:
|
106
|
+
user: UserOAuth = Depends(current_active_superuser),
|
107
107
|
db: AsyncSession = Depends(get_async_db),
|
108
108
|
) -> list[WorkflowReadV1]:
|
109
109
|
"""
|
@@ -119,7 +119,7 @@ async def view_workflow(
|
|
119
119
|
|
120
120
|
if user_id is not None:
|
121
121
|
stm = stm.join(Project).where(
|
122
|
-
Project.user_list.any(
|
122
|
+
Project.user_list.any(UserOAuth.id == user_id)
|
123
123
|
)
|
124
124
|
if id is not None:
|
125
125
|
stm = stm.where(Workflow.id == id)
|
@@ -153,7 +153,7 @@ async def view_dataset(
|
|
153
153
|
type: Optional[str] = None,
|
154
154
|
timestamp_created_min: Optional[datetime] = None,
|
155
155
|
timestamp_created_max: Optional[datetime] = None,
|
156
|
-
user:
|
156
|
+
user: UserOAuth = Depends(current_active_superuser),
|
157
157
|
db: AsyncSession = Depends(get_async_db),
|
158
158
|
) -> list[DatasetReadV1]:
|
159
159
|
"""
|
@@ -170,7 +170,7 @@ async def view_dataset(
|
|
170
170
|
|
171
171
|
if user_id is not None:
|
172
172
|
stm = stm.join(Project).where(
|
173
|
-
Project.user_list.any(
|
173
|
+
Project.user_list.any(UserOAuth.id == user_id)
|
174
174
|
)
|
175
175
|
if id is not None:
|
176
176
|
stm = stm.where(Dataset.id == id)
|
@@ -211,7 +211,7 @@ async def view_job(
|
|
211
211
|
end_timestamp_min: Optional[datetime] = None,
|
212
212
|
end_timestamp_max: Optional[datetime] = None,
|
213
213
|
log: bool = True,
|
214
|
-
user:
|
214
|
+
user: UserOAuth = Depends(current_active_superuser),
|
215
215
|
db: AsyncSession = Depends(get_async_db),
|
216
216
|
) -> list[ApplyWorkflowReadV1]:
|
217
217
|
"""
|
@@ -243,7 +243,7 @@ async def view_job(
|
|
243
243
|
stm = stm.where(ApplyWorkflow.id == id)
|
244
244
|
if user_id is not None:
|
245
245
|
stm = stm.join(Project).where(
|
246
|
-
Project.user_list.any(
|
246
|
+
Project.user_list.any(UserOAuth.id == user_id)
|
247
247
|
)
|
248
248
|
if project_id is not None:
|
249
249
|
stm = stm.where(ApplyWorkflow.project_id == project_id)
|
@@ -282,7 +282,7 @@ async def view_job(
|
|
282
282
|
async def view_single_job(
|
283
283
|
job_id: int = None,
|
284
284
|
show_tmp_logs: bool = False,
|
285
|
-
user:
|
285
|
+
user: UserOAuth = Depends(current_active_superuser),
|
286
286
|
db: AsyncSession = Depends(get_async_db),
|
287
287
|
) -> ApplyWorkflowReadV1:
|
288
288
|
|
@@ -311,7 +311,7 @@ async def view_single_job(
|
|
311
311
|
async def update_job(
|
312
312
|
job_update: ApplyWorkflowUpdateV1,
|
313
313
|
job_id: int,
|
314
|
-
user:
|
314
|
+
user: UserOAuth = Depends(current_active_superuser),
|
315
315
|
db: AsyncSession = Depends(get_async_db),
|
316
316
|
) -> Optional[ApplyWorkflowReadV1]:
|
317
317
|
"""
|
@@ -344,7 +344,7 @@ async def update_job(
|
|
344
344
|
@router_admin_v1.get("/job/{job_id}/stop/", status_code=202)
|
345
345
|
async def stop_job(
|
346
346
|
job_id: int,
|
347
|
-
user:
|
347
|
+
user: UserOAuth = Depends(current_active_superuser),
|
348
348
|
db: AsyncSession = Depends(get_async_db),
|
349
349
|
) -> Response:
|
350
350
|
"""
|
@@ -371,7 +371,7 @@ async def stop_job(
|
|
371
371
|
)
|
372
372
|
async def download_job_logs(
|
373
373
|
job_id: int,
|
374
|
-
user:
|
374
|
+
user: UserOAuth = Depends(current_active_superuser),
|
375
375
|
db: AsyncSession = Depends(get_async_db),
|
376
376
|
) -> StreamingResponse:
|
377
377
|
"""
|
@@ -24,7 +24,6 @@ from ....utils import get_timestamp
|
|
24
24
|
from ....zip_tools import _zip_folder_to_byte_stream_iterator
|
25
25
|
from ...db import AsyncSession
|
26
26
|
from ...db import get_async_db
|
27
|
-
from ...models.security import UserOAuth as User
|
28
27
|
from ...models.v1 import Task
|
29
28
|
from ...models.v2 import JobV2
|
30
29
|
from ...models.v2 import ProjectV2
|
@@ -36,9 +35,10 @@ from ...schemas.v2 import JobReadV2
|
|
36
35
|
from ...schemas.v2 import JobStatusTypeV2
|
37
36
|
from ...schemas.v2 import JobUpdateV2
|
38
37
|
from ...schemas.v2 import ProjectReadV2
|
39
|
-
from ...security import current_active_superuser
|
40
38
|
from ..aux._job import _write_shutdown_file
|
41
39
|
from ..aux._runner import _check_shutdown_is_supported
|
40
|
+
from fractal_server.app.models import UserOAuth
|
41
|
+
from fractal_server.app.routes.auth import current_active_superuser
|
42
42
|
|
43
43
|
router_admin_v2 = APIRouter()
|
44
44
|
|
@@ -64,7 +64,7 @@ def _convert_to_db_timestamp(dt: datetime) -> datetime:
|
|
64
64
|
async def view_project(
|
65
65
|
id: Optional[int] = None,
|
66
66
|
user_id: Optional[int] = None,
|
67
|
-
user:
|
67
|
+
user: UserOAuth = Depends(current_active_superuser),
|
68
68
|
db: AsyncSession = Depends(get_async_db),
|
69
69
|
) -> list[ProjectReadV2]:
|
70
70
|
"""
|
@@ -80,7 +80,7 @@ async def view_project(
|
|
80
80
|
if id is not None:
|
81
81
|
stm = stm.where(ProjectV2.id == id)
|
82
82
|
if user_id is not None:
|
83
|
-
stm = stm.where(ProjectV2.user_list.any(
|
83
|
+
stm = stm.where(ProjectV2.user_list.any(UserOAuth.id == user_id))
|
84
84
|
|
85
85
|
res = await db.execute(stm)
|
86
86
|
project_list = res.scalars().all()
|
@@ -102,7 +102,7 @@ async def view_job(
|
|
102
102
|
end_timestamp_min: Optional[datetime] = None,
|
103
103
|
end_timestamp_max: Optional[datetime] = None,
|
104
104
|
log: bool = True,
|
105
|
-
user:
|
105
|
+
user: UserOAuth = Depends(current_active_superuser),
|
106
106
|
db: AsyncSession = Depends(get_async_db),
|
107
107
|
) -> list[JobReadV2]:
|
108
108
|
"""
|
@@ -132,7 +132,7 @@ async def view_job(
|
|
132
132
|
stm = stm.where(JobV2.id == id)
|
133
133
|
if user_id is not None:
|
134
134
|
stm = stm.join(ProjectV2).where(
|
135
|
-
ProjectV2.user_list.any(
|
135
|
+
ProjectV2.user_list.any(UserOAuth.id == user_id)
|
136
136
|
)
|
137
137
|
if project_id is not None:
|
138
138
|
stm = stm.where(JobV2.project_id == project_id)
|
@@ -169,7 +169,7 @@ async def view_job(
|
|
169
169
|
async def view_single_job(
|
170
170
|
job_id: int = None,
|
171
171
|
show_tmp_logs: bool = False,
|
172
|
-
user:
|
172
|
+
user: UserOAuth = Depends(current_active_superuser),
|
173
173
|
db: AsyncSession = Depends(get_async_db),
|
174
174
|
) -> JobReadV2:
|
175
175
|
|
@@ -198,7 +198,7 @@ async def view_single_job(
|
|
198
198
|
async def update_job(
|
199
199
|
job_update: JobUpdateV2,
|
200
200
|
job_id: int,
|
201
|
-
user:
|
201
|
+
user: UserOAuth = Depends(current_active_superuser),
|
202
202
|
db: AsyncSession = Depends(get_async_db),
|
203
203
|
) -> Optional[JobReadV2]:
|
204
204
|
"""
|
@@ -231,7 +231,7 @@ async def update_job(
|
|
231
231
|
@router_admin_v2.get("/job/{job_id}/stop/", status_code=202)
|
232
232
|
async def stop_job(
|
233
233
|
job_id: int,
|
234
|
-
user:
|
234
|
+
user: UserOAuth = Depends(current_active_superuser),
|
235
235
|
db: AsyncSession = Depends(get_async_db),
|
236
236
|
) -> Response:
|
237
237
|
"""
|
@@ -258,7 +258,7 @@ async def stop_job(
|
|
258
258
|
)
|
259
259
|
async def download_job_logs(
|
260
260
|
job_id: int,
|
261
|
-
user:
|
261
|
+
user: UserOAuth = Depends(current_active_superuser),
|
262
262
|
db: AsyncSession = Depends(get_async_db),
|
263
263
|
) -> StreamingResponse:
|
264
264
|
"""
|
@@ -292,7 +292,7 @@ class TaskCompatibility(BaseModel):
|
|
292
292
|
async def flag_task_v1_as_v2_compatible(
|
293
293
|
task_id: int,
|
294
294
|
compatibility: TaskCompatibility,
|
295
|
-
user:
|
295
|
+
user: UserOAuth = Depends(current_active_superuser),
|
296
296
|
db: AsyncSession = Depends(get_async_db),
|
297
297
|
) -> Response:
|
298
298
|
|
@@ -352,7 +352,7 @@ async def query_tasks(
|
|
352
352
|
owner: Optional[str] = None,
|
353
353
|
kind: Optional[Literal["common", "users"]] = None,
|
354
354
|
max_number_of_results: int = 25,
|
355
|
-
user:
|
355
|
+
user: UserOAuth = Depends(current_active_superuser),
|
356
356
|
db: AsyncSession = Depends(get_async_db),
|
357
357
|
) -> list[TaskV2Info]:
|
358
358
|
"""
|
@@ -6,8 +6,8 @@ from fastapi import Depends
|
|
6
6
|
|
7
7
|
from ....config import get_settings
|
8
8
|
from ....syringe import Inject
|
9
|
-
from
|
10
|
-
from
|
9
|
+
from fractal_server.app.models import UserOAuth
|
10
|
+
from fractal_server.app.routes.auth import current_active_superuser
|
11
11
|
|
12
12
|
|
13
13
|
router_api = APIRouter()
|
@@ -22,7 +22,7 @@ from ....models.v1 import Task
|
|
22
22
|
from ....models.v1 import Workflow
|
23
23
|
from ....models.v1 import WorkflowTask
|
24
24
|
from ....schemas.v1 import JobStatusTypeV1
|
25
|
-
from
|
25
|
+
from fractal_server.app.models import UserOAuth
|
26
26
|
|
27
27
|
|
28
28
|
def _raise_if_v1_is_read_only() -> None:
|
@@ -327,7 +327,7 @@ async def _get_job_check_owner(
|
|
327
327
|
async def _get_task_check_owner(
|
328
328
|
*,
|
329
329
|
task_id: int,
|
330
|
-
user:
|
330
|
+
user: UserOAuth,
|
331
331
|
db: AsyncSession,
|
332
332
|
) -> Task:
|
333
333
|
"""
|
@@ -27,13 +27,13 @@ from ....schemas.v1 import ResourceReadV1
|
|
27
27
|
from ....schemas.v1 import ResourceUpdateV1
|
28
28
|
from ....schemas.v1 import WorkflowExportV1
|
29
29
|
from ....schemas.v1 import WorkflowTaskExportV1
|
30
|
-
from ....security import current_active_user
|
31
|
-
from ....security import User
|
32
30
|
from ._aux_functions import _get_dataset_check_owner
|
33
31
|
from ._aux_functions import _get_project_check_owner
|
34
32
|
from ._aux_functions import _get_submitted_jobs_statement
|
35
33
|
from ._aux_functions import _get_workflow_check_owner
|
36
34
|
from ._aux_functions import _raise_if_v1_is_read_only
|
35
|
+
from fractal_server.app.models import UserOAuth
|
36
|
+
from fractal_server.app.routes.auth import current_active_user
|
37
37
|
|
38
38
|
router = APIRouter()
|
39
39
|
|
@@ -46,7 +46,7 @@ router = APIRouter()
|
|
46
46
|
async def create_dataset(
|
47
47
|
project_id: int,
|
48
48
|
dataset: DatasetCreateV1,
|
49
|
-
user:
|
49
|
+
user: UserOAuth = Depends(current_active_user),
|
50
50
|
db: AsyncSession = Depends(get_async_db),
|
51
51
|
) -> Optional[DatasetReadV1]:
|
52
52
|
"""
|
@@ -72,7 +72,7 @@ async def create_dataset(
|
|
72
72
|
async def read_dataset_list(
|
73
73
|
project_id: int,
|
74
74
|
history: bool = True,
|
75
|
-
user:
|
75
|
+
user: UserOAuth = Depends(current_active_user),
|
76
76
|
db: AsyncSession = Depends(get_async_db),
|
77
77
|
) -> Optional[list[DatasetReadV1]]:
|
78
78
|
"""
|
@@ -103,7 +103,7 @@ async def read_dataset_list(
|
|
103
103
|
async def read_dataset(
|
104
104
|
project_id: int,
|
105
105
|
dataset_id: int,
|
106
|
-
user:
|
106
|
+
user: UserOAuth = Depends(current_active_user),
|
107
107
|
db: AsyncSession = Depends(get_async_db),
|
108
108
|
) -> Optional[DatasetReadV1]:
|
109
109
|
"""
|
@@ -128,7 +128,7 @@ async def update_dataset(
|
|
128
128
|
project_id: int,
|
129
129
|
dataset_id: int,
|
130
130
|
dataset_update: DatasetUpdateV1,
|
131
|
-
user:
|
131
|
+
user: UserOAuth = Depends(current_active_user),
|
132
132
|
db: AsyncSession = Depends(get_async_db),
|
133
133
|
) -> Optional[DatasetReadV1]:
|
134
134
|
"""
|
@@ -165,7 +165,7 @@ async def update_dataset(
|
|
165
165
|
async def delete_dataset(
|
166
166
|
project_id: int,
|
167
167
|
dataset_id: int,
|
168
|
-
user:
|
168
|
+
user: UserOAuth = Depends(current_active_user),
|
169
169
|
db: AsyncSession = Depends(get_async_db),
|
170
170
|
) -> Response:
|
171
171
|
"""
|
@@ -239,7 +239,7 @@ async def create_resource(
|
|
239
239
|
project_id: int,
|
240
240
|
dataset_id: int,
|
241
241
|
resource: ResourceCreateV1,
|
242
|
-
user:
|
242
|
+
user: UserOAuth = Depends(current_active_user),
|
243
243
|
db: AsyncSession = Depends(get_async_db),
|
244
244
|
) -> Optional[ResourceReadV1]:
|
245
245
|
"""
|
@@ -268,7 +268,7 @@ async def create_resource(
|
|
268
268
|
async def get_resource_list(
|
269
269
|
project_id: int,
|
270
270
|
dataset_id: int,
|
271
|
-
user:
|
271
|
+
user: UserOAuth = Depends(current_active_user),
|
272
272
|
db: AsyncSession = Depends(get_async_db),
|
273
273
|
) -> Optional[list[ResourceReadV1]]:
|
274
274
|
"""
|
@@ -296,7 +296,7 @@ async def update_resource(
|
|
296
296
|
dataset_id: int,
|
297
297
|
resource_id: int,
|
298
298
|
resource_update: ResourceUpdateV1,
|
299
|
-
user:
|
299
|
+
user: UserOAuth = Depends(current_active_user),
|
300
300
|
db: AsyncSession = Depends(get_async_db),
|
301
301
|
) -> Optional[ResourceReadV1]:
|
302
302
|
"""
|
@@ -337,7 +337,7 @@ async def delete_resource(
|
|
337
337
|
project_id: int,
|
338
338
|
dataset_id: int,
|
339
339
|
resource_id: int,
|
340
|
-
user:
|
340
|
+
user: UserOAuth = Depends(current_active_user),
|
341
341
|
db: AsyncSession = Depends(get_async_db),
|
342
342
|
) -> Response:
|
343
343
|
"""
|
@@ -371,7 +371,7 @@ async def delete_resource(
|
|
371
371
|
async def export_history_as_workflow(
|
372
372
|
project_id: int,
|
373
373
|
dataset_id: int,
|
374
|
-
user:
|
374
|
+
user: UserOAuth = Depends(current_active_user),
|
375
375
|
db: AsyncSession = Depends(get_async_db),
|
376
376
|
) -> Optional[WorkflowExportV1]:
|
377
377
|
"""
|
@@ -439,7 +439,7 @@ async def export_history_as_workflow(
|
|
439
439
|
async def get_workflowtask_status(
|
440
440
|
project_id: int,
|
441
441
|
dataset_id: int,
|
442
|
-
user:
|
442
|
+
user: UserOAuth = Depends(current_active_user),
|
443
443
|
db: AsyncSession = Depends(get_async_db),
|
444
444
|
) -> Optional[DatasetStatusReadV1]:
|
445
445
|
"""
|
@@ -535,14 +535,16 @@ async def get_workflowtask_status(
|
|
535
535
|
@router.get("/dataset/", response_model=list[DatasetReadV1])
|
536
536
|
async def get_user_datasets(
|
537
537
|
history: bool = True,
|
538
|
-
user:
|
538
|
+
user: UserOAuth = Depends(current_active_user),
|
539
539
|
db: AsyncSession = Depends(get_async_db),
|
540
540
|
) -> list[DatasetReadV1]:
|
541
541
|
"""
|
542
542
|
Returns all the datasets of the current user
|
543
543
|
"""
|
544
544
|
stm = select(Dataset)
|
545
|
-
stm = stm.join(Project).where(
|
545
|
+
stm = stm.join(Project).where(
|
546
|
+
Project.user_list.any(UserOAuth.id == user.id)
|
547
|
+
)
|
546
548
|
res = await db.execute(stm)
|
547
549
|
dataset_list = res.scalars().all()
|
548
550
|
await db.close()
|
@@ -16,20 +16,20 @@ from ....models.v1 import JobStatusTypeV1
|
|
16
16
|
from ....models.v1 import Project
|
17
17
|
from ....runner.filenames import WORKFLOW_LOG_FILENAME
|
18
18
|
from ....schemas.v1 import ApplyWorkflowReadV1
|
19
|
-
from ....security import current_active_user
|
20
|
-
from ....security import User
|
21
19
|
from ...aux._job import _write_shutdown_file
|
22
20
|
from ...aux._runner import _check_shutdown_is_supported
|
23
21
|
from ._aux_functions import _get_job_check_owner
|
24
22
|
from ._aux_functions import _get_project_check_owner
|
25
23
|
from ._aux_functions import _get_workflow_check_owner
|
24
|
+
from fractal_server.app.models import UserOAuth
|
25
|
+
from fractal_server.app.routes.auth import current_active_user
|
26
26
|
|
27
27
|
router = APIRouter()
|
28
28
|
|
29
29
|
|
30
30
|
@router.get("/job/", response_model=list[ApplyWorkflowReadV1])
|
31
31
|
async def get_user_jobs(
|
32
|
-
user:
|
32
|
+
user: UserOAuth = Depends(current_active_user),
|
33
33
|
log: bool = True,
|
34
34
|
db: AsyncSession = Depends(get_async_db),
|
35
35
|
) -> list[ApplyWorkflowReadV1]:
|
@@ -37,7 +37,9 @@ async def get_user_jobs(
|
|
37
37
|
Returns all the jobs of the current user
|
38
38
|
"""
|
39
39
|
stm = select(ApplyWorkflow)
|
40
|
-
stm = stm.join(Project).where(
|
40
|
+
stm = stm.join(Project).where(
|
41
|
+
Project.user_list.any(UserOAuth.id == user.id)
|
42
|
+
)
|
41
43
|
res = await db.execute(stm)
|
42
44
|
job_list = res.scalars().all()
|
43
45
|
await db.close()
|
@@ -55,7 +57,7 @@ async def get_user_jobs(
|
|
55
57
|
async def get_workflow_jobs(
|
56
58
|
project_id: int,
|
57
59
|
workflow_id: int,
|
58
|
-
user:
|
60
|
+
user: UserOAuth = Depends(current_active_user),
|
59
61
|
db: AsyncSession = Depends(get_async_db),
|
60
62
|
) -> Optional[list[ApplyWorkflowReadV1]]:
|
61
63
|
"""
|
@@ -78,7 +80,7 @@ async def read_job(
|
|
78
80
|
project_id: int,
|
79
81
|
job_id: int,
|
80
82
|
show_tmp_logs: bool = False,
|
81
|
-
user:
|
83
|
+
user: UserOAuth = Depends(current_active_user),
|
82
84
|
db: AsyncSession = Depends(get_async_db),
|
83
85
|
) -> Optional[ApplyWorkflowReadV1]:
|
84
86
|
"""
|
@@ -111,7 +113,7 @@ async def read_job(
|
|
111
113
|
async def download_job_logs(
|
112
114
|
project_id: int,
|
113
115
|
job_id: int,
|
114
|
-
user:
|
116
|
+
user: UserOAuth = Depends(current_active_user),
|
115
117
|
db: AsyncSession = Depends(get_async_db),
|
116
118
|
) -> StreamingResponse:
|
117
119
|
"""
|
@@ -141,7 +143,7 @@ async def download_job_logs(
|
|
141
143
|
)
|
142
144
|
async def get_job_list(
|
143
145
|
project_id: int,
|
144
|
-
user:
|
146
|
+
user: UserOAuth = Depends(current_active_user),
|
145
147
|
log: bool = True,
|
146
148
|
db: AsyncSession = Depends(get_async_db),
|
147
149
|
) -> Optional[list[ApplyWorkflowReadV1]]:
|
@@ -170,7 +172,7 @@ async def get_job_list(
|
|
170
172
|
async def stop_job(
|
171
173
|
project_id: int,
|
172
174
|
job_id: int,
|
173
|
-
user:
|
175
|
+
user: UserOAuth = Depends(current_active_user),
|
174
176
|
db: AsyncSession = Depends(get_async_db),
|
175
177
|
) -> Response:
|
176
178
|
"""
|