fractal-server 2.11.1__py3-none-any.whl → 2.12.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.
Files changed (61) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/app/models/__init__.py +0 -2
  3. fractal_server/app/models/linkuserproject.py +0 -9
  4. fractal_server/app/routes/aux/_job.py +1 -3
  5. fractal_server/app/runner/filenames.py +0 -2
  6. fractal_server/app/runner/shutdown.py +3 -27
  7. fractal_server/config.py +1 -15
  8. fractal_server/main.py +1 -12
  9. fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +67 -0
  10. fractal_server/string_tools.py +0 -21
  11. fractal_server/tasks/utils.py +0 -24
  12. {fractal_server-2.11.1.dist-info → fractal_server-2.12.0a0.dist-info}/METADATA +1 -1
  13. {fractal_server-2.11.1.dist-info → fractal_server-2.12.0a0.dist-info}/RECORD +16 -60
  14. fractal_server/app/models/v1/__init__.py +0 -13
  15. fractal_server/app/models/v1/dataset.py +0 -71
  16. fractal_server/app/models/v1/job.py +0 -101
  17. fractal_server/app/models/v1/project.py +0 -29
  18. fractal_server/app/models/v1/state.py +0 -34
  19. fractal_server/app/models/v1/task.py +0 -85
  20. fractal_server/app/models/v1/workflow.py +0 -133
  21. fractal_server/app/routes/admin/v1.py +0 -377
  22. fractal_server/app/routes/api/v1/__init__.py +0 -26
  23. fractal_server/app/routes/api/v1/_aux_functions.py +0 -478
  24. fractal_server/app/routes/api/v1/dataset.py +0 -554
  25. fractal_server/app/routes/api/v1/job.py +0 -195
  26. fractal_server/app/routes/api/v1/project.py +0 -475
  27. fractal_server/app/routes/api/v1/task.py +0 -203
  28. fractal_server/app/routes/api/v1/task_collection.py +0 -239
  29. fractal_server/app/routes/api/v1/workflow.py +0 -355
  30. fractal_server/app/routes/api/v1/workflowtask.py +0 -187
  31. fractal_server/app/runner/async_wrap_v1.py +0 -27
  32. fractal_server/app/runner/v1/__init__.py +0 -415
  33. fractal_server/app/runner/v1/_common.py +0 -620
  34. fractal_server/app/runner/v1/_local/__init__.py +0 -186
  35. fractal_server/app/runner/v1/_local/_local_config.py +0 -105
  36. fractal_server/app/runner/v1/_local/_submit_setup.py +0 -48
  37. fractal_server/app/runner/v1/_local/executor.py +0 -100
  38. fractal_server/app/runner/v1/_slurm/__init__.py +0 -312
  39. fractal_server/app/runner/v1/_slurm/_submit_setup.py +0 -81
  40. fractal_server/app/runner/v1/_slurm/get_slurm_config.py +0 -163
  41. fractal_server/app/runner/v1/common.py +0 -117
  42. fractal_server/app/runner/v1/handle_failed_job.py +0 -141
  43. fractal_server/app/schemas/v1/__init__.py +0 -37
  44. fractal_server/app/schemas/v1/applyworkflow.py +0 -161
  45. fractal_server/app/schemas/v1/dataset.py +0 -165
  46. fractal_server/app/schemas/v1/dumps.py +0 -64
  47. fractal_server/app/schemas/v1/manifest.py +0 -126
  48. fractal_server/app/schemas/v1/project.py +0 -66
  49. fractal_server/app/schemas/v1/state.py +0 -18
  50. fractal_server/app/schemas/v1/task.py +0 -167
  51. fractal_server/app/schemas/v1/task_collection.py +0 -110
  52. fractal_server/app/schemas/v1/workflow.py +0 -212
  53. fractal_server/tasks/v1/_TaskCollectPip.py +0 -103
  54. fractal_server/tasks/v1/__init__.py +0 -0
  55. fractal_server/tasks/v1/background_operations.py +0 -352
  56. fractal_server/tasks/v1/endpoint_operations.py +0 -156
  57. fractal_server/tasks/v1/get_collection_data.py +0 -14
  58. fractal_server/tasks/v1/utils.py +0 -67
  59. {fractal_server-2.11.1.dist-info → fractal_server-2.12.0a0.dist-info}/LICENSE +0 -0
  60. {fractal_server-2.11.1.dist-info → fractal_server-2.12.0a0.dist-info}/WHEEL +0 -0
  61. {fractal_server-2.11.1.dist-info → fractal_server-2.12.0a0.dist-info}/entry_points.txt +0 -0
@@ -1 +1 @@
1
- __VERSION__ = "2.11.1"
1
+ __VERSION__ = "2.12.0a0"
@@ -4,9 +4,7 @@ thus we should always export all relevant database models from here or they
4
4
  will not be picked up by alembic.
5
5
  """
6
6
  from .linkusergroup import LinkUserGroup # noqa: F401
7
- from .linkuserproject import LinkUserProject # noqa: F401
8
7
  from .linkuserproject import LinkUserProjectV2 # noqa: F401
9
8
  from .security import * # noqa
10
9
  from .user_settings import UserSettings # noqa
11
- from .v1 import * # noqa
12
10
  from .v2 import * # noqa
@@ -2,15 +2,6 @@ from sqlmodel import Field
2
2
  from sqlmodel import SQLModel
3
3
 
4
4
 
5
- class LinkUserProject(SQLModel, table=True):
6
- """
7
- Crossing table between User and Project
8
- """
9
-
10
- project_id: int = Field(foreign_key="project.id", primary_key=True)
11
- user_id: int = Field(foreign_key="user_oauth.id", primary_key=True)
12
-
13
-
14
5
  class LinkUserProjectV2(SQLModel, table=True):
15
6
  """
16
7
  Crossing table between User and ProjectV2
@@ -1,12 +1,10 @@
1
1
  from pathlib import Path
2
- from typing import Union
3
2
 
4
- from ...models.v1 import ApplyWorkflow
5
3
  from ...models.v2 import JobV2
