fractal-server 2.14.0a1__py3-none-any.whl → 2.14.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.14.0a1"
1
+ __VERSION__ = "2.14.0a2"
@@ -50,4 +50,4 @@ class ImageStatus(SQLModel, table=True):
50
50
 
51
51
  parameters_hash: str
52
52
  status: str
53
- logfile: str
53
+ logfile: Optional[str]
@@ -3,9 +3,6 @@ from typing import Optional
3
3
 
4
4
  from fastapi import APIRouter
5
5
  from fastapi import Depends
6
- from fastapi import HTTPException
7
- from fastapi import Query
8
- from fastapi import status
9
6
  from fastapi.responses import JSONResponse
10
7
  from pydantic import BaseModel
11
8
  from pydantic.types import AwareDatetime
@@ -18,6 +15,9 @@ from fractal_server.app.models import UserOAuth
18
15
  from fractal_server.app.models.v2 import AccountingRecord
19
16
  from fractal_server.app.models.v2 import AccountingRecordSlurm
20
17
  from fractal_server.app.routes.auth import current_active_superuser
18
+ from fractal_server.app.routes.pagination import get_pagination_params
19
+ from fractal_server.app.routes.pagination import PaginationRequest
20
+ from fractal_server.app.routes.pagination import PaginationResponse
21
21
  from fractal_server.app.schemas.v2 import AccountingRecordRead
22
22
 
23
23
 
@@ -27,32 +27,19 @@ class AccountingQuery(BaseModel):
27
27
  timestamp_max: Optional[AwareDatetime] = None
28
28
 
29
29
 
30
- class AccountingPage(BaseModel):
31
- total_count: int
32
- page_size: int
33
- current_page: int
34
- records: list[AccountingRecordRead]
35
-
36
-
37
30
  router = APIRouter()
38
31
 
39
32
 
40
- @router.post("/", response_model=AccountingPage)
33
+ @router.post("/", response_model=PaginationResponse[AccountingRecordRead])
41
34
  async def query_accounting(
42
35
  query: AccountingQuery,
43
- # pagination
44
- page: int = Query(default=1, ge=1),
45
- page_size: Optional[int] = Query(default=None, ge=1),
46
- # dependencies
36
+ # Dependencies
37
+ pagination: PaginationRequest = Depends(get_pagination_params),
47
38
  superuser: UserOAuth = Depends(current_active_superuser),
48
39
  db: AsyncSession = Depends(get_async_db),
49
- ) -> AccountingPage:
50
-
51
- if page_size is None and page > 1:
52
- raise HTTPException(
53
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
54
- detail=(f"Invalid pagination parameters: {page=}, {page_size=}."),
55
- )
40
+ ) -> PaginationResponse[AccountingRecordRead]:
41
+ page = pagination.page
42
+ page_size = pagination.page_size
56
43
 
57
44
  stm = select(AccountingRecord).order_by(AccountingRecord.id)
58
45
  stm_count = select(func.count(AccountingRecord.id))
