fractal-server 2.18.0a0__py3-none-any.whl → 2.18.0a2__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.
@@ -1 +1 @@
1
- __VERSION__ = "2.18.0a0"
1
+ __VERSION__ = "2.18.0a2"
@@ -67,11 +67,11 @@ async def query_accounting(
67
67
  res = await db.execute(stm)
68
68
  records = res.scalars().all()
69
69
 
70
- return PaginationResponse[AccountingRecordRead](
70
+ return dict(
71
71
  total_count=total_count,
72
72
  page_size=page_size,
73
73
  current_page=page,
74
- items=[record.model_dump() for record in records],
74
+ items=records,
75
75
  )
76
76
 
77
77
 
@@ -146,11 +146,11 @@ async def view_job(
146
146
  for job in job_list:
147
147
  setattr(job, "log", None)
148
148
 
149
- return PaginationResponse[JobReadV2](
149
+ return dict(
150
150
  total_count=total_count,
151
151
  page_size=page_size,
152
152
  current_page=page,
153
- items=[job.model_dump() for job in job_list],
153
+ items=job_list,
154
154
  )
155
155
 
156
156
 
@@ -170,7 +170,7 @@ async def query_tasks(
170
170
  ],
171
171
  )
172
172
  )
173
- return PaginationResponse[TaskV2Info](
173
+ return dict(
174
174
  total_count=total_count,
175
175
  page_size=page_size,
176
176
  current_page=page,
@@ -5,6 +5,7 @@ from fastapi import status
5
5
  from pydantic.types import AwareDatetime
6
6
  from sqlalchemy.sql.operators import is_
7
7
  from sqlalchemy.sql.operators import is_not
8
+ from sqlmodel import func
8
9
  from sqlmodel import select
9
10
 
10
11
  from fractal_server.app.db import AsyncSession
@@ -16,6 +17,9 @@ from fractal_server.app.routes.auth import current_superuser_act
16
17
  from fractal_server.app.routes.auth._aux_auth import (
17
18
  _verify_user_belongs_to_group,
18
19
  )
20
+ from fractal_server.app.routes.pagination import PaginationRequest
21
+ from fractal_server.app.routes.pagination import PaginationResponse
22
+ from fractal_server.app.routes.pagination import get_pagination_params
19
23
  from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
20
24
  from fractal_server.app.schemas.v2 import TaskGroupActivityStatusV2
21
25
  from fractal_server.app.schemas.v2 import TaskGroupActivityV2Read
@@ -29,7 +33,9 @@ router = APIRouter()
29
33
  logger = set_logger(__name__)
30
34
 
31
35
 
32
- @router.get("/activity/", response_model=list[TaskGroupActivityV2Read])
36
+ @router.get(
37
+ "/activity/", response_model=PaginationResponse[TaskGroupActivityV2Read]
38
+ )
33
39
  async def get_task_group_activity_list(
34
40
  task_group_activity_id: int | None = None,
35
41
  user_id: int | None = None,
@@ -38,30 +44,65 @@ async def get_task_group_activity_list(
38
44
  status: TaskGroupActivityStatusV2 | None = None,
39
45
  action: TaskGroupActivityActionV2 | None = None,
40
46
  timestamp_started_min: AwareDatetime | None = None,
47
+ pagination: PaginationRequest = Depends(get_pagination_params),
41
48
  superuser: UserOAuth = Depends(current_superuser_act),
42
49
  db: AsyncSession = Depends(get_async_db),
43
- ) -> list[TaskGroupActivityV2Read]:
50
+ ) -> PaginationResponse[TaskGroupActivityV2Read]:
51
+ # Assign pagination parameters
52
+ page = pagination.page
53
+ page_size = pagination.page_size
54
+
44
55
  stm = select(TaskGroupActivityV2)
56
+ stm_count = select(func.count(TaskGroupActivityV2.id))
45
57
  if task_group_activity_id is not None:
46
58
  stm = stm.where(TaskGroupActivityV2.id == task_group_activity_id)
59
+ stm_count = stm_count.where(
60
+ TaskGroupActivityV2.id == task_group_activity_id
61
+ )
47
62
  if user_id:
48
63
  stm = stm.where(TaskGroupActivityV2.user_id == user_id)
64
+ stm_count = stm_count.where(TaskGroupActivityV2.user_id == user_id)
49
65
  if taskgroupv2_id:
50
66
  stm = stm.where(TaskGroupActivityV2.taskgroupv2_id == taskgroupv2_id)
67
+ stm_count = stm_count.where(
68
+ TaskGroupActivityV2.taskgroupv2_id == taskgroupv2_id
69
+ )
51
70
  if pkg_name:
52
71
  stm = stm.where(TaskGroupActivityV2.pkg_name.icontains(pkg_name))
72
+ stm_count = stm_count.where(
73
+ TaskGroupActivityV2.pkg_name.icontains(pkg_name)
74
+ )
53
75
  if status:
54
76
  stm = stm.where(TaskGroupActivityV2.status == status)
77
+ stm_count = stm_count.where(TaskGroupActivityV2.status == status)
55
78
  if action:
56
79
  stm = stm.where(TaskGroupActivityV2.action == action)
80
+ stm_count = stm_count.where(TaskGroupActivityV2.action == action)
57
81
  if timestamp_started_min is not None:
58
82
  stm = stm.where(
59
83
  TaskGroupActivityV2.timestamp_started >= timestamp_started_min
60
84
  )
85
+ stm_count = stm_count.where(
86
+ TaskGroupActivityV2.timestamp_started >= timestamp_started_min
87
+ )
88
+
89
+ # Find total number of elements
90
+ res_total_count = await db.execute(stm_count)
91
+ total_count = res_total_count.scalar()
92
+ if page_size is None:
93
+ page_size = total_count
94
+ else:
95
+ stm = stm.offset((page - 1) * page_size).limit(page_size)
61
96
 
62
97
  res = await db.execute(stm)
63
98
  activities = res.scalars().all()
64
- return activities
99
+
100
+ return dict(
101
+ total_count=total_count,
102
+ page_size=page_size,
103
+ current_page=page,
104
+ items=activities,
105
+ )
65
106
 
66
107
 
67
108
  @router.get("/{task_group_id}/", response_model=TaskGroupReadSuperuser)
@@ -79,7 +120,7 @@ async def query_task_group(
79
120
  return task_group
80
121
 
81
122
 
82
- @router.get("/", response_model=list[TaskGroupReadSuperuser])
123
+ @router.get("/", response_model=PaginationResponse[TaskGroupReadSuperuser])
83
124
  async def query_task_group_list(
84
125
  user_id: int | None = None,
85
126
  user_group_id: int | None = None,
@@ -90,10 +131,16 @@ async def query_task_group_list(
90
131
  timestamp_last_used_min: AwareDatetime | None = None,
91
132
  timestamp_last_used_max: AwareDatetime | None = None,
92
133
  resource_id: int | None = None,
134
+ pagination: PaginationRequest = Depends(get_pagination_params),
93
135
  user: UserOAuth = Depends(current_superuser_act),
94
136
  db: AsyncSession = Depends(get_async_db),
95
- ) -> list[TaskGroupReadSuperuser]:
137
+ ) -> PaginationResponse[TaskGroupReadSuperuser]:
138
+ # Assign pagination parameters
139
+ page = pagination.page
140
+ page_size = pagination.page_size
141
+
96
142
  stm = select(TaskGroupV2)
143
+ stm_count = select(func.count(TaskGroupV2.id))
97
144
 
98
145
  if user_group_id is not None and private is True:
99
146
  raise HTTPException(
@@ -105,37 +152,66 @@ async def query_task_group_list(
105
152
  )
106
153
  if user_id is not None:
107
154
  stm = stm.where(TaskGroupV2.user_id == user_id)
155
+ stm_count = stm_count.where(TaskGroupV2.user_id == user_id)
108
156
  if user_group_id is not None:
109
157
  stm = stm.where(TaskGroupV2.user_group_id == user_group_id)
158
+ stm_count = stm_count.where(TaskGroupV2.user_group_id == user_group_id)
110
159
  if private is not None:
111
160
  if private is True:
112
161
  stm = stm.where(is_(TaskGroupV2.user_group_id, None))
162
+ stm_count = stm_count.where(is_(TaskGroupV2.user_group_id, None))
113
163
  else:
114
164
  stm = stm.where(is_not(TaskGroupV2.user_group_id, None))
165
+ stm_count = stm_count.where(is_not(TaskGroupV2.user_group_id, None))
115
166
  if active is not None:
116
167
  if active is True:
117
168
  stm = stm.where(is_(TaskGroupV2.active, True))
169
+ stm_count = stm_count.where(is_(TaskGroupV2.active, True))
118
170
  else:
119
171
  stm = stm.where(is_(TaskGroupV2.active, False))
172
+ stm_count = stm_count.where(is_(TaskGroupV2.active, False))
120
173
  if origin is not None:
121
174
  stm = stm.where(TaskGroupV2.origin == origin)
175
+ stm_count = stm_count.where(TaskGroupV2.origin == origin)
122
176
  if pkg_name is not None:
123
177
  stm = stm.where(TaskGroupV2.pkg_name.icontains(pkg_name))
178
+ stm_count = stm_count.where(TaskGroupV2.pkg_name.icontains(pkg_name))
124
179
  if timestamp_last_used_min is not None:
125
180
  stm = stm.where(
126
181
  TaskGroupV2.timestamp_last_used >= timestamp_last_used_min
127
182
  )
183
+ stm_count = stm_count.where(
184
+ TaskGroupV2.timestamp_last_used >= timestamp_last_used_min
185
+ )
128
186
  if timestamp_last_used_max is not None:
129
187
  stm = stm.where(
130
188
  TaskGroupV2.timestamp_last_used <= timestamp_last_used_max
131
189
  )
190
+ stm_count = stm_count.where(
191
+ TaskGroupV2.timestamp_last_used <= timestamp_last_used_max
192
+ )
132
193
  if resource_id is not None:
133
194
  stm = stm.where(TaskGroupV2.resource_id == resource_id)
195
+ stm_count = stm_count.where(TaskGroupV2.resource_id == resource_id)
196
+
197
+ # Find total number of elements
198
+ res_total_count = await db.execute(stm_count)
199
+ total_count = res_total_count.scalar()
200
+ if page_size is None:
201
+ page_size = total_count
202
+ else:
203
+ stm = stm.offset((page - 1) * page_size).limit(page_size)
134
204
 
135
205
  stm = stm.order_by(TaskGroupV2.id)
136
206
  res = await db.execute(stm)
137
207
  task_groups_list = res.scalars().all()
138
- return task_groups_list
208
+
209
+ return dict(
210
+ total_count=total_count,
211
+ page_size=page_size,
212
+ current_page=page,
213
+ items=task_groups_list,
214
+ )
139
215
 
140
216
 
141
217
  @router.patch("/{task_group_id}/", response_model=TaskGroupReadSuperuser)
@@ -243,9 +243,8 @@ async def get_access_info(
243
243
  UserOAuth.id == LinkUserProjectV2.user_id,
244
244
  )
245
245
  .where(LinkUserProjectV2.is_owner.is_(True))
246
- .where(LinkUserProjectV2.project_id == ProjectV2.id)
246
+ .where(LinkUserProjectV2.project_id == project_id)
247
247
  .scalar_subquery()
248
- .correlate(LinkUserProjectV2)
249
248
  ),
250
249
  )
251
250
  .where(LinkUserProjectV2.project_id == project_id)
@@ -5,12 +5,10 @@ from fastapi import Depends
5
5
  from fastapi import HTTPException
6
6
  from fastapi import Response
7
7
  from fastapi import status
8
- from sqlmodel import select
9
8
 
10
9
  from fractal_server.app.db import AsyncSession
11
10
  from fractal_server.app.db import get_async_db
12
11
  from fractal_server.app.models import UserOAuth
13
- from fractal_server.app.models.linkuserproject import LinkUserProjectV2
14
12
  from fractal_server.app.routes.auth import current_user_act_ver_prof
15
13
  from fractal_server.app.schemas.v2 import TaskType
16
14
  from fractal_server.app.schemas.v2 import WorkflowTaskCreateV2
@@ -53,30 +51,6 @@ async def create_workflowtask(
53
51
  db=db,
54
52
  )
55
53
 
56
- res = await db.execute(
57
- select(UserOAuth.id)
58
- .join(LinkUserProjectV2, LinkUserProjectV2.user_id == UserOAuth.id)
59
- .where(LinkUserProjectV2.project_id == project_id)
60
- .where(LinkUserProjectV2.is_owner.is_(True))
61
- )
62
- project_owner_id = res.scalar_one()
63
- if project_owner_id != user.id:
64
- try:
65
- await _get_task_read_access(
66
- task_id=task_id,
67
- user_id=project_owner_id,
68
- db=db,
69
- require_active=True,
70
- )
71
- except HTTPException as e:
72
- if e.status_code == 403:
73
- raise HTTPException(
74
- status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
75
- detail="The task must be accessible to the project owner.",
76
- )
77
- else:
78
- raise e
79
-
80
54
  task = await _get_task_read_access(
81
55
  task_id=task_id, user_id=user.id, db=db, require_active=True
82
56
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fractal-server
3
- Version: 2.18.0a0
3
+ Version: 2.18.0a2
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  License-Expression: BSD-3-Clause
6
6
  License-File: LICENSE
@@ -1,4 +1,4 @@
1
- fractal_server/__init__.py,sha256=zUjuvRpoe51pROLg8ctvKgpIyEZgCSJzeDX3TTVg9Ms,25
1
+ fractal_server/__init__.py,sha256=ymMa3khu1XbUTZPvgZZ7weboT819iCbAcr-inHWj9bk,25
2
2
  fractal_server/__main__.py,sha256=o63YYNPm6wv0YG5PTtxPselXY6g3ii5VoBP8blPGgK8,11423
3
3
  fractal_server/alembic.ini,sha256=MWwi7GzjzawI9cCAK1LW7NxIBQDUqD12-ptJoq5JpP0,3153
4
4
  fractal_server/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -23,14 +23,14 @@ fractal_server/app/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
23
23
  fractal_server/app/routes/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  fractal_server/app/routes/admin/v2/__init__.py,sha256=l3BVqu5f_KXW-8KCpmnI9QS_sZJTXygIz7Z_WawCGDA,1170
25
25
  fractal_server/app/routes/admin/v2/_aux_functions.py,sha256=fqA5sUCFuD2iVANQt2WUUfVOEVz5egQA7inzUKYGCw0,1684
26
- fractal_server/app/routes/admin/v2/accounting.py,sha256=HJ98G_Pde31cwEOqtloAJBXxsoRgNaoSG46OW7x1OBM,3584
26
+ fractal_server/app/routes/admin/v2/accounting.py,sha256=xNXyQYpa0K0bOjd5WNVKfU6zBhvT2-Xgrx2F4vdS9C0,3512
27
27
  fractal_server/app/routes/admin/v2/impersonate.py,sha256=ictDjuvBr3iLv3YtwkVRMNQRq5qtPAeAXbbC7STSsEg,1125
28
- fractal_server/app/routes/admin/v2/job.py,sha256=aozHUx7nrDGr-JagePWjwdFGfW7nsAMH4RNvi4iLrsk,10515
28
+ fractal_server/app/routes/admin/v2/job.py,sha256=PKiZx0kzD9nteyqV0BUDlNdlH6pmRD8EzrJmpZCzlMs,10460
29
29
  fractal_server/app/routes/admin/v2/profile.py,sha256=DwLlA9K3hkl9BqzyifIDiaWeHOM_N_17kqB5CSJOhSI,3165
30
30
  fractal_server/app/routes/admin/v2/resource.py,sha256=c2z6b_D_W6_dqVnxNF8F8OdlI5Z4asex8Zgfwzjbi2Q,6330
31
31
  fractal_server/app/routes/admin/v2/sharing.py,sha256=x7RtbDPapyENEU_s4-glPoEeEOxxj2VBgduVQ1V7wkE,3796
32
- fractal_server/app/routes/admin/v2/task.py,sha256=t_ldc_71ZNbYuymmhn2WT8RqZlxMUceQfLU3LLInR4I,6127
33
- fractal_server/app/routes/admin/v2/task_group.py,sha256=zotpvn5ccQ9Kn-mgIorxJ8RU0BelxP_EEIi-2THH4kA,6248
32
+ fractal_server/app/routes/admin/v2/task.py,sha256=DMGMUY2uF55wrCkPr3u8qBLp4UWZbAEk2W5sbYMQS-Q,6101
33
+ fractal_server/app/routes/admin/v2/task_group.py,sha256=CodDIzTBbTOOdLbXr7qAv6VZydpA6xl0be0W_cw42tE,9330
34
34
  fractal_server/app/routes/admin/v2/task_group_lifecycle.py,sha256=3LtyLDLFDEWSx9e4huXV_uBUdoDuIWib7IzMjlD1OMI,9975
35
35
  fractal_server/app/routes/api/__init__.py,sha256=kq_c4t4a0rrJ6zMO0WGOTjCHf46SAlmWhh7Sa-3LkNg,1659
36
36
  fractal_server/app/routes/api/v2/__init__.py,sha256=lOSRxe408B3dUfd1FtpfynEWBwKDVFlUt3I4NpIQTRo,2938
@@ -47,7 +47,7 @@ fractal_server/app/routes/api/v2/images.py,sha256=k9wd44iwjCtEWSH9j6X6zToBwuOOo6
47
47
  fractal_server/app/routes/api/v2/job.py,sha256=vRN3Ovwami_4CpZw8zJN1azltMCh2ed42dlOfVHHG6Q,7274
48
48
  fractal_server/app/routes/api/v2/pre_submission_checks.py,sha256=Cs_ODoRWmkbSJJhlIE7pQh9JuJGXZTAr-EVF6wqKNGA,5215
49
49
  fractal_server/app/routes/api/v2/project.py,sha256=TlcixNdrss6-0jSiFGnlLP-qCsuX8_nhUyagG5tip3c,5833
50
- fractal_server/app/routes/api/v2/sharing.py,sha256=mwq8p6rQ4wE4ymli_azV-BYDbVk45RzYqMBei0wuzzk,9446
50
+ fractal_server/app/routes/api/v2/sharing.py,sha256=MvegcF3xaT9nztVwLiUisp4B8IrKRa2LVlSR2GGTqYk,9398
51
51
  fractal_server/app/routes/api/v2/status_legacy.py,sha256=zP5YheZBoeffanUpVZvKYL4kYIiGIkGtR9W9GX0pXVE,6599
52
52
  fractal_server/app/routes/api/v2/submit.py,sha256=HScEY2IC4xVLXBoe1Pwiy9bjNR1FnEuAJWjQTidEGFU,9562
53
53
  fractal_server/app/routes/api/v2/task.py,sha256=gekExcUmk-A8psT0_D356U-j8k38aw_wrCO8kWgG2Tw,7536
@@ -59,7 +59,7 @@ fractal_server/app/routes/api/v2/task_group_lifecycle.py,sha256=g20Egnwlw8Qvm1Pz
59
59
  fractal_server/app/routes/api/v2/task_version_update.py,sha256=p0Bk8B7EZi9T0IWeDPqH7U7JNcjMGj1x72-ngZGgTOU,8497
60
60
  fractal_server/app/routes/api/v2/workflow.py,sha256=EW6u-_O6ox3DVBYgrllMfCMHC-DNetUNT6OZudbThko,10830
61
61
  fractal_server/app/routes/api/v2/workflow_import.py,sha256=zSCWKFzwIX2fWpxZJKXHbFk11nuUrgJL50-P0E_vYTc,9668
62
- fractal_server/app/routes/api/v2/workflowtask.py,sha256=phHiQU8y4kTDaCJ6BQwTp4SPdE_L4MH3QTnWnkx1hcA,9225
62
+ fractal_server/app/routes/api/v2/workflowtask.py,sha256=t4h7l63Kfr0vrD6OsN39YSDBXQyoyPqFX3hX7mYXk3U,8274
63
63
  fractal_server/app/routes/auth/__init__.py,sha256=RghfjGuu0RTW8RxBCvaePx9KErO4rTkI96XgbtbeSJU,2337
64
64
  fractal_server/app/routes/auth/_aux_auth.py,sha256=s_boxuhPC60j74NmE8FopYPv_Fc4hiADvL0beWPcuE0,5474
65
65
  fractal_server/app/routes/auth/current_user.py,sha256=Y_2Es3HFtTMuVUmWVHFFvk3vsRgmlqS_x5BwkeavlvI,5552
@@ -263,8 +263,8 @@ fractal_server/types/validators/_workflow_task_arguments_validators.py,sha256=zt
263
263
  fractal_server/urls.py,sha256=QjIKAC1a46bCdiPMu3AlpgFbcv6a4l3ABcd5xz190Og,471
264
264
  fractal_server/utils.py,sha256=-rjg8QTXQcKweXjn0NcmETFs1_uM9PGnbl0Q7c4ERPM,2181
265
265
  fractal_server/zip_tools.py,sha256=Uhn-ax4_9g1PJ32BdyaX30hFpAeVOv2tZYTUK-zVn1E,5719
266
- fractal_server-2.18.0a0.dist-info/METADATA,sha256=Z6QtIkxxrETcp7P-PYKpvhf1xAhqzoEuwwZtkfGz3gs,4277
267
- fractal_server-2.18.0a0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
268
- fractal_server-2.18.0a0.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
269
- fractal_server-2.18.0a0.dist-info/licenses/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
270
- fractal_server-2.18.0a0.dist-info/RECORD,,
266
+ fractal_server-2.18.0a2.dist-info/METADATA,sha256=B1LorgKcZ-DA4V6EEu2lrU6wqLrv_5yo-9pJqSdwZmY,4277
267
+ fractal_server-2.18.0a2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
268
+ fractal_server-2.18.0a2.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
269
+ fractal_server-2.18.0a2.dist-info/licenses/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
270
+ fractal_server-2.18.0a2.dist-info/RECORD,,