6
4
  from ...runner.filenames import SHUTDOWN_FILENAME
7
5
 
8
6
 
9
- def _write_shutdown_file(*, job: Union[ApplyWorkflow, JobV2]):
7
+ def _write_shutdown_file(*, job: JobV2):
10
8
  """
11
9
  Write job's shutdown file.
12
10
 
@@ -1,4 +1,2 @@
1
- HISTORY_FILENAME_V1 = "history.json"
2
- METADATA_FILENAME_V1 = "metadata.json"
3
1
  SHUTDOWN_FILENAME = "shutdown"
4
2
  WORKFLOW_LOG_FILENAME = "workflow.log"
@@ -3,8 +3,6 @@ import time
3
3
  from sqlmodel import select
4
4
 
5
5
  from fractal_server.app.db import get_async_db
6
- from fractal_server.app.models.v1 import ApplyWorkflow
7
- from fractal_server.app.models.v1.job import JobStatusTypeV1
8
6
  from fractal_server.app.models.v2 import JobV2
9
7
  from fractal_server.app.models.v2.job import JobStatusTypeV2
10
8
  from fractal_server.app.routes.aux._job import _write_shutdown_file
@@ -13,9 +11,7 @@ from fractal_server.logger import get_logger
13
11
  from fractal_server.syringe import Inject
14
12
 
15
13
 
16
- async def cleanup_after_shutdown(
17
- *, jobsV1: list[int], jobsV2: list[int], logger_name: str
18
- ):
14
+ async def cleanup_after_shutdown(*, jobsV2: list[int], logger_name: str):
19
15
  logger = get_logger(logger_name)
20
16
  logger.info("Cleanup function after shutdown")
21
17
  stm_v2 = (
@@ -24,22 +20,12 @@ async def cleanup_after_shutdown(
24
20
  .where(JobV2.status == JobStatusTypeV2.SUBMITTED)
25
21
  )
26
22
 
27
- stm_v1 = (
28
- select(ApplyWorkflow)
29
- .where(ApplyWorkflow.id.in_(jobsV1))
30
- .where(ApplyWorkflow.status == JobStatusTypeV1.SUBMITTED)
31
- )
32
-
33
23
  async for session in get_async_db():
34
24
  jobsV2_db = (await session.execute(stm_v2)).scalars().all()
35
- jobsV1_db = (await session.execute(stm_v1)).scalars().all()
36
25
 
37
26
  for job in jobsV2_db:
38
27
  _write_shutdown_file(job=job)
39
28
 
40
- for job in jobsV1_db:
41
- _write_shutdown_file(job=job)
42
-
43
29
  settings = Inject(get_settings)
44
30
 
45
31
  t_start = time.perf_counter()
@@ -49,9 +35,8 @@ async def cleanup_after_shutdown(
49
35
  logger.info("Waiting 3 seconds before checking")
50
36
  time.sleep(3)
51
37
  jobsV2_db = (await session.execute(stm_v2)).scalars().all()
52
- jobsV1_db = (await session.execute(stm_v1)).scalars().all()
53
38
 
54
- if len(jobsV2_db) == 0 and len(jobsV1_db) == 0:
39
+ if len(jobsV2_db) == 0:
55
40
  logger.info(
56
41
  (
57
42
  "All jobs associated to this app are "
@@ -61,10 +46,7 @@ async def cleanup_after_shutdown(
61
46
  return
62
47
  else:
63
48
  logger.info(
64
- (
65
- f"Some jobs are still 'submitted' "
66
- f"{jobsV1_db=}, {jobsV2_db=}"
67
- )
49
+ (f"Some jobs are still 'submitted' " f"{jobsV2_db=}")
68
50
  )
69
51
  logger.info(
70
52
  (
@@ -79,10 +61,4 @@ async def cleanup_after_shutdown(
79
61
  session.add(job)
80
62
  await session.commit()
81
63
 
82
- for job in jobsV1_db:
83
- job.status = "failed"
84
- job.log = (job.log or "") + "\nJob stopped due to app shutdown\n"
85
- session.add(job)
86
- await session.commit()
87
-
88
64
  logger.info("Exit from shutdown logic")
fractal_server/config.py CHANGED
@@ -338,7 +338,7 @@ class Settings(BaseSettings):
338
338
 
339
339
  FRACTAL_API_MAX_JOB_LIST_LENGTH: int = 50
340
340
  """
341
- Number of ids that can be stored in the `jobsV1` and `jobsV2` attributes of
341
+ Number of ids that can be stored in the `jobsV2` attribute of
342
342
  `app.state`.
343
343
  """
344
344
 
@@ -496,13 +496,6 @@ class Settings(BaseSettings):
496
496
  `JobExecutionError`.
497
497
  """
498
498
 
499
- FRACTAL_API_SUBMIT_RATE_LIMIT: int = 2
500
- """
501
- Interval to wait (in seconds) to be allowed to call again
502
- `POST api/v1/{project_id}/workflow/{workflow_id}/apply/`
503
- with the same path and query parameters.
504
- """
505
-
506
499
  FRACTAL_RUNNER_TASKS_INCLUDE_IMAGE: str = (
507
500
  "Copy OME-Zarr structure;Convert Metadata Components from 2D to 3D"
508
501
  )
@@ -511,13 +504,6 @@ class Settings(BaseSettings):
511
504
  attribute in their input-arguments JSON file.
512
505
  """
513
506
 
514
- FRACTAL_API_V1_MODE: Literal[
515
- "include", "include_read_only", "exclude"
516
- ] = "include"
517
- """
518
- Whether to include the v1 API.
519
- """
520
-
521
507
  FRACTAL_PIP_CACHE_DIR: Optional[str] = None
522
508
  """
523
509
  Absolute path to the cache directory for `pip`; if unset,
fractal_server/main.py CHANGED
@@ -39,20 +39,11 @@ def collect_routers(app: FastAPI) -> None:
39
39
  The application to register the routers to.