@@ -69,20 +56,23 @@ async def query_accounting(
69
56
  stm_count = stm_count.where(
70
57
  AccountingRecord.timestamp <= query.timestamp_max
71
58
  )
59
+
60
+ res_total_count = await db.execute(stm_count)
61
+ total_count = res_total_count.scalar()
62
+
72
63
  if page_size is not None:
73
64
  stm = stm.offset((page - 1) * page_size).limit(page_size)
65
+ else:
66
+ page_size = total_count
74
67
 
75
68
  res = await db.execute(stm)
76
69
  records = res.scalars().all()
77
- res_total_count = await db.execute(stm_count)
78
- total_count = res_total_count.scalar()
79
70
 
80
- actual_page_size = page_size or len(records)
81
- return AccountingPage(
71
+ return PaginationResponse[AccountingRecordRead](
82
72
  total_count=total_count,
83
- page_size=actual_page_size,
73
+ page_size=page_size,
84
74
  current_page=page,
85
- records=[record.model_dump() for record in records],
75
+ items=[record.model_dump() for record in records],
86
76
  )
87
77
 
88
78
 
@@ -470,7 +470,7 @@ async def _get_workflowtask_check_history_owner(
470
470
  dataset_id: int,
471
471
  user_id: int,
472
472
  db: AsyncSession,
473
- ) -> list[int]:
473
+ ) -> WorkflowTaskV2:
474
474
  """
475
475
  Verify user access for the history of this dataset and workflowtask.
476
476
 
@@ -479,9 +479,6 @@ async def _get_workflowtask_check_history_owner(
479
479
  workflow_task_id:
480
480
  user_id:
481
481
  db:
482
-
483
- Returns:
484
- List of WorkflowTask IDs
485
482
  """
486
483
  workflowtask = await db.get(WorkflowTaskV2, workflowtask_id)
487
484
  if workflowtask is None:
@@ -495,3 +492,4 @@ async def _get_workflowtask_check_history_owner(
495
492
  user_id=user_id,
496
493
  db=db,
497
494
  )
495
+ return workflowtask
@@ -1,25 +1,28 @@
1
+ from pathlib import Path
1
2
  from typing import Optional
2
3
 
3
4
  from fastapi import APIRouter
4
5
  from fastapi import Depends
5
6
  from fastapi import HTTPException
6
- from fastapi import Query
7
7
  from fastapi import status
8
8
  from fastapi.responses import JSONResponse
9
+ from pydantic import BaseModel
9
10
  from sqlmodel import func
10
11
  from sqlmodel import select
11
12
 
12
13
  from ._aux_functions import _get_dataset_check_owner
13
14
  from ._aux_functions import _get_workflow_check_owner
14
- from ._aux_functions import _get_workflow_task_check_owner
15
+ from ._aux_functions import _get_workflowtask_check_history_owner
15
16
  from fractal_server.app.db import AsyncSession
16
17
  from fractal_server.app.db import get_async_db
17
18
  from fractal_server.app.history.status_enum import HistoryItemImageStatus
18
19
  from fractal_server.app.models import UserOAuth
19
20
  from fractal_server.app.models.v2 import HistoryItemV2
20
21
  from fractal_server.app.models.v2 import ImageStatus
21
- from fractal_server.app.models.v2 import WorkflowTaskV2
22
22
  from fractal_server.app.routes.auth import current_active_user
23
+ from fractal_server.app.routes.pagination import get_pagination_params
24
+ from fractal_server.app.routes.pagination import PaginationRequest
25
+ from fractal_server.app.routes.pagination import PaginationResponse
23
26
  from fractal_server.app.schemas.v2.history import HistoryItemV2Read
24
27
 
25
28
  router = APIRouter()
@@ -122,16 +125,10 @@ async def get_per_workflowtask_subsets_aggregated_info(
122
125
  user: UserOAuth = Depends(current_active_user),
123
126
  db: AsyncSession = Depends(get_async_db),
124
127
  ) -> JSONResponse:
125
- wftask = await db.get(WorkflowTaskV2, workflowtask_id)
126
- if wftask is None:
127
- raise HTTPException(
128
- status_code=status.HTTP_404_NOT_FOUND,
129
- detail="WorkflowTask not found",
130
- )
131
- await _get_workflow_task_check_owner(
132
- project_id=project_id,
133
- workflow_id=wftask.workflow_id,
134
- workflow_task_id=workflowtask_id,
128
+
129
+ await _get_workflowtask_check_history_owner(
130
+ dataset_id=dataset_id,
131
+ workflowtask_id=workflowtask_id,
135
132
  user_id=user.id,
136
133
  db=db,
137
134
  )
@@ -181,30 +178,18 @@ async def get_per_workflowtask_images(
181
178
  dataset_id: int,
182
179
  status: HistoryItemImageStatus,
183
180
  parameters_hash: Optional[str] = None,
184
- # Pagination
185
- page: int = Query(default=1, ge=1),
186
- page_size: Optional[int] = Query(default=None, ge=1),
187
181
  # Dependencies
182
+ pagination: PaginationRequest = Depends(get_pagination_params),
188
183
  user: UserOAuth = Depends(current_active_user),
189
184
  db: AsyncSession = Depends(get_async_db),
190
- ) -> JSONResponse:
185
+ ) -> PaginationResponse[str]:
191
186
 
192
- if page_size is None and page > 1:
193
- raise HTTPException(
194
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
195
- detail=(f"Invalid pagination parameters: {page=}, {page_size=}."),
196
- )
187
+ page = pagination.page
188
+ page_size = pagination.page_size
197
189
 
198
- wftask = await db.get(WorkflowTaskV2, workflowtask_id)
199
- if wftask is None:
200
- raise HTTPException(
201
- status_code=status.HTTP_404_NOT_FOUND,
202
- detail="WorkflowTask not found",
203
- )
204
- await _get_workflow_task_check_owner(
205
- project_id=project_id,
206
- workflow_id=wftask.workflow_id,
207
- workflow_task_id=workflowtask_id,
190
+ await _get_workflowtask_check_history_owner(
191
+ dataset_id=dataset_id,
192
+ workflowtask_id=workflowtask_id,
208
193
  user_id=user.id,
209
194
  db=db,
210
195
  )
@@ -228,20 +213,82 @@ async def get_per_workflowtask_images(
228
213
  )
229
214
  query = query.where(ImageStatus.parameters_hash == parameters_hash)
230
215
 
216
+ res_total_count = await db.execute(total_count_stm)
217
+ total_count = res_total_count.scalar()
218
+
231
219
  if page_size is not None:
232
220
  query = query.limit(page_size)
221
+ else:
222
+ page_size = total_count
223
+
233
224
  if page > 1:
234
225
  query = query.offset((page - 1) * page_size)
235
226
 
236
- res_total_count = await db.execute(total_count_stm)
237
- total_count = res_total_count.scalar()
238
-
239
227
  res = await db.execute(query)
240
228
  images = res.scalars().all()
241
229
 
242
- return {
243
- "total_count": total_count,
244
- "page_size": page_size,
245
- "current_page": page,
246
- "images": images,
247
- }
230
+ return PaginationResponse[str](
231
+ total_count=total_count,
232
+ page_size=page_size,
233
+ current_page=page,
234
+ items=images,
235
+ )
236
+
237
+
238
+ class ImageLogsRequest(BaseModel):
239
+ workflowtask_id: int
240
+ dataset_id: int
241
+ zarr_url: str
242
+
243
+
244
+ @router.post("/project/{project_id}/status/image-logs/")
245
+ async def get_image_logs(
246
+ project_id: int,
247
+ request_data: ImageLogsRequest,
248
+ user: UserOAuth = Depends(current_active_user),
249
+ db: AsyncSession = Depends(get_async_db),
250
+ ) -> JSONResponse:
251
+
252
+ wftask = await _get_workflowtask_check_history_owner(
253
+ dataset_id=request_data.dataset_id,
254
+ workflowtask_id=request_data.workflowtask_id,
255
+ user_id=user.id,
256
+ db=db,
257
+ )
258
+
259
+ image_status = await db.get(
260
+ ImageStatus,
261
+ (
262
+ request_data.zarr_url,
263
+ request_data.workflowtask_id,
264
+ request_data.dataset_id,
265
+ ),
266
+ )
267
+ if image_status is None:
268
+ raise HTTPException(
269
+ status_code=status.HTTP_404_NOT_FOUND,
270
+ detail="ImageStatus not found",
271
+ )
272
+
273
+ if image_status.logfile is None:
274
+ return JSONResponse(
275
+ content=(
276
+ f"Logs for task '{wftask.task.name}' in dataset "
277
+ f"{request_data.dataset_id} are not yet available."
278
+ )
279
+ )
280
+
281
+ logfile = Path(image_status.logfile)
282
+ if not logfile.exists():
283
+ return JSONResponse(
284
+ content=(
285
+ f"Error while retrieving logs for task '{wftask.task.name}' "
286
+ f"in dataset {request_data.dataset_id}: "
287
+ f"file '{logfile}' is not available."
288
+ )
289
+ )
290
+
291
+ with logfile.open("r") as f:
292
+ file_contents = f.read()
293
+
294
+ return JSONResponse(content=file_contents)
@@ -17,6 +17,9 @@ from fractal_server.app.db import AsyncSession
17
17
  from fractal_server.app.db import get_async_db
18
18
  from fractal_server.app.models import UserOAuth
19
19
  from fractal_server.app.routes.auth import current_active_user
20
+ from fractal_server.app.routes.pagination import get_pagination_params
21
+ from fractal_server.app.routes.pagination import PaginationRequest
22
+ from fractal_server.app.routes.pagination import PaginationResponse
20
23
  from fractal_server.app.schemas._filter_validators import (
21
24
  validate_attribute_filters,
22
25
  )
@@ -31,17 +34,11 @@ from fractal_server.images.tools import match_filter
31
34
  router = APIRouter()
32
35
 
33
36
 
34
- class ImagePage(BaseModel):
35
-
36
- total_count: int
37
- page_size: int
38
- current_page: int
37
+ class ImagePage(PaginationResponse[SingleImage]):
39
38
 
40
39
  attributes: dict[str, list[Any]]
41
40
  types: list[str]
42
41
 
43
- images: list[SingleImage]
44
-
45
42
 
46
43
  class ImageQuery(BaseModel):
47
44
  zarr_url: Optional[str] = None
@@ -118,18 +115,14 @@ async def post_new_image(
118
115
  async def query_dataset_images(
119
116
  project_id: int,
120
117
  dataset_id: int,
121
- page: int = 1, # query param
122
- page_size: Optional[int] = None, # query param
123
- query: Optional[ImageQuery] = None, # body
118
+ query: Optional[ImageQuery] = None,
119
+ pagination: PaginationRequest = Depends(get_pagination_params),
124
120
  user: UserOAuth = Depends(current_active_user),
125
121
  db: AsyncSession = Depends(get_async_db),
126
122
  ) -> ImagePage:
127
123
 
128
- if page < 1:
129
- raise HTTPException(
130
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
131
- detail=f"Invalid pagination parameter: page={page} < 1",
132
- )
124
+ page = pagination.page
125
+ page_size = pagination.page_size
133
126
 
134
127
  output = await _get_dataset_check_owner(
135
128
  project_id=project_id, dataset_id=dataset_id, user_id=user.id, db=db
@@ -177,20 +170,10 @@ async def query_dataset_images(
177
170
 
178
171
  total_count = len(images)
179
172
 
180
- if page_size is not None:
181
- if page_size <= 0:
182
- raise HTTPException(
183
- status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
184
- detail=(
185
- f"Invalid pagination parameter: page_size={page_size} <= 0"
186
- ),
187
- )
188
- else:
173
+ if page_size is None:
189
174
  page_size = total_count
190
175
 
191
- if total_count == 0:
192
- page = 1
193
- else:
176
+ if total_count > 0:
194
177
  last_page = (total_count // page_size) + (total_count % page_size > 0)
195
178
  if page > last_page:
196
179
  page = last_page
@@ -201,9 +184,9 @@ async def query_dataset_images(
201
184
  total_count=total_count,
202
185
  current_page=page,
203
186
  page_size=page_size,
187
+ items=images,
204
188
  attributes=attributes,
205
189
  types=types,
206
- images=images,
207
190
  )
208
191
 
209
192
 
@@ -0,0 +1,47 @@
1
+ from typing import Generic
2
+ from typing import Optional
3
+ from typing import TypeVar
4
+
5
+ from fastapi import HTTPException
6
+ from pydantic import BaseModel
7
+ from pydantic import Field
8
+ from pydantic import model_validator
9
+ from pydantic import ValidationError
10
+
11
+ T = TypeVar("T")
12
+
13
+
14
+ class PaginationRequest(BaseModel):
15
+
16
+ page: int = Field(ge=1)
17
+ page_size: Optional[int] = Field(ge=1)
18
+
19
+ @model_validator(mode="after")
20
+ def valid_pagination_parameters(self):
21
+ if self.page_size is None and self.page > 1:
22
+ raise ValueError(
23
+ f"page_size is None but page={self.page} is greater than 1."
24
+ )
25
+ return self
26
+
27
+
28
+ def get_pagination_params(
29
+ page: int = 1, page_size: Optional[int] = None
30
+ ) -> PaginationRequest:
31
+ try:
32
+ pagination = PaginationRequest(page=page, page_size=page_size)
33
+ except ValidationError as e:
34
+ raise HTTPException(
35
+ status_code=422,
36
+ detail=f"Invalid pagination parameters. Original error: '{e}'.",
37
+ )
38
+ return pagination
39
+
40
+
41
+ class PaginationResponse(BaseModel, Generic[T]):
42
+
43
+ current_page: int = Field(ge=1)
44
+ page_size: int = Field(ge=0)
45
+ total_count: int = Field(ge=0)
46
+
47
+ items: list[T]
fractal_server/config.py CHANGED
@@ -502,14 +502,6 @@ class Settings(BaseSettings):
502
502
  `JobExecutionError`.
503
503
  """
504
504
 
505
- FRACTAL_RUNNER_TASKS_INCLUDE_IMAGE: str = (
506
- "Copy OME-Zarr structure;Convert Metadata Components from 2D to 3D"
507
- )
508
- """
509
- `;`-separated list of names for task that require the `metadata["image"]`
510
- attribute in their input-arguments JSON file.
511
- """
512
-
513
505
  FRACTAL_PIP_CACHE_DIR: Optional[str] = None
514
506
  """
515
507
  Absolute path to the cache directory for `pip`; if unset,
@@ -1,8 +1,8 @@
1
1
  """image status
2
2
 
3
- Revision ID: 8223fcef886c
3
+ Revision ID: 954ddc64425a
4
4
  Revises: 87cd72a537a2
5
- Create Date: 2025-02-24 11:32:22.267338
5
+ Create Date: 2025-02-28 16:37:38.765883
6
6
 
7
7
  """
8
8
  import sqlalchemy as sa
@@ -11,7 +11,7 @@ from alembic import op
11
11
 
12
12
 
13
13
  # revision identifiers, used by Alembic.
14
- revision = "8223fcef886c"
14
+ revision = "954ddc64425a"
15
15
  down_revision = "87cd72a537a2"
16
16
  branch_labels = None
17
17
  depends_on = None
@@ -35,7 +35,7 @@ def upgrade() -> None:
35
35
  "status", sqlmodel.sql.sqltypes.AutoString(), nullable=False
36
36
  ),
37
37
  sa.Column(
38
- "logfile", sqlmodel.sql.sqltypes.AutoString(), nullable=False
38
+ "logfile", sqlmodel.sql.sqltypes.AutoString(), nullable=True
39
39
  ),
40
40
  sa.ForeignKeyConstraint(
41
41
  ["dataset_id"],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fractal-server
3
- Version: 2.14.0a1
3
+ Version: 2.14.0a2
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  Home-page: https://github.com/fractal-analytics-platform/fractal-server
6
6
  License: BSD-3-Clause
@@ -1,4 +1,4 @@
1
- fractal_server/__init__.py,sha256=i6KRQMtGkZNUkj6PkUVE40hBCnPliGm9eHyaj34caWI,25
1
+ fractal_server/__init__.py,sha256=dWQvRQS4d6bb0CHJ35U72icZFcp1aPaXkJMRU7U2UPk,25
2
2
  fractal_server/__main__.py,sha256=igfS2XL3e8JycuhASl2vsYuIPma0MG0cfPPFRuQfh14,6906
3
3
  fractal_server/alembic.ini,sha256=MWwi7GzjzawI9cCAK1LW7NxIBQDUqD12-ptJoq5JpP0,3153
4
4
  fractal_server/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -14,7 +14,7 @@ fractal_server/app/models/user_settings.py,sha256=Y-ZV-uZAFLZqXxy8c5_Qeh_F7zQuZD
14
14
  fractal_server/app/models/v2/__init__.py,sha256=VNoK2OUB8_IPvZoItLOxup84ZMNslO7j30jojNS2lI0,774
15
15
  fractal_server/app/models/v2/accounting.py,sha256=f2ALxfKKBNxFLJTtC2-YqRepVK253x68y7zkD2V_Nls,1115
16
16
  fractal_server/app/models/v2/dataset.py,sha256=O5_6YfNeX6JM7PUcEZhbeV4JCvuAhFCQbOOuefpVnqc,1544
17
- fractal_server/app/models/v2/history.py,sha256=MFr4Z29RLIFSPH5M8GhgDMaXOz4SMAiC1MZmaC4kLk4,1528
17
+ fractal_server/app/models/v2/history.py,sha256=SqD6Va7h7LUzSzf_yz_iTcDQpivxif6hy--Rls_yekw,1538
18
18
  fractal_server/app/models/v2/job.py,sha256=L0P1mrztMqqb-6qdPEbuHXhCsf2mxVUct_ehcXrREGg,1844
19
19
  fractal_server/app/models/v2/project.py,sha256=rAHoh5KfYwIaW7rTX0_O0jvWmxEvfo1BafvmcXuSSRk,786
20
20
  fractal_server/app/models/v2/task.py,sha256=8KEROaadgccXRZIP7EriBp2j1FgzYkgiirOi5_fG79M,1494
@@ -24,7 +24,7 @@ fractal_server/app/models/v2/workflowtask.py,sha256=919L2jCm9y57MXiezGBb28uiXpxy
24
24
  fractal_server/app/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  fractal_server/app/routes/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  fractal_server/app/routes/admin/v2/__init__.py,sha256=_5lqb6-M8-fZqE1HRMep6pAFYRUKMxrvbZOKs-RXWkw,933
27
- fractal_server/app/routes/admin/v2/accounting.py,sha256=ueTGk9748d-gNorqCkkhddgGKzgpWVZQ4G0Loobl7eQ,3788
27
+ fractal_server/app/routes/admin/v2/accounting.py,sha256=UDMPD9DMhMBcu4UsEOEtKMCGnkVMtmwBuRklek-_ShQ,3631
28
28
  fractal_server/app/routes/admin/v2/impersonate.py,sha256=gc4lshfEPFR6W2asH7aKu6hqE6chzusdhAUVV9p51eU,1131
29
29
  fractal_server/app/routes/admin/v2/job.py,sha256=4soc-5d99QEsir7U9AqpofgaGggSBwgMm7mXW5LBvSI,7439
30
30
  fractal_server/app/routes/admin/v2/project.py,sha256=luy-yiGX1JYTdPm1hpIdDUUqPm8xHuipLy9k2X6zu74,1223
@@ -33,12 +33,12 @@ fractal_server/app/routes/admin/v2/task_group.py,sha256=XTjdqgABXZcx9EenaoqSmHh1
33
33
  fractal_server/app/routes/admin/v2/task_group_lifecycle.py,sha256=0e0ZJ_k75TVHaT2o8Xk33DPDSgh-eBhZf-y4y7t-Adg,9429
34
34
  fractal_server/app/routes/api/__init__.py,sha256=2IDheFi0OFdsUg7nbUiyahqybvpgXqeHUXIL2QtWrQQ,641
35
35
  fractal_server/app/routes/api/v2/__init__.py,sha256=S7zOeoLkD6Sss1JLRQxeQWPSXKMX2yaIVhLQUw0PDh0,2176
36
- fractal_server/app/routes/api/v2/_aux_functions.py,sha256=m4gqcOAatwShBmUeiSSF-I_rIRY-bHRSjEfmvnGU0AA,13498
36
+ fractal_server/app/routes/api/v2/_aux_functions.py,sha256=pmYbsHjJexb5-zMCJQLNStmU_95ZfeEIBpoCJx4GFIY,13480
37
37
  fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py,sha256=qdXCb6IP8-qPEAxGZKljtjIqNzIAyRaAsQSRi5VqFHM,6773
38
38
  fractal_server/app/routes/api/v2/_aux_functions_tasks.py,sha256=uhNSs-jcS7ndIUFKiOC1yrDiViw3uvKEXi9UL04BMks,11642
39
39
  fractal_server/app/routes/api/v2/dataset.py,sha256=gS5169eJRGHBQNUnkDB75Bv3Kg8Ql-tMVw5_FAxUEKc,9664
40
- fractal_server/app/routes/api/v2/history.py,sha256=Np2TzTLstOKhrbqTsxak8Z1uvafsrGU2EHIflzgHfXQ,8093
41
- fractal_server/app/routes/api/v2/images.py,sha256=32sSDSWri_A8uQHcdbVTPvGGEjj9vk5ILj8q0-2jLX8,8507
40
+ fractal_server/app/routes/api/v2/history.py,sha256=VTyZA6wAC3Uc-AfaaoQ-RsQdzZKIMkhSX142lwTI1tc,9260
41
+ fractal_server/app/routes/api/v2/images.py,sha256=wUhYomNLGtJTtu_pD2oQorcH2LISxo64Wxo6ogc4IXc,8185
42
42
  fractal_server/app/routes/api/v2/job.py,sha256=m89FTh9Px25oXCeWj2k2NdGWQaO2oxMh-6lZppcsJOY,5551
43
43
  fractal_server/app/routes/api/v2/project.py,sha256=mYTahW8udrfCbnVYrKPX2VPyT3kFjYScE500jZZz8e4,7827
44
44
  fractal_server/app/routes/api/v2/submit.py,sha256=K4OjcSg476JXIeeMUaYdTDk8Qpj5IO5UULvfErI7Y5Y,8624
@@ -63,6 +63,7 @@ fractal_server/app/routes/aux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
63
63
  fractal_server/app/routes/aux/_job.py,sha256=XWyWpOObcV55YyK7uzGRlaslmPDCBZy4hiSZBpoa_bg,616
64
64
  fractal_server/app/routes/aux/_runner.py,sha256=spNudutueHTBJPhm55RlOuYzb31DhyheSjl2rk6dloM,873
65
65
  fractal_server/app/routes/aux/validate_user_settings.py,sha256=FLVi__8YFcm_6c_K5uMQo7raWWXQLBcZtx8yaPO4jaE,2301
66
+ fractal_server/app/routes/pagination.py,sha256=L8F5JqekF39qz-LpeScdlhb57MQnSRXjK4ZEtsZqYLk,1210
66
67
  fractal_server/app/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
68
  fractal_server/app/runner/components.py,sha256=ZF8ct_Ky5k8IAcrmpYOZ-bc6OBgdELEighYVqFDEbZg,119
68
69
  fractal_server/app/runner/compress_folder.py,sha256=HSc1tv7x2DBjBoXwugZlC79rm9GNBIWtQKK9yWn5ZBI,3991
@@ -130,7 +131,7 @@ fractal_server/app/schemas/v2/workflowtask.py,sha256=qMvwlnFCsnyD8uv8HJ4cFy2-QMm
130
131
  fractal_server/app/security/__init__.py,sha256=8dg7vBzLjU43p_eGoHuFBO97FtIDtNnbJJ5mzVSVRNI,14094
131
132
  fractal_server/app/security/signup_email.py,sha256=CR1VbsGFNshxsWquLDZPbUAYnGzkCHeJChtncq63RBc,1434
132
133
  fractal_server/app/user_settings.py,sha256=OP1yiYKtPadxwM51_Q0hdPk3z90TCN4z1BLpQsXyWiU,1316
133
- fractal_server/config.py,sha256=Lc1lgN4J1sTeE5kdWm3b2ltDYtTzyzmuA6ms1T1ZboI,28824
134
+ fractal_server/config.py,sha256=-ZcGmK-3tppIQCD13aKNSiom7u0XQgil_nis37HKjTA,28549
134
135
  fractal_server/data_migrations/README.md,sha256=_3AEFvDg9YkybDqCLlFPdDmGJvr6Tw7HRI14aZ3LOIw,398
135
136
  fractal_server/data_migrations/tools.py,sha256=LeMeASwYGtEqd-3wOLle6WARdTGAimoyMmRbbJl-hAM,572
136
137
  fractal_server/gunicorn_fractal.py,sha256=u6U01TLGlXgq1v8QmEpLih3QnsInZD7CqphgJ_GrGzc,1230
@@ -153,12 +154,12 @@ fractal_server/migrations/versions/50a13d6138fd_initial_schema.py,sha256=zwXegXs
153
154
  fractal_server/migrations/versions/5bf02391cfef_v2.py,sha256=axhNkr_H6R4rRbY7oGYazNbFvPXeSyBDWFVbKNmiqs8,8433
154
155
  fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py,sha256=Q-DsMzG3IcUV2Ol1dhJWosDvKERamBE6QvA2zzS5zpQ,1632
155
156
  fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py,sha256=mbWuCkTpRAdGbRhW7lhXs_e5S6O37UAcCN6JfoY5H8A,1353
156
- fractal_server/migrations/versions/8223fcef886c_image_status.py,sha256=Nhlw22F9w1Obh-Tte6787Fyglb4NuQwdJQeO-HlkqSs,1743
157
157
  fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py,sha256=NSCuhANChsg76vBkShBl-9tQ4VEHubOjtAv1etHhlvY,2684
158
158
  fractal_server/migrations/versions/87cd72a537a2_add_historyitem_table.py,sha256=xxAftQYyQ2C_7qiuPcG5FeVmhFQGznxfCglsfk2CjiU,2092
159
159
  fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py,sha256=68y9-fpSuKx6KPtM_9n8Ho0I1qwa8IoG-yJqXUYQrGg,1111
160
160
  fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py,sha256=6pgODDtyAxevZvAJBj9IJ41inhV1RpwbpZr_qfPPu1A,1115
161
161
  fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py,sha256=yL3-Hvzw5jBLKj4LFP1z5ofZE9L9W3tLwYtPNW7z4ko,1508
162
+ fractal_server/migrations/versions/954ddc64425a_image_status.py,sha256=cPjuGTztDkjvhVQDO8i41qAmG5O2CgKNUfV_PRK9Pck,1742
162
163
  fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py,sha256=eKTZm3EgUgapXBxO0RuHkEfTKic-TZG3ADaMpGLuc0k,1057
163
164
  fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py,sha256=0im6TxDr53sKKcjiPgeH4ftVRGnRXZSh2lPbRQ1Ir9w,883
164
165
  fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py,sha256=syONdZNf4-OnAcWIsbzXpYwpXPsXZ4SsmjwVvmVG0PU,2256
@@ -205,8 +206,8 @@ fractal_server/tasks/v2/utils_templates.py,sha256=07TZpJ0Mh_A4lXVXrrH2o1VLFFGwxe
205
206
  fractal_server/urls.py,sha256=QjIKAC1a46bCdiPMu3AlpgFbcv6a4l3ABcd5xz190Og,471
206
207
  fractal_server/utils.py,sha256=PMwrxWFxRTQRl1b9h-NRIbFGPKqpH_hXnkAT3NfZdpY,3571
207
208
  fractal_server/zip_tools.py,sha256=GjDgo_sf6V_DDg6wWeBlZu5zypIxycn_l257p_YVKGc,4876
208
- fractal_server-2.14.0a1.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
209
- fractal_server-2.14.0a1.dist-info/METADATA,sha256=JUF12zuO6tyA45Y1CCKwxWlMbOYLaiLkTcXDbahCyes,4550
210
- fractal_server-2.14.0a1.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
211
- fractal_server-2.14.0a1.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
212
- fractal_server-2.14.0a1.dist-info/RECORD,,
209
+ fractal_server-2.14.0a2.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
210
+ fractal_server-2.14.0a2.dist-info/METADATA,sha256=t9JaZ6P-FKFHdGcvOagYEK-agbJKuVojh4CiE6pdFRc,4550
211
+ fractal_server-2.14.0a2.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
212
+ fractal_server-2.14.0a2.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
213
+ fractal_server-2.14.0a2.dist-info/RECORD,,