40
40
  """
41
41
  from .app.routes.api import router_api
42
- from .app.routes.api.v1 import router_api_v1
43
42
  from .app.routes.api.v2 import router_api_v2
44
- from .app.routes.admin.v1 import router_admin_v1
45
43
  from .app.routes.admin.v2 import router_admin_v2
46
44
  from .app.routes.auth.router import router_auth
47
45
 
48
- settings = Inject(get_settings)
49
-
50
46
  app.include_router(router_api, prefix="/api")
51
- if settings.FRACTAL_API_V1_MODE.startswith("include"):
52
- app.include_router(router_api_v1, prefix="/api/v1")
53
- app.include_router(
54
- router_admin_v1, prefix="/admin/v1", tags=["V1 Admin area"]
55
- )
56
47
  app.include_router(router_api_v2, prefix="/api/v2")
57
48
  app.include_router(
58
49
  router_admin_v2, prefix="/admin/v2", tags=["V2 Admin area"]
@@ -84,7 +75,6 @@ def check_settings() -> None:
84
75
 
85
76
  @asynccontextmanager
86
77
  async def lifespan(app: FastAPI):
87
- app.state.jobsV1 = []
88
78
  app.state.jobsV2 = []
89
79
  logger = set_logger("fractal_server.lifespan")
90
80
  logger.info("Start application startup")
@@ -123,12 +113,11 @@ async def lifespan(app: FastAPI):
123
113
 
124
114
  logger.info(
125
115
  f"Current worker with pid {os.getpid()} is shutting down. "
126
- f"Current jobs: {app.state.jobsV1=}, {app.state.jobsV2=}"
116
+ f"Current jobs: {app.state.jobsV2=}"
127
117
  )
128
118
  if _backend_supports_shutdown(settings.FRACTAL_RUNNER_BACKEND):
129
119
  try:
130
120
  await cleanup_after_shutdown(
131
- jobsV1=app.state.jobsV1,
132
121
  jobsV2=app.state.jobsV2,
133
122
  logger_name="fractal_server.lifespan",
134
123
  )
@@ -0,0 +1,67 @@
1
+ """Drop V1 tables
2
+
3
+ Revision ID: 1eac13a26c83
4
+ Revises: af8673379a5c
5
+ Create Date: 2025-01-10 13:17:47.838607
6
+
7
+ """
8
+ import logging
9
+
10
+ from alembic import op
11
+ from sqlmodel import SQLModel
12
+
13
+ from fractal_server.migrations.naming_convention import NAMING_CONVENTION
14
+
15
+ # revision identifiers, used by Alembic.
16
+ revision = "1eac13a26c83"
17
+ down_revision = "af8673379a5c"
18
+ branch_labels = None
19
+ depends_on = None
20
+
21
+
22
+ TABLES_V1 = [
23
+ "resource",
24
+ "applyworkflow",
25
+ "task",
26
+ "workflow",
27
+ "workflowtask",
28
+ "linkuserproject",
29
+ "dataset",
30
+ "project",
31
+ "state",
32
+ ]
33
+
34
+
35
+ def upgrade() -> None:
36
+
37
+ logger = logging.getLogger("alembic.runtime.migration")
38
+
39
+ target_metadata = SQLModel.metadata
40
+ target_metadata.naming_convention = NAMING_CONVENTION
41
+
42
+ connection = op.get_bind()
43
+ target_metadata.reflect(
44
+ bind=connection,
45
+ extend_existing=True,
46
+ only=TABLES_V1,
47
+ )
48
+
49
+ logger.info("Starting non-reversible upgrade")
50
+ logger.info("Dropping all V1 ForeignKey constraints")
51
+ fk_names = []
52
+ for table_name in TABLES_V1:
53
+ table = target_metadata.tables[table_name]
54
+ for fk in table.foreign_keys:
55
+ op.drop_constraint(fk.name, table_name, type_="foreignkey")
56
+ fk_names.append(fk.name)
57
+ logger.info(f"Dropped all V1 ForeignKey constraints: {fk_names}")
58
+ logger.info(f"Dropping all V1 tables: {TABLES_V1}")
59
+ for table_name in TABLES_V1:
60
+ op.drop_table(table_name)
61
+
62
+
63
+ def downgrade() -> None:
64
+ raise RuntimeError(
65
+ "Cannot downgrade from 1eac13a26c83 to db09233ad13a, "
66
+ "because it's fully breaking."
67
+ )
@@ -33,27 +33,6 @@ def sanitize_string(value: str) -> str:
33
33
  return new_value
34
34
 
35
35
 
36
- def slugify_task_name_for_source_v1(task_name: str) -> str:
37
- """
38
- NOTE: this function is used upon creation of tasks' sources, therefore
39
- for the moment we cannot replace it with its more comprehensive version
40
- from `fractal_server.string_tools.sanitize_string`, nor we can remove it.
41
-
42
- As of 2.3.1, we are renaming it to `slugify_task_name_for_source`, to make
43
- it clear that it should not be used for other purposes.
44
-
45
- As of 2.7.0, we are renaming it to `slugify_task_name_for_source_v1`, to
46
- make it clear that it is not used for v2.
47
-
48
- Args:
49
- task_name:
50
-
51
- Return:
52
- Slug-ified task name.
53
- """
54
- return task_name.replace(" ", "_").lower()
55
-
56
-
57
36
  def validate_cmd(
58
37
  command: str,
59
38
  *,
@@ -1,7 +1,5 @@
1
1
  from pathlib import Path
2
2
 
3
- from fractal_server.config import get_settings
4
- from fractal_server.syringe import Inject
5
3
 
6
4
  COLLECTION_FILENAME = "collection.json"
7
5
  COLLECTION_LOG_FILENAME = "collection.log"
@@ -9,31 +7,9 @@ COLLECTION_FREEZE_FILENAME = "collection_freeze.txt"
9
7
  FORBIDDEN_DEPENDENCY_STRINGS = ["github.com"]
10
8
 
11
9
 
12
- def get_absolute_venv_path_v1(venv_path: Path) -> Path:
13
- """
14
- If a path is not absolute, make it a relative path of FRACTAL_TASKS_DIR.
15
-
16
- As of v2.7.0, we rename this to v1 since it is only to be used in v1.
17
- """
18
- if venv_path.is_absolute():
19
- package_path = venv_path
20
- else:
21
- settings = Inject(get_settings)
22
- package_path = settings.FRACTAL_TASKS_DIR / venv_path
23
- return package_path
24
-
25
-
26
10
  def get_collection_path(base: Path) -> Path:
27
11
  return base / COLLECTION_FILENAME
28
12
 
29
13
 
30
14
  def get_log_path(base: Path) -> Path:
31
15
  return base / COLLECTION_LOG_FILENAME
32
-
33
-
34
- def get_collection_log_v1(path: Path) -> str:
35
- package_path = get_absolute_venv_path_v1(path)
36
- log_path = get_log_path(package_path)
37
- with log_path.open("r") as f:
38
- log = f.read()
39
- return log
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fractal-server
3
- Version: 2.11.1
3
+ Version: 2.12.0a0
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,20 +1,13 @@
1
- fractal_server/__init__.py,sha256=IDMsn_8tp36mX2SfY8u--GT2UfFEEyrK2bOGt3Pg-e0,23
1
+ fractal_server/__init__.py,sha256=Wn8eJa03y-IsDDGndomL0oqMXnAho6QTuQcpQidSwcA,25
2
2
  fractal_server/__main__.py,sha256=D2YTmSowmXNyvqOjW_HeItCZT2UliWlySl_owicaZg0,8026
3
3
  fractal_server/alembic.ini,sha256=MWwi7GzjzawI9cCAK1LW7NxIBQDUqD12-ptJoq5JpP0,3153
4
4
  fractal_server/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  fractal_server/app/db/__init__.py,sha256=wup2wcOkyOh8Vd0Xm76PZn_naxeMqaL4eF8DHHXTGlI,2889
6
- fractal_server/app/models/__init__.py,sha256=aG7mf1zZbsgzDSp7GHEcZhdjHfW3TGPOLCI8MrvYhPw,500
6
+ fractal_server/app/models/__init__.py,sha256=xJWiGAwpXmCpnFMC4c_HTqoUCzMOXrakoGLUH_uMvdA,415
7
7
  fractal_server/app/models/linkusergroup.py,sha256=LWTUfhH2uAnn_4moK7QdRUIHWtpw-hPZuW-5jClv_OE,610
8
- fractal_server/app/models/linkuserproject.py,sha256=eQaourbGRshvlMVlKzLYJKHEjfsW1CbWws9yW4eHXhA,567
8
+ fractal_server/app/models/linkuserproject.py,sha256=hvaxh3Lkiy2uUCwB8gvn8RorCpvxSSdzWdCS_U1GL7g,315
9
9
  fractal_server/app/models/security.py,sha256=kLvarGwG1CxvtbpV2HkkOobzHU5Ia0PHyNzHghKSEx4,3751
10
10
  fractal_server/app/models/user_settings.py,sha256=Y-ZV-uZAFLZqXxy8c5_Qeh_F7zQuZDWOgLpU6Zs6iqU,1316
11
- fractal_server/app/models/v1/__init__.py,sha256=hUI7dEbPaiZGN0IbHW4RSmSicyvtn_xeuevoX7zvUwI,466
12
- fractal_server/app/models/v1/dataset.py,sha256=99GDgt7njx8yYQApkImqp_7bHA5HH3ElvbR6Oyj9kVI,2017
13
- fractal_server/app/models/v1/job.py,sha256=QLGXcWdVRHaUHQNDapYYlLpEfw4K7QyD8TmcwhrWw2o,3304
14
- fractal_server/app/models/v1/project.py,sha256=JG7b5J9CzVNxua4MaMYpfB57xt2qjbXr5SnR7_oKQ70,819
15
- fractal_server/app/models/v1/state.py,sha256=m9gMZqqnm3oDpJNJp-Lht4kM7oO7pcEI7sL1g7LFvWU,1043
16
- fractal_server/app/models/v1/task.py,sha256=uFXam7eu3Ye1Yt7_g7llCzY8BetmDRilsq5hR2C1Zbg,2640
17
- fractal_server/app/models/v1/workflow.py,sha256=dnY5eMaOe3oZv8arn00RNX9qVkBtTLG-vYdWXcQuyo4,3950
18
11
  fractal_server/app/models/v2/__init__.py,sha256=63THGEZQlxWcosGCI74SEvJU7wOoOn1j1byTjf4NFOI,526
19
12
  fractal_server/app/models/v2/dataset.py,sha256=RuqTHXWEgs4A3OSk8Pq9DTq9Xr7w1IJNnyXhOzrDiR0,1509
20
13
  fractal_server/app/models/v2/job.py,sha256=BMmu5oXdZvN7jEIAMZvQMB3PQBcCYzxn6Qm6HdRWre4,1725
@@ -25,7 +18,6 @@ fractal_server/app/models/v2/workflow.py,sha256=YBgFGCziUgU0aJ5EM3Svu9W2c46AewZO
25
18
  fractal_server/app/models/v2/workflowtask.py,sha256=sBnKiEx9KqhprUaZVY6R8lyfCdwRaX8obYm6bXdn6_E,1119
26
19
  fractal_server/app/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
20
  fractal_server/app/routes/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- fractal_server/app/routes/admin/v1.py,sha256=ggJZMeKhRijfVe2h2VzfIcpR15FqkKImANhkTXl0mSk,12908
29
21
  fractal_server/app/routes/admin/v2/__init__.py,sha256=KYrw0COmmMuIMp7c6YcYRXah4tEYplCWeROnPK1VTeg,681
30
22
  fractal_server/app/routes/admin/v2/job.py,sha256=cbkFIRIIXaWmNsUFI7RAu8HpQ0mWn_bgoxtvWZxr-IA,7624
31
23
  fractal_server/app/routes/admin/v2/project.py,sha256=luy-yiGX1JYTdPm1hpIdDUUqPm8xHuipLy9k2X6zu74,1223
@@ -33,15 +25,6 @@ fractal_server/app/routes/admin/v2/task.py,sha256=gShC2EAOYa0qTB69EXTDXz5Y375Qoa
33
25
  fractal_server/app/routes/admin/v2/task_group.py,sha256=DncrOAB4q-v3BAmxg35m4EohleriW_FLGE5gpW_Or08,8120
34
26
  fractal_server/app/routes/admin/v2/task_group_lifecycle.py,sha256=0e0ZJ_k75TVHaT2o8Xk33DPDSgh-eBhZf-y4y7t-Adg,9429
35
27
  fractal_server/app/routes/api/__init__.py,sha256=2IDheFi0OFdsUg7nbUiyahqybvpgXqeHUXIL2QtWrQQ,641
36
- fractal_server/app/routes/api/v1/__init__.py,sha256=Y2HQdG197J0a7DyQEE2jn53IfxD0EHGhzK1I2JZuEck,958
37
- fractal_server/app/routes/api/v1/_aux_functions.py,sha256=P9Q48thGH95w0h5cacYoibxqgiiLW4oqZ8rNJ2LIISY,13219
38
- fractal_server/app/routes/api/v1/dataset.py,sha256=7P2VugyaHDhAhUK2EUDksj7O2SgSxRsR7dMDMQB_dPI,17288
39
- fractal_server/app/routes/api/v1/job.py,sha256=0jGxvu0xNQnWuov2qnoo9yE7Oat37XbcVn4Ute-UsiE,5370
40
- fractal_server/app/routes/api/v1/project.py,sha256=3NsdNXLIsE8QiNgKP1Kp1-B0zYG0Zi5HKBzWA0LjlQg,15551
41
- fractal_server/app/routes/api/v1/task.py,sha256=eW89nMCjpD4G6tHXDo2qGBKqWaPirjH6M3hpdJQhfa0,6528
42
- fractal_server/app/routes/api/v1/task_collection.py,sha256=5EMh3yhS1Z4x25kp5Iaxalrf7RgJh-XD1nBjrFvgwsg,9072
43
- fractal_server/app/routes/api/v1/workflow.py,sha256=2T93DuEnSshaDCue-JPmjuvGCtbk6lt9pFMuPt783t8,11217
44
- fractal_server/app/routes/api/v1/workflowtask.py,sha256=OYYConwJbmNULDw5I3T-UbSJKrbbBiAHbbBeVcpoFKQ,5785
45
28
  fractal_server/app/routes/api/v2/__init__.py,sha256=w4c9WzagaVV5d4TWBX5buu5ENk8jf3YftMQYmhavz9Q,2172
46
29
  fractal_server/app/routes/api/v2/_aux_functions.py,sha256=NJ6_1biN_hhIEK1w8Vj6XhLmdkQ5kMVd_MX5JC_nHLU,11524
47
30
  fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py,sha256=c8eqPXdMhc3nIixX50B1Ka5n7LgbOZm2JbEs7lICQ04,6767
@@ -70,11 +53,10 @@ fractal_server/app/routes/auth/register.py,sha256=DlHq79iOvGd_gt2v9uwtsqIKeO6i_G
70
53
  fractal_server/app/routes/auth/router.py,sha256=tzJrygXFZlmV_uWelVqTOJMEH-3Fr7ydwlgx1LxRjxY,527
71
54
  fractal_server/app/routes/auth/users.py,sha256=kZv-Ls224WBFiuvVeM584LhYq_BLz6HQ9HpWbWQxRRM,7808
72
55
  fractal_server/app/routes/aux/__init__.py,sha256=LR4bR7RunHAK6jc9IR2bReQd-BdXADdnDccXI4uGeGY,731
73
- fractal_server/app/routes/aux/_job.py,sha256=q-RCiW17yXnZKAC_0La52RLvhqhxuvbgQJ2MlGXOj8A,702
56
+ fractal_server/app/routes/aux/_job.py,sha256=XWyWpOObcV55YyK7uzGRlaslmPDCBZy4hiSZBpoa_bg,616
74
57
  fractal_server/app/routes/aux/_runner.py,sha256=FdCVla5DxGAZ__aB7Z8dEJzD_RIeh5tftjrPyqkr8N8,895
75
58
  fractal_server/app/routes/aux/validate_user_settings.py,sha256=Y8eubau0julkwVYB5nA83nDtxh_7RU9Iq0zAhb_dXLA,2351
76
59
  fractal_server/app/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
- fractal_server/app/runner/async_wrap_v1.py,sha256=g3opE96OsW-kL_YJVCRFOyHISJt8gQwtUnfJzdZPCOQ,832
78
60
  fractal_server/app/runner/components.py,sha256=ZF8ct_Ky5k8IAcrmpYOZ-bc6OBgdELEighYVqFDEbZg,119
79
61
  fractal_server/app/runner/compress_folder.py,sha256=HSc1tv7x2DBjBoXwugZlC79rm9GNBIWtQKK9yWn5ZBI,3991
80
62
  fractal_server/app/runner/exceptions.py,sha256=_qZ_t8O4umAdJ1ikockiF5rDJuxnEskrGrLjZcnQl7A,4159
@@ -94,22 +76,11 @@ fractal_server/app/runner/executors/slurm/sudo/_subprocess_run_as_user.py,sha256
94
76
  fractal_server/app/runner/executors/slurm/sudo/executor.py,sha256=FVgx2mxqCLOhSoH3UTAeNc0BT0eJaxHMglGzGYePGPM,47439
95
77
  fractal_server/app/runner/executors/slurm/utils_executors.py,sha256=naPyJI0I3lD-sYHbSXbMFGUBK4h_SggA5V91Z1Ch1Xg,1416
96
78
  fractal_server/app/runner/extract_archive.py,sha256=tLpjDrX47OjTNhhoWvm6iNukg8KoieWyTb7ZfvE9eWU,2483
97
- fractal_server/app/runner/filenames.py,sha256=h4iOHD5z_f1y-bFJL-FXAws7k7SwmBmCr8y28m-EGcY,146
79
+ fractal_server/app/runner/filenames.py,sha256=lPnxKHtdRizr6FqG3zOdjDPyWA7GoaJGTtiuJV0gA8E,70
98
80
  fractal_server/app/runner/run_subprocess.py,sha256=c3JbYXq3hX2aaflQU19qJ5Xs6J6oXGNvnTEoAfv2bxc,959
99
81
  fractal_server/app/runner/set_start_and_last_task_index.py,sha256=-q4zVybAj8ek2XlbENKlfOAJ39hT_zoJoZkqzDqiAMY,1254
100
- fractal_server/app/runner/shutdown.py,sha256=I_o2iYKJwzku0L3E85ETjrve3QPECygR5xhhsAo5huM,2910
82
+ fractal_server/app/runner/shutdown.py,sha256=9pfSKHDNdIcm0eY-opgRTi7y0HmvfPmYiu9JR6Idark,2082
101
83
  fractal_server/app/runner/task_files.py,sha256=sd_MpJ01C8c9QTO8GzGMidFGdlq_hXX_ARDRhd_YMnI,3762
102
- fractal_server/app/runner/v1/__init__.py,sha256=VvJFk4agX2X3fQfDcoNmOB2ouNCaQU7dAqaFmpcdP8I,15063
103
- fractal_server/app/runner/v1/_common.py,sha256=MALqlDwvvniBT_z2cuyEHdiOmzSp9lH4BEGGitFggAQ,21561
104
- fractal_server/app/runner/v1/_local/__init__.py,sha256=4u5RWwSDlNnhPC4ZRP7OAW8_UVt7K27fHByoFf37ne4,6938
105
- fractal_server/app/runner/v1/_local/_local_config.py,sha256=hM7SPxR07luXPcXdrWXRpEB2uOyjSSRUdqW3QBKJn9c,3147
106
- fractal_server/app/runner/v1/_local/_submit_setup.py,sha256=XyBDPb4IYdKEEnzLYdcYteIHWVWofJxKMmQCyRkn5Bc,1509
107
- fractal_server/app/runner/v1/_local/executor.py,sha256=QrJlD77G6q4WohoJQO7XXbvi2RlCUsNvMnPDEZIoAqA,3620
108
- fractal_server/app/runner/v1/_slurm/__init__.py,sha256=SsImgL8Agb2Qy98IY8S6N0ZIiXMpZ-eHvFHl7Hlb5tE,10955
109
- fractal_server/app/runner/v1/_slurm/_submit_setup.py,sha256=KO9c694d318adoPQh9UGwxLkw4fRIgybQ5h7QHQKLXQ,2828
110
- fractal_server/app/runner/v1/_slurm/get_slurm_config.py,sha256=6pQNNx997bLIfLp0guF09t_O0ZYRXnbEGLktSAcKnic,5999
111
- fractal_server/app/runner/v1/common.py,sha256=_L-vjLnWato80VdlB_BFN4G8P4jSM07u-5cnl1T3S34,3294
112
- fractal_server/app/runner/v1/handle_failed_job.py,sha256=R8IsM_ucX0_lqFCly8BYuzf-VAVafE5wj_1JXapnxeQ,4696
113
84
  fractal_server/app/runner/v2/__init__.py,sha256=1V4uocFaZQAQ1f01UEV8XjXo_9gNjiWgchsHfsm_TZM,15229
114
85
  fractal_server/app/runner/v2/_local/__init__.py,sha256=QnQ9jfqpzShzjp6H7rfVx9Sqp03J1JB6fCpwNx2MDOw,5119
115
86
  fractal_server/app/runner/v2/_local/_local_config.py,sha256=9oi209Dlp35ANfxb_DISqmMKKc6DPaMsmYVWbZLseME,3630
@@ -139,16 +110,6 @@ fractal_server/app/schemas/_validators.py,sha256=3dotVxUHWKAmUO3aeoluYDLRKrw1OS-
139
110
  fractal_server/app/schemas/user.py,sha256=icjox9gK_invW44Nh_L4CvqfRa92qghyQhmevyg09nQ,2243
140
111
  fractal_server/app/schemas/user_group.py,sha256=t30Kd07PY43G_AqFDb8vjdInTeLeU9WvFZDx8fVLPSI,1750
141
112
  fractal_server/app/schemas/user_settings.py,sha256=re7ZFS8BLjR9MdIoZNRt2DNPc7znCgDpEYFKr8ZsAZg,2980
142
- fractal_server/app/schemas/v1/__init__.py,sha256=CrBGgBhoemCvmZ70ZUchM-jfVAICnoa7AjZBAtL2UB0,1852
143
- fractal_server/app/schemas/v1/applyworkflow.py,sha256=dYArxQAOBdUIEXX_Ejz8b9fBhEYu1nMm6b_Z6_P6TgA,4052
144
- fractal_server/app/schemas/v1/dataset.py,sha256=DWFCxZjApcKt2M6UJMK0tmejXwUT09vjUULf2D7Y-f0,3293
145
- fractal_server/app/schemas/v1/dumps.py,sha256=67VXnyLh_0Ufo7rPM2jZ9P9rk0CnYcVAkilx_cLX6sg,1274
146
- fractal_server/app/schemas/v1/manifest.py,sha256=Yht7guhs0Pcl2U0RMOCbI_UHBZ9YO_YU0H8hxACx3TY,3829
147
- fractal_server/app/schemas/v1/project.py,sha256=Zxd-AguQQG9z2CfJ_sJh5SB9WcHPFbWpLgP_AhjOyZs,1067
148
- fractal_server/app/schemas/v1/state.py,sha256=tBXzp_qW2TNNNPBo-AWEaffEU-1GkMBtUoaMgiN_EL0,302
149
- fractal_server/app/schemas/v1/task.py,sha256=7BxOZ_qoRQ8n3YbQpDvB7VMcxB5fSYQmR5RLIWhuJ5U,3704
150
- fractal_server/app/schemas/v1/task_collection.py,sha256=uvq9bcMaGD_qHsh7YtcpoSAkVAbw12eY4DocIO3MKOg,3057
151
- fractal_server/app/schemas/v1/workflow.py,sha256=oRKamLSuAgrTcv3gMMxGcotDloLL2c3NNgPA39UEmmM,4467
152
113
  fractal_server/app/schemas/v2/__init__.py,sha256=IT2a6fbRx3rt8h6jri_4gZWzTN9EVXewiWoIuBcZ-xA,2618
153
114
  fractal_server/app/schemas/v2/dataset.py,sha256=FKzQyMBAdFo9hnR4HzXQML7VbkM8YlKE4OLKjpo-Pdw,5085
154
115
  fractal_server/app/schemas/v2/dumps.py,sha256=Yiyma6pMnEk1c-Ekf0e-IWgM20_R4qWyHuoqfdc6brE,1635
@@ -164,7 +125,7 @@ fractal_server/app/schemas/v2/workflowtask.py,sha256=xjFTmnKuHSetJvN-9k_GTMbPKwP
164
125
  fractal_server/app/security/__init__.py,sha256=qn6idYgl-p5HWea0gTVnz4JnkoxGEkmQjPzvKpDWT0I,14035
165
126
  fractal_server/app/security/signup_email.py,sha256=DrL51UdTSrgjleynMD5CRZwTSOpPrZ96fasRV0fvxDE,1165
166
127
  fractal_server/app/user_settings.py,sha256=OP1yiYKtPadxwM51_Q0hdPk3z90TCN4z1BLpQsXyWiU,1316
167
- fractal_server/config.py,sha256=9rAzw7OO6ZeHEz-I8NJHuGoHf4xCHxfFLyRNZQD9ytY,27019
128
+ fractal_server/config.py,sha256=fIXjjdczTSBuPphQT6FukE3AwhdfIupsbmR38j3HZ_U,26623
168
129
  fractal_server/data_migrations/README.md,sha256=_3AEFvDg9YkybDqCLlFPdDmGJvr6Tw7HRI14aZ3LOIw,398
169
130
  fractal_server/data_migrations/tools.py,sha256=LeMeASwYGtEqd-3wOLle6WARdTGAimoyMmRbbJl-hAM,572
170
131
  fractal_server/gunicorn_fractal.py,sha256=u6U01TLGlXgq1v8QmEpLih3QnsInZD7CqphgJ_GrGzc,1230
@@ -172,12 +133,13 @@ fractal_server/images/__init__.py,sha256=-_wjoKtSX02P1KjDxDP_EXKvmbONTRmbf7iGVTs
172
133
  fractal_server/images/models.py,sha256=t4zcUFmWxhAzGgy7kkxs9Ctq8SAhVs0v910UcXcHIUw,3349
173
134
  fractal_server/images/tools.py,sha256=4kfPAFJJnvg7fM-cL0JMx97Dc1Npva_0ghitEji3JUU,3407
174
135
  fractal_server/logger.py,sha256=5Z3rfsFwl8UysVljTOaaIvt8Pyp6CVH492ez3jE8WAw,5113
175
- fractal_server/main.py,sha256=gStLT9Du5QMpc9SyvRvtKU21EKwp-dG4HL3zGHzE06A,4908
136
+ fractal_server/main.py,sha256=1ZesKY3-ML8BVmVRg_r_aNWoaSea1uR3GP0DlunpE5U,4452
176
137
  fractal_server/migrations/env.py,sha256=9t_OeKVlhM8WRcukmTrLbWNup-imiBGP_9xNgwCbtpI,2730
177
138
  fractal_server/migrations/naming_convention.py,sha256=htbKrVdetx3pklowb_9Cdo5RqeF0fJ740DNecY5de_M,265
178
139
  fractal_server/migrations/versions/034a469ec2eb_task_groups.py,sha256=vrPhC8hfFu1c4HmLHNZyCuqEfecFD8-bWc49bXMNes0,6199
179
140
  fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py,sha256=-BSS9AFTPcu3gYC-sYbawSy4MWQQx8TfMb5BW5EBKmQ,1450
180
141
  fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py,sha256=Q1Gj1cJ0UrdLBJ5AXfFK9QpxTtmcv-4Z3NEGDnxOme4,961
142
+ fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py,sha256=ok8dl4IkI-dfsyE_NZ8IndjQrnQ_g6CDZo4PwozpIwE,1605
181
143
  fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py,sha256=lANgTox0rz459_yo1Rw7fGCT1qw5sUCUXTLUMc_Bzf8,911
182
144
  fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py,sha256=-wHe-fOffmYeAm0JXVl_lxZ7hhDkaEVqxgxpHkb_uL8,954
183
145
  fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py,sha256=Mob8McGYAcmgvrseyyYOa54E6Gsgr-4SiGdC-r9O4_A,1157
@@ -206,16 +168,10 @@ fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.p
206
168
  fractal_server/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
207
169
  fractal_server/ssh/__init__.py,sha256=sVUmzxf7_DuXG1xoLQ1_00fo5NPhi2LJipSmU5EAkPs,124
208
170
  fractal_server/ssh/_fabric.py,sha256=lNy4IX1I4We6VoWa4Bz4fUPuApLMSoejpyE6I3jDZeM,22869
209
- fractal_server/string_tools.py,sha256=XtMNsr5R7GmgzmFi68zkKMedHs8vjGoVMMCXqWhIk9k,2568
171
+ fractal_server/string_tools.py,sha256=niViRrrZAOo0y6pEFI9L_eUYS1PoOiQZUBtngiLc2_k,1877
210
172
  fractal_server/syringe.py,sha256=3qSMW3YaMKKnLdgnooAINOPxnCOxP7y2jeAQYB21Gdo,2786
211
173
  fractal_server/tasks/__init__.py,sha256=kadmVUoIghl8s190_Tt-8f-WBqMi8u8oU4Pvw39NHE8,23
212
- fractal_server/tasks/utils.py,sha256=gA9nYAviWKAMJmaF5RtoT2InddU6dCT2qA6fZTYNGO4,1105
213
- fractal_server/tasks/v1/_TaskCollectPip.py,sha256=ARq5AoHYXH0hziEsb-nFAqbsLA-VIddXOdXL38O6_zA,3746
214
- fractal_server/tasks/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
215
- fractal_server/tasks/v1/background_operations.py,sha256=0Zm8TT_RV0BxJCXbruYJCu1eXOkEcHpqnWn_BEe7huw,11829
216
- fractal_server/tasks/v1/endpoint_operations.py,sha256=NQYvgh-_qEI9YhsLiulfOFPDacCd-rgl3cCbPbkJUA0,5103
217
- fractal_server/tasks/v1/get_collection_data.py,sha256=5C22jp356rCH5IIC0J57wOu-DCC_kp3B6p68JooN7IM,508
218
- fractal_server/tasks/v1/utils.py,sha256=HYFyNAyZofmf--mVgdwGC5TJpGShIWIDaS01yRr4HxM,1771
174
+ fractal_server/tasks/utils.py,sha256=iJcfOCU5FAOosj6yEWlHtnvF0PuvaQGGvgdFWbbycYo,376
219
175
  fractal_server/tasks/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
220
176
  fractal_server/tasks/v2/local/__init__.py,sha256=9RVItnS7OyLsJOuJjWMCicaky4ASUPQEYD4SzDs0hOE,141
221
177
  fractal_server/tasks/v2/local/_utils.py,sha256=EvhmVwYjqaNyDCUMEsTWYOUXLgEwR1xr6bu32apCEI8,2491
@@ -241,8 +197,8 @@ fractal_server/tasks/v2/utils_templates.py,sha256=07TZpJ0Mh_A4lXVXrrH2o1VLFFGwxe
241
197
  fractal_server/urls.py,sha256=QjIKAC1a46bCdiPMu3AlpgFbcv6a4l3ABcd5xz190Og,471
242
198
  fractal_server/utils.py,sha256=PMwrxWFxRTQRl1b9h-NRIbFGPKqpH_hXnkAT3NfZdpY,3571
243
199
  fractal_server/zip_tools.py,sha256=GjDgo_sf6V_DDg6wWeBlZu5zypIxycn_l257p_YVKGc,4876
244
- fractal_server-2.11.1.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
245
- fractal_server-2.11.1.dist-info/METADATA,sha256=2-8AQ21JsDrgiHyn28rTFVP8-viNbAJu9rJxBC5z2nA,4562
246
- fractal_server-2.11.1.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
247
- fractal_server-2.11.1.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
248
- fractal_server-2.11.1.dist-info/RECORD,,
200
+ fractal_server-2.12.0a0.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
201
+ fractal_server-2.12.0a0.dist-info/METADATA,sha256=LghysLw-HvU3qdWps85YpkIfYdEYWBMcl0Wc_JygZaQ,4564
202
+ fractal_server-2.12.0a0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
203
+ fractal_server-2.12.0a0.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
204
+ fractal_server-2.12.0a0.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- """
2
- `models` module
3
- """
4
- from ..linkuserproject import LinkUserProject # noqa F401
5
- from .dataset import Dataset # noqa F401
6
- from .dataset import Resource # noqa F401
7
- from .job import ApplyWorkflow # noqa F401
8
- from .job import JobStatusTypeV1 # noqa F401
9
- from .project import Project # noqa F401
10
- from .state import State # noqa F401
11
- from .task import Task # noqa F401
12
- from .workflow import Workflow # noqa F401
13
- from .workflow import WorkflowTask # noqa F401
@@ -1,71 +0,0 @@
1
- from datetime import datetime
2
- from typing import Any
3
- from typing import Optional
4
-
5
- from sqlalchemy import Column
6
- from sqlalchemy.ext.orderinglist import ordering_list
7
- from sqlalchemy.types import DateTime
8
- from sqlalchemy.types import JSON
9
- from sqlmodel import Field
10
- from sqlmodel import Relationship
11
- from sqlmodel import SQLModel
12
-
13
- from ....utils import get_timestamp
14
- from ...schemas.v1.dataset import _DatasetBaseV1
15
- from ...schemas.v1.dataset import _ResourceBaseV1
16
-
17
-
18
- class Resource(_ResourceBaseV1, SQLModel, table=True):
19
- id: Optional[int] = Field(default=None, primary_key=True)
20
- dataset_id: int = Field(foreign_key="dataset.id")
21
-
22
-
23
- class Dataset(_DatasetBaseV1, SQLModel, table=True):
24
- """
25
- Represent a dataset
26
-
27
- Attributes:
28
- id:
29
- Primary key
30
- project_id:
31
- ID of the project the workflow belongs to.
32
- meta:
33
- Metadata of the Dataset
34
- history:
35
- History of the Dataset
36
- resource_list:
37
- (Mapper attribute)
38
-
39
- """
40
-
41
- id: Optional[int] = Field(default=None, primary_key=True)
42
- project_id: int = Field(foreign_key="project.id")
43
- project: "Project" = Relationship( # noqa: F821
44
- sa_relationship_kwargs=dict(lazy="selectin"),
45
- )
46
-
47
- resource_list: list[Resource] = Relationship(
48
- sa_relationship_kwargs={
49
- "lazy": "selectin",
50
- "order_by": "Resource.id",
51
- "collection_class": ordering_list("id"),
52
- "cascade": "all, delete-orphan",
53
- }
54
- )
55
-
56
- meta: dict[str, Any] = Field(sa_column=Column(JSON), default={})
57
- history: list[dict[str, Any]] = Field(
58
- sa_column=Column(JSON, server_default="[]", nullable=False)
59
- )
60
-
61
- timestamp_created: datetime = Field(
62
- default_factory=get_timestamp,
63
- sa_column=Column(DateTime(timezone=True), nullable=False),
64
- )
65
-
66
- class Config:
67
- arbitrary_types_allowed = True
68
-
69
- @property
70
- def paths(self) -> list[str]:
71
- return [r.path for r in self.resource_list]