fractal-server 2.14.0a3__py3-none-any.whl → 2.14.0a4__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 (47) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +3 -1
  3. fractal_server/app/history/__init__.py +4 -4
  4. fractal_server/app/history/image_updates.py +124 -143
  5. fractal_server/app/history/status_enum.py +2 -2
  6. fractal_server/app/models/v2/__init__.py +6 -4
  7. fractal_server/app/models/v2/history.py +44 -20
  8. fractal_server/app/routes/api/__init__.py +1 -1
  9. fractal_server/app/routes/api/v2/__init__.py +4 -0
  10. fractal_server/app/routes/api/v2/_aux_functions_history.py +49 -0
  11. fractal_server/app/routes/api/v2/dataset.py +0 -12
  12. fractal_server/app/routes/api/v2/history.py +301 -186
  13. fractal_server/app/routes/api/v2/project.py +0 -25
  14. fractal_server/app/routes/api/v2/status_legacy.py +168 -0
  15. fractal_server/app/routes/api/v2/workflow.py +2 -17
  16. fractal_server/app/routes/api/v2/workflowtask.py +41 -71
  17. fractal_server/app/routes/auth/oauth.py +5 -3
  18. fractal_server/app/runner/executors/local/runner.py +10 -55
  19. fractal_server/app/runner/executors/slurm_sudo/runner.py +171 -108
  20. fractal_server/app/runner/v2/__init__.py +0 -20
  21. fractal_server/app/runner/v2/runner.py +45 -58
  22. fractal_server/app/runner/v2/runner_functions.py +164 -22
  23. fractal_server/app/schemas/_validators.py +13 -24
  24. fractal_server/app/schemas/user.py +10 -7
  25. fractal_server/app/schemas/user_settings.py +9 -21
  26. fractal_server/app/schemas/v2/dataset.py +8 -6
  27. fractal_server/app/schemas/v2/job.py +9 -5
  28. fractal_server/app/schemas/v2/manifest.py +2 -6
  29. fractal_server/app/schemas/v2/project.py +9 -7
  30. fractal_server/app/schemas/v2/task.py +41 -77
  31. fractal_server/app/schemas/v2/task_collection.py +14 -32
  32. fractal_server/app/schemas/v2/task_group.py +10 -9
  33. fractal_server/app/schemas/v2/workflow.py +10 -11
  34. fractal_server/app/security/signup_email.py +2 -2
  35. fractal_server/config.py +31 -32
  36. fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +120 -0
  37. fractal_server/tasks/v2/templates/2_pip_install.sh +1 -1
  38. fractal_server/tasks/v2/utils_templates.py +6 -0
  39. {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/METADATA +1 -1
  40. {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/RECORD +43 -44
  41. fractal_server/app/runner/executors/slurm_sudo/_executor_wait_thread.py +0 -130
  42. fractal_server/app/schemas/v2/history.py +0 -23
  43. fractal_server/migrations/versions/87cd72a537a2_add_historyitem_table.py +0 -68
  44. fractal_server/migrations/versions/954ddc64425a_image_status.py +0 -63
  45. {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/LICENSE +0 -0
  46. {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/WHEEL +0 -0
  47. {fractal_server-2.14.0a3.dist-info → fractal_server-2.14.0a4.dist-info}/entry_points.txt +0 -0
fractal_server/config.py CHANGED
@@ -28,6 +28,7 @@ from pydantic import EmailStr
28
28
  from pydantic import Field
29
29
  from pydantic import field_validator
30
30
  from pydantic import model_validator
31
+ from pydantic import SecretStr
31
32
  from pydantic_settings import BaseSettings
32
33
  from pydantic_settings import SettingsConfigDict
33
34
  from sqlalchemy.engine import URL
@@ -54,8 +55,8 @@ class MailSettings(BaseModel):
54
55
  recipients: list[EmailStr] = Field(min_length=1)
55
56
  smtp_server: str
56
57
  port: int
57
- encrypted_password: Optional[str] = None
58
- encryption_key: Optional[str] = None
58
+ encrypted_password: Optional[SecretStr] = None
59
+ encryption_key: Optional[SecretStr] = None
59
60
  instance_name: str
60
61
  use_starttls: bool
61
62
  use_login: bool
@@ -97,7 +98,7 @@ class OAuthClientConfig(BaseModel):
97
98
 
98
99
  CLIENT_NAME: str
99
100
  CLIENT_ID: str
100
- CLIENT_SECRET: str
101
+ CLIENT_SECRET: SecretStr
101
102
  OIDC_CONFIGURATION_ENDPOINT: Optional[str] = None
102
103
  REDIRECT_URL: Optional[str] = None
103
104
 
@@ -137,7 +138,7 @@ class Settings(BaseSettings):
137
138
  JWT token lifetime, in seconds.
138
139
  """
139
140
 
140
- JWT_SECRET_KEY: Optional[str] = None
141
+ JWT_SECRET_KEY: Optional[SecretStr] = None
141
142
  """
142
143
  JWT secret
143
144
 
@@ -204,7 +205,7 @@ class Settings(BaseSettings):
204
205
  """
205
206
  User to use when connecting to the PostgreSQL database.
206
207
  """
207
- POSTGRES_PASSWORD: Optional[str] = None
208
+ POSTGRES_PASSWORD: Optional[SecretStr] = None
208
209
  """
209
210
  Password to use when connecting to the PostgreSQL database.
210
211
  """
@@ -223,10 +224,15 @@ class Settings(BaseSettings):
223
224
 
224
225
  @property
225
226
  def DATABASE_ASYNC_URL(self) -> URL:
227
+ if self.POSTGRES_PASSWORD is None:
228
+ password = None
229
+ else:
230
+ password = self.POSTGRES_PASSWORD.get_secret_value()
231
+
226
232
  url = URL.create(
227
233
  drivername="postgresql+psycopg",
228
234
  username=self.POSTGRES_USER,
229
- password=self.POSTGRES_PASSWORD,
235
+ password=password,
230
236
  host=self.POSTGRES_HOST,
231
237
  port=self.POSTGRES_PORT,
232
238
  database=self.POSTGRES_DB,
@@ -250,7 +256,7 @@ class Settings(BaseSettings):
250
256
  default admin credentials.
251
257
  """
252
258
 
253
- FRACTAL_DEFAULT_ADMIN_PASSWORD: str = "1234"
259
+ FRACTAL_DEFAULT_ADMIN_PASSWORD: SecretStr = "1234"
254
260
  """
255
261
  Admin default password, used upon creation of the first superuser during
256
262
  server startup.
@@ -579,11 +585,11 @@ class Settings(BaseSettings):
579
585
  """
580
586
  Address of the OAuth-signup email sender.
581
587
  """
582
- FRACTAL_EMAIL_PASSWORD: Optional[str] = None
588
+ FRACTAL_EMAIL_PASSWORD: Optional[SecretStr] = None
583
589
  """
584
590
  Password for the OAuth-signup email sender.
585
591
  """
586
- FRACTAL_EMAIL_PASSWORD_KEY: Optional[str] = None
592
+ FRACTAL_EMAIL_PASSWORD_KEY: Optional[SecretStr] = None
587
593
  """
588
594
  Key value for `cryptography.fernet` decrypt
589
595
  """
@@ -653,8 +659,12 @@ class Settings(BaseSettings):
653
659
  )
654
660
  try:
655
661
  (
656
- Fernet(self.FRACTAL_EMAIL_PASSWORD_KEY)
657
- .decrypt(self.FRACTAL_EMAIL_PASSWORD)
662
+ Fernet(
663
+ self.FRACTAL_EMAIL_PASSWORD_KEY.get_secret_value()
664
+ )
665
+ .decrypt(
666
+ self.FRACTAL_EMAIL_PASSWORD.get_secret_value()
667
+ )
658
668
  .decode("utf-8")
659
669
  )
660
670
  except Exception as e:
@@ -663,14 +673,22 @@ class Settings(BaseSettings):
663
673
  "FRACTAL_EMAIL_PASSWORD_KEY). "
664
674
  f"Original error: {str(e)}."
665
675
  )
676
+ password = self.FRACTAL_EMAIL_PASSWORD.get_secret_value()
677
+ else:
678
+ password = None
679
+
680
+ if self.FRACTAL_EMAIL_PASSWORD_KEY is not None:
681
+ key = self.FRACTAL_EMAIL_PASSWORD_KEY.get_secret_value()
682
+ else:
683
+ key = None
666
684
 
667
685
  self.email_settings = MailSettings(
668
686
  sender=self.FRACTAL_EMAIL_SENDER,
669
687
  recipients=self.FRACTAL_EMAIL_RECIPIENTS.split(","),
670
688
  smtp_server=self.FRACTAL_EMAIL_SMTP_SERVER,
671
689
  port=self.FRACTAL_EMAIL_SMTP_PORT,
672
- encrypted_password=self.FRACTAL_EMAIL_PASSWORD,
673
- encryption_key=self.FRACTAL_EMAIL_PASSWORD_KEY,
690
+ encrypted_password=password,
691
+ encryption_key=key,
674
692
  instance_name=self.FRACTAL_EMAIL_INSTANCE_NAME,
675
693
  use_starttls=use_starttls,
676
694
  use_login=use_login,
@@ -788,25 +806,6 @@ class Settings(BaseSettings):
788
806
  self.check_db()
789
807
  self.check_runner()
790
808
 
791
- def get_sanitized(self) -> dict:
792
- def _must_be_sanitized(string) -> bool:
793
- if not string.upper().startswith("FRACTAL") or any(
794
- s in string.upper()
795
- for s in ["PASSWORD", "SECRET", "PWD", "TOKEN", "KEY"]
796
- ):
797
- return True
798
- else:
799
- return False
800
-
801
- sanitized_settings = {}
802
- for k, v in self.model_dump().items():
803
- if _must_be_sanitized(k):
804
- sanitized_settings[k] = "***"
805
- else:
806
- sanitized_settings[k] = v
807
-
808
- return sanitized_settings
809
-
810
809
 
811
810
  def get_settings(settings=Settings()) -> Settings:
812
811
  return settings
@@ -0,0 +1,120 @@
1
+ """new history items
2
+
3
+ Revision ID: fbce16ff4e47
4
+ Revises: af1ef1c83c9b
5
+ Create Date: 2025-03-14 15:25:01.083619
6
+
7
+ """
8
+ import sqlalchemy as sa
9
+ import sqlmodel
10
+ from alembic import op
11
+ from sqlalchemy.dialects import postgresql
12
+
13
+ # revision identifiers, used by Alembic.
14
+ revision = "fbce16ff4e47"
15
+ down_revision = "af1ef1c83c9b"
16
+ branch_labels = None
17
+ depends_on = None
18
+
19
+
20
+ def upgrade() -> None:
21
+ # ### commands auto generated by Alembic - please adjust! ###
22
+ op.create_table(
23
+ "historyrun",
24
+ sa.Column("id", sa.Integer(), nullable=False),
25
+ sa.Column("dataset_id", sa.Integer(), nullable=False),
26
+ sa.Column("workflowtask_id", sa.Integer(), nullable=True),
27
+ sa.Column(
28
+ "workflowtask_dump",
29
+ postgresql.JSONB(astext_type=sa.Text()),
30
+ nullable=False,
31
+ ),
32
+ sa.Column(
33
+ "task_group_dump",
34
+ postgresql.JSONB(astext_type=sa.Text()),
35
+ nullable=False,
36
+ ),
37
+ sa.Column(
38
+ "timestamp_started", sa.DateTime(timezone=True), nullable=False
39
+ ),
40
+ sa.Column(
41
+ "status", sqlmodel.sql.sqltypes.AutoString(), nullable=False
42
+ ),
43
+ sa.Column("num_available_images", sa.Integer(), nullable=False),
44
+ sa.ForeignKeyConstraint(
45
+ ["dataset_id"],
46
+ ["datasetv2.id"],
47
+ name=op.f("fk_historyrun_dataset_id_datasetv2"),
48
+ ondelete="CASCADE",
49
+ ),
50
+ sa.ForeignKeyConstraint(
51
+ ["workflowtask_id"],
52
+ ["workflowtaskv2.id"],
53
+ name=op.f("fk_historyrun_workflowtask_id_workflowtaskv2"),
54
+ ondelete="SET NULL",
55
+ ),
56
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_historyrun")),
57
+ )
58
+ op.create_table(
59
+ "historyunit",
60
+ sa.Column("id", sa.Integer(), nullable=False),
61
+ sa.Column("history_run_id", sa.Integer(), nullable=False),
62
+ sa.Column(
63
+ "logfile", sqlmodel.sql.sqltypes.AutoString(), nullable=True
64
+ ),
65
+ sa.Column(
66
+ "status", sqlmodel.sql.sqltypes.AutoString(), nullable=False
67
+ ),
68
+ sa.Column("zarr_urls", postgresql.ARRAY(sa.String()), nullable=True),
69
+ sa.ForeignKeyConstraint(
70
+ ["history_run_id"],
71
+ ["historyrun.id"],
72
+ name=op.f("fk_historyunit_history_run_id_historyrun"),
73
+ ondelete="CASCADE",
74
+ ),
75
+ sa.PrimaryKeyConstraint("id", name=op.f("pk_historyunit")),
76
+ )
77
+ op.create_table(
78
+ "historyimagecache",
79
+ sa.Column(
80
+ "zarr_url", sqlmodel.sql.sqltypes.AutoString(), nullable=False
81
+ ),
82
+ sa.Column("dataset_id", sa.Integer(), nullable=False),
83
+ sa.Column("workflowtask_id", sa.Integer(), nullable=False),
84
+ sa.Column("latest_history_unit_id", sa.Integer(), nullable=False),
85
+ sa.ForeignKeyConstraint(
86
+ ["dataset_id"],
87
+ ["datasetv2.id"],
88
+ name=op.f("fk_historyimagecache_dataset_id_datasetv2"),
89
+ ondelete="CASCADE",
90
+ ),
91
+ sa.ForeignKeyConstraint(
92
+ ["latest_history_unit_id"],
93
+ ["historyunit.id"],
94
+ name=op.f(
95
+ "fk_historyimagecache_latest_history_unit_id_historyunit"
96
+ ),
97
+ ondelete="CASCADE",
98
+ ),
99
+ sa.ForeignKeyConstraint(
100
+ ["workflowtask_id"],
101
+ ["workflowtaskv2.id"],
102
+ name=op.f("fk_historyimagecache_workflowtask_id_workflowtaskv2"),
103
+ ondelete="CASCADE",
104
+ ),
105
+ sa.PrimaryKeyConstraint(
106
+ "zarr_url",
107
+ "dataset_id",
108
+ "workflowtask_id",
109
+ name=op.f("pk_historyimagecache"),
110
+ ),
111
+ )
112
+ # ### end Alembic commands ###
113
+
114
+
115
+ def downgrade() -> None:
116
+ # ### commands auto generated by Alembic - please adjust! ###
117
+ op.drop_table("historyimagecache")
118
+ op.drop_table("historyunit")
119
+ op.drop_table("historyrun")
120
+ # ### end Alembic commands ###
@@ -25,7 +25,7 @@ echo
25
25
 
26
26
  # Install package
27
27
  write_log "START install ${INSTALL_STRING}"
28
- "$VENVPYTHON" -m pip install --no-cache-dir "$INSTALL_STRING"
28
+ "$VENVPYTHON" -m pip install ${FRACTAL_PIP_CACHE_DIR_ARG} "$INSTALL_STRING"
29
29
  write_log "END install ${INSTALL_STRING}"
30
30
  echo
31
31
 
@@ -2,12 +2,15 @@ from pathlib import Path
2
2
 
3
3
  from fractal_server.app.models.v2 import TaskGroupV2
4
4
  from fractal_server.config import get_settings
5
+ from fractal_server.logger import set_logger
5
6
  from fractal_server.syringe import Inject
6
7
 
7
8
  TEMPLATES_DIR = Path(__file__).parent / "templates"
8
9
 
9
10
  SCRIPTS_SUBFOLDER = "scripts"
10
11
 
12
+ logger = set_logger(__name__)
13
+
11
14
 
12
15
  def customize_template(
13
16
  *,
@@ -87,4 +90,7 @@ def get_collection_replacements(
87
90
  task_group.pinned_package_versions_string,
88
91
  ),
89
92
  ]
93
+ logger.info(
94
+ f"Cache-dir argument for `pip install`: {settings.PIP_CACHE_DIR_ARG}"
95
+ )
90
96
  return replacements
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fractal-server
3
- Version: 2.14.0a3
3
+ Version: 2.14.0a4
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,20 @@
1
- fractal_server/__init__.py,sha256=hpk2FCu0xXoEuH8cDYFItQE2071uD_KsQqreoRWpt4A,25
2
- fractal_server/__main__.py,sha256=igfS2XL3e8JycuhASl2vsYuIPma0MG0cfPPFRuQfh14,6906
1
+ fractal_server/__init__.py,sha256=7tAxXkNvimqYIX0U_oeIYOmpP_2NjEN3fI6It2ac4-s,25
2
+ fractal_server/__main__.py,sha256=rkM8xjY1KeS3l63irB8yCrlVobR-73uDapC4wvrIlxI,6957
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/history/__init__.py,sha256=bisQpsMCFmtQGhIsf9ES0HdEuH4DYkPxVO7SlvxaWTY,239
7
- fractal_server/app/history/image_updates.py,sha256=YqoOwPW97LQk9-o04zB1lSU0yQ90V0AcuhFIhTVUxos,3959
8
- fractal_server/app/history/status_enum.py,sha256=xBBLHQY2Z105b2_HVU9DVRgdEVbbjLm6l4kkcV0Q1Sk,275
6
+ fractal_server/app/history/__init__.py,sha256=ZF-5wb_NH_7SJkUiVkYq2X0MJAy1fFnYBRpgPfEirjo,234
7
+ fractal_server/app/history/image_updates.py,sha256=ToY3yENMM6OdWUuFPG5F7qsLefrsaPqyRDFHaimsaHI,4188
8
+ fractal_server/app/history/status_enum.py,sha256=umznsG4-ZunCLz2ks3Gb-K_s1irwd4ibOJ8vJ2Z0C-M,235
9
9
  fractal_server/app/models/__init__.py,sha256=xJWiGAwpXmCpnFMC4c_HTqoUCzMOXrakoGLUH_uMvdA,415
10
10
  fractal_server/app/models/linkusergroup.py,sha256=LWTUfhH2uAnn_4moK7QdRUIHWtpw-hPZuW-5jClv_OE,610
11
11
  fractal_server/app/models/linkuserproject.py,sha256=hvaxh3Lkiy2uUCwB8gvn8RorCpvxSSdzWdCS_U1GL7g,315
12
12
  fractal_server/app/models/security.py,sha256=mMb_HiwWY74QZrs9xuyno0CVSmk4GYQWk5FxGixr8SU,3860
13
13
  fractal_server/app/models/user_settings.py,sha256=Y-ZV-uZAFLZqXxy8c5_Qeh_F7zQuZDWOgLpU6Zs6iqU,1316
14
- fractal_server/app/models/v2/__init__.py,sha256=VNoK2OUB8_IPvZoItLOxup84ZMNslO7j30jojNS2lI0,774
14
+ fractal_server/app/models/v2/__init__.py,sha256=vjHwek7-IXmaZZL9VF0nD30YL9ca4wNc8P4RXJK_kDc,832
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=SqD6Va7h7LUzSzf_yz_iTcDQpivxif6hy--Rls_yekw,1538
17
+ fractal_server/app/models/v2/history.py,sha256=C0pqn_S5yqc8PjayoyRNcsk5Mt_SxvHitdQznuxJvGM,2044
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
@@ -31,31 +31,33 @@ fractal_server/app/routes/admin/v2/project.py,sha256=luy-yiGX1JYTdPm1hpIdDUUqPm8
31
31
  fractal_server/app/routes/admin/v2/task.py,sha256=QOwgyDU9m7T_wLMwkdgfFaoMjNxcDg6zMVpngxhUvqk,4374
32
32
  fractal_server/app/routes/admin/v2/task_group.py,sha256=XTjdqgABXZcx9EenaoqSmHh12BXSentUus3SV0oxBMs,7929
33
33
  fractal_server/app/routes/admin/v2/task_group_lifecycle.py,sha256=0e0ZJ_k75TVHaT2o8Xk33DPDSgh-eBhZf-y4y7t-Adg,9429
34
- fractal_server/app/routes/api/__init__.py,sha256=2IDheFi0OFdsUg7nbUiyahqybvpgXqeHUXIL2QtWrQQ,641
35
- fractal_server/app/routes/api/v2/__init__.py,sha256=S7zOeoLkD6Sss1JLRQxeQWPSXKMX2yaIVhLQUw0PDh0,2176
34
+ fractal_server/app/routes/api/__init__.py,sha256=B8l6PSAhR10iZqHEiyTat-_0tkeKdrCigIE6DJGP5b8,638
35
+ fractal_server/app/routes/api/v2/__init__.py,sha256=Q65mxJOfuexzj53m6IB5fNl9PDec-Asu97W0bBxrRMM,2324
36
36
  fractal_server/app/routes/api/v2/_aux_functions.py,sha256=pmYbsHjJexb5-zMCJQLNStmU_95ZfeEIBpoCJx4GFIY,13480
37
+ fractal_server/app/routes/api/v2/_aux_functions_history.py,sha256=dGr9mhuE1kJPx8RNDwFplCWBunV1Zh0QxNQbssGAqMI,1341
37
38
  fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py,sha256=qdXCb6IP8-qPEAxGZKljtjIqNzIAyRaAsQSRi5VqFHM,6773
38
39
  fractal_server/app/routes/api/v2/_aux_functions_tasks.py,sha256=uhNSs-jcS7ndIUFKiOC1yrDiViw3uvKEXi9UL04BMks,11642
39
- fractal_server/app/routes/api/v2/dataset.py,sha256=gS5169eJRGHBQNUnkDB75Bv3Kg8Ql-tMVw5_FAxUEKc,9664
40
- fractal_server/app/routes/api/v2/history.py,sha256=C_V_u2ab4i8v4bM-uQ0SV3Olyor_5olQRDYFsLco2Ac,9801
40
+ fractal_server/app/routes/api/v2/dataset.py,sha256=osoWJIA5SZH4aAr-0TG6Uc3877wzsgCLB_Oek59hRjk,9230
41
+ fractal_server/app/routes/api/v2/history.py,sha256=GPok8bYnagGPjNmoHvdLm2h-lirsd2ROUlMt2OjIoKM,12911
41
42
  fractal_server/app/routes/api/v2/images.py,sha256=wUhYomNLGtJTtu_pD2oQorcH2LISxo64Wxo6ogc4IXc,8185
42
43
  fractal_server/app/routes/api/v2/job.py,sha256=m89FTh9Px25oXCeWj2k2NdGWQaO2oxMh-6lZppcsJOY,5551
43
- fractal_server/app/routes/api/v2/project.py,sha256=apWQNOdj2FIZmBl6Cjtr2tK-jUclEsw-ikKg6PMT8sU,7828
44
+ fractal_server/app/routes/api/v2/project.py,sha256=hMvL9QLPUcAAiPGy6ta2LBLTVRozJsfvBPl5D06_MHg,6666
45
+ fractal_server/app/routes/api/v2/status_legacy.py,sha256=sJLHGGHI9so_Sa4-8JuhMGBPeE6n4K2DmDuiw6IB4XY,6317
44
46
  fractal_server/app/routes/api/v2/submit.py,sha256=K4OjcSg476JXIeeMUaYdTDk8Qpj5IO5UULvfErI7Y5Y,8624
45
47
  fractal_server/app/routes/api/v2/task.py,sha256=z3_SxsXoKsbM9GGNJUdIiZisQwAJSBqvCc7thaJIOTU,7191
46
48
  fractal_server/app/routes/api/v2/task_collection.py,sha256=IDNF6sjDuU37HIQ0TuQA-TZIuf7nfHAQXUUNmkrlhLM,12706
47
49
  fractal_server/app/routes/api/v2/task_collection_custom.py,sha256=cctW61-C2QYF2KXluS15lLhZJS_kt30Ca6UGLFO32z0,6207
48
50
  fractal_server/app/routes/api/v2/task_group.py,sha256=j3zDvVZizB7NWEgVgZU42JCXETkaVkk2ImJPr0jS7BQ,8164
49
51
  fractal_server/app/routes/api/v2/task_group_lifecycle.py,sha256=3o9bCC8ubMwffQPPaxQZy-CjH9IB2RkIReIecI6L2_w,9300
50
- fractal_server/app/routes/api/v2/workflow.py,sha256=R-wnT9tWTSbaNobGcfgLdk-4pbfbxoBwKZd1JRZXsSU,12223
52
+ fractal_server/app/routes/api/v2/workflow.py,sha256=U3iZX5IiFAJ20-R8IjlYToOdm9gXsmtr1lW7ASEH9P8,11689
51
53
  fractal_server/app/routes/api/v2/workflow_import.py,sha256=INmnhlMEBJp-vHPR0f940DANPmIidts3OfcooeM_aNA,11205
52
- fractal_server/app/routes/api/v2/workflowtask.py,sha256=89yLpSzdr7Mv3wRmdMt71CSC3hclrVUP56UVtfTQHOQ,12152
54
+ fractal_server/app/routes/api/v2/workflowtask.py,sha256=pi4oxWszNgWkDm6oQavanmq4_P5kpcgN3Dfjz9XAuV8,11063
53
55
  fractal_server/app/routes/auth/__init__.py,sha256=fao6CS0WiAjHDTvBzgBVV_bSXFpEAeDBF6Z6q7rRkPc,1658
54
56
  fractal_server/app/routes/auth/_aux_auth.py,sha256=UZgauY0V6mSqjte_sYI1cBl2h8bcbLaeWzgpl1jdJlk,4883
55
57
  fractal_server/app/routes/auth/current_user.py,sha256=FUegTahlxT3BdPVCQYir0-ogg2YAaZ1DYuLcE_5NC9Y,5906
56
58
  fractal_server/app/routes/auth/group.py,sha256=EblxNVNTiPQj82eMaxNxf3OqoAbRLOExxCnm1-8C-k0,8364
57
59
  fractal_server/app/routes/auth/login.py,sha256=tSu6OBLOieoBtMZB4JkBAdEgH2Y8KqPGSbwy7NIypIo,566
58
- fractal_server/app/routes/auth/oauth.py,sha256=AnFHbjqL2AgBX3eksI931xD6RTtmbciHBEuGf9YJLjU,1895
60
+ fractal_server/app/routes/auth/oauth.py,sha256=KCtJHSzemC4S8AfX9bLLdVhlF1nU4DOyox-sNQtcWew,1978
59
61
  fractal_server/app/routes/auth/register.py,sha256=DlHq79iOvGd_gt2v9uwtsqIKeO6i_GKaW59VIkllPqY,587
60
62
  fractal_server/app/routes/auth/router.py,sha256=tzJrygXFZlmV_uWelVqTOJMEH-3Fr7ydwlgx1LxRjxY,527
61
63
  fractal_server/app/routes/auth/users.py,sha256=Zr1Bsa7Hpricb_1uFwKPCtgt3PzGnP0TaMLMdpbQDNs,7825
@@ -73,7 +75,7 @@ fractal_server/app/runner/executors/base_runner.py,sha256=0E3gbSndXdEAxZwFCiZXrU
73
75
  fractal_server/app/runner/executors/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
76
  fractal_server/app/runner/executors/local/_local_config.py,sha256=8dyg2Gh8L2FlG_jJRYLMkcMgVHGEY2w7DME9aaKXFFo,3688
75
77
  fractal_server/app/runner/executors/local/_submit_setup.py,sha256=pDc9Q6axXL8_5JAV0byXzGOLOB0bZF88_L9LZykOgwM,1220
76
- fractal_server/app/runner/executors/local/runner.py,sha256=tEI3qe9UQKgqNoY6gkP1b2O1yRw3VGTiPTDKztrCt2I,7577
78
+ fractal_server/app/runner/executors/local/runner.py,sha256=Iy5Pc8rdkj7IGcwUbkO_UgZNDytXtfMysYtMSu_dlY0,5498
77
79
  fractal_server/app/runner/executors/slurm_common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
80
  fractal_server/app/runner/executors/slurm_common/_batching.py,sha256=ZY020JZlDS5mfpgpWTChQkyHU7iLE5kx2HVd57_C6XA,8850
79
81
  fractal_server/app/runner/executors/slurm_common/_job_states.py,sha256=nuV-Zba38kDrRESOVB3gaGbrSPZc4q7YGichQaeqTW0,238
@@ -88,50 +90,48 @@ fractal_server/app/runner/executors/slurm_ssh/_slurm_job.py,sha256=IL1C52dezEiin
88
90
  fractal_server/app/runner/executors/slurm_ssh/executor.py,sha256=JW6zguEy9XsHebSPt_JTK4Kw78r5rlbDEipSOxOqoHk,53660
89
91
  fractal_server/app/runner/executors/slurm_sudo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
92
  fractal_server/app/runner/executors/slurm_sudo/_check_jobs_status.py,sha256=eZd9lxbObsqc1M3B96IGMJ-1oC0jo8lBOX4Nto97VvE,2036
91
- fractal_server/app/runner/executors/slurm_sudo/_executor_wait_thread.py,sha256=7CaMarvaKFCq3RcyqW5CABng_3b3QaS2pmTzVRDgm3I,4077
92
93
  fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py,sha256=O1bNg1DiSDJmQE0RmOk2Ii47DagiXp5ryd0R6KxO2OM,3177
93
- fractal_server/app/runner/executors/slurm_sudo/runner.py,sha256=JFVGb0K7w0l6kuy4QjIey_3M4indQUwvqbflzdW9Gi8,21256
94
+ fractal_server/app/runner/executors/slurm_sudo/runner.py,sha256=VOWd8bYzCU8C6TziZN7VUurX52lbvNDWLZ2Ht3uvnGc,24057
94
95
  fractal_server/app/runner/extract_archive.py,sha256=tLpjDrX47OjTNhhoWvm6iNukg8KoieWyTb7ZfvE9eWU,2483
95
96
  fractal_server/app/runner/filenames.py,sha256=lPnxKHtdRizr6FqG3zOdjDPyWA7GoaJGTtiuJV0gA8E,70
96
97
  fractal_server/app/runner/run_subprocess.py,sha256=c3JbYXq3hX2aaflQU19qJ5Xs6J6oXGNvnTEoAfv2bxc,959
97
98
  fractal_server/app/runner/set_start_and_last_task_index.py,sha256=-q4zVybAj8ek2XlbENKlfOAJ39hT_zoJoZkqzDqiAMY,1254
98
99
  fractal_server/app/runner/shutdown.py,sha256=9pfSKHDNdIcm0eY-opgRTi7y0HmvfPmYiu9JR6Idark,2082
99
100
  fractal_server/app/runner/task_files.py,sha256=5enzBqiQct1AUGwrGX-rxFCxnhW3SPYIUylMYwyVfrE,2482
100
- fractal_server/app/runner/v2/__init__.py,sha256=llVnhgNGsSuP_eZ_ilQixQTmwst79LWrgjILpC2Xn9o,14247
101
+ fractal_server/app/runner/v2/__init__.py,sha256=ro5C4ro7gXuV-H7p8SrV90vBsS52IfukWn-b2FxJ9F4,13293
101
102
  fractal_server/app/runner/v2/_local.py,sha256=Zas2RS_f9mfdkXszBpzISHylLX1bX8pFuoLA1fHLFqQ,2945
102
103
  fractal_server/app/runner/v2/_slurm_ssh.py,sha256=5w_lwQzySx-R3kVg2Bf-21n5JpWjJAgMtYP2BROvWJo,3227
103
104
  fractal_server/app/runner/v2/_slurm_sudo.py,sha256=CzWUeC6at_Sj-wU1myjA68ZRKMiLZYBTLv9I9odUxBU,2914
104
105
  fractal_server/app/runner/v2/deduplicate_list.py,sha256=IVTE4abBU1bUprFTkxrTfYKnvkNTanWQ-KWh_etiT08,645
105
106
  fractal_server/app/runner/v2/merge_outputs.py,sha256=D1L4Taieq9i71SPQyNc1kMokgHh-sV_MqF3bv7QMDBc,907
106
- fractal_server/app/runner/v2/runner.py,sha256=qtxmnrgMdlB3CA5Ayg7BXUv1yETR6H7kMLp70R1faSM,14456
107
- fractal_server/app/runner/v2/runner_functions.py,sha256=Zvi6sC5krltygLO-fC0K21VJEhmX1XQCm9IzVqf_cB0,9583
107
+ fractal_server/app/runner/v2/runner.py,sha256=25kOKm4B7_BhUlg7Dh0yzIcJ2izugA_WFNhVf06O0Y4,13970
108
+ fractal_server/app/runner/v2/runner_functions.py,sha256=PQC5wsi-o3AlFZbk3EeIZ_9KMBLQxYleMDi7CYcXySE,14473
108
109
  fractal_server/app/runner/v2/runner_functions_low_level.py,sha256=dvvRK7od8iQ8vdPf80uGUxs3i5i0buGjCodBxSjZ7PQ,3671
109
110
  fractal_server/app/runner/v2/task_interface.py,sha256=e1GGQSYd0MyBj1EZvEVzqv-HpVE4YffXOq82WLrCaOc,1866
110
111
  fractal_server/app/runner/versions.py,sha256=dSaPRWqmFPHjg20kTCHmi_dmGNcCETflDtDLronNanU,852
111
112
  fractal_server/app/schemas/__init__.py,sha256=stURAU_t3AOBaH0HSUbV-GKhlPKngnnIMoqWc3orFyI,135
112
113
  fractal_server/app/schemas/_filter_validators.py,sha256=Gkf2USrkuxZx1TWeeMRmhgfmG60AAIDQfbaWslLsvJQ,1572
113
- fractal_server/app/schemas/_validators.py,sha256=ap0VWJzOfPcq_tbH3sglZClkuinNvMjRq9fhTIdn-zk,3029
114
- fractal_server/app/schemas/user.py,sha256=vLijVyPIQJdpFc36S6qK2XtSKMzfkhULN1nBsb9tV18,2407
114
+ fractal_server/app/schemas/_validators.py,sha256=ZzTlTTzRATzf9Snx4Xp67aDmG77GaM2ewssFtlxQaaY,2680
115
+ fractal_server/app/schemas/user.py,sha256=oCftAKeHdFFowpLyh1G-RiylR8cIO7fTn0PkT5xjs0E,2494
115
116
  fractal_server/app/schemas/user_group.py,sha256=Uao1igRYflBu7Dg6Zs0kaFU3zBFJzIwDLrkFfaJk6z8,2176
116
- fractal_server/app/schemas/user_settings.py,sha256=4XeXQ3rnDS1UvLPd9hvh-WVSbzBGcMDjChfiZ_WGi-w,3134
117
+ fractal_server/app/schemas/user_settings.py,sha256=z7hx54yTrWfjo98oX_1lkeRh1UGrC1dSRH6yIOpnCsY,2772
117
118
  fractal_server/app/schemas/v2/__init__.py,sha256=pjRUOJwZGzsDbBbxfnCgQgShs5V8SaHRqwIQDW3STpY,2676
118
119
  fractal_server/app/schemas/v2/accounting.py,sha256=Wylt7uWTiDIFlHJOh4XEtYitk2FjFlmnodDrJDxcr0E,397
119
- fractal_server/app/schemas/v2/dataset.py,sha256=xo7Y3fq5ThMVBp6xDVypdG-EmGfBX_vWVRs66u2pC34,5157
120
+ fractal_server/app/schemas/v2/dataset.py,sha256=9yc-tte70yPPk4CSfy2imykYVbCW8-23K499pi9z2e0,5206
120
121
  fractal_server/app/schemas/v2/dumps.py,sha256=2GUjoqeblUvrSoojBz5odoUUf53IABtbY_5GvFZoMVc,1782
121
- fractal_server/app/schemas/v2/history.py,sha256=OHwRIbOIjBiiTYUNZYsHTdEXJHff17JRizQ8pf1e0vk,601
122
- fractal_server/app/schemas/v2/job.py,sha256=Dp_RRiC5uvJqq1fAJlBXztAFA-tS5FWuRnUbTnLtL6M,4226
123
- fractal_server/app/schemas/v2/manifest.py,sha256=tcCvT4PbdtpdC5eU54MKUne6puXpnPlIExZYwLGHEAo,7133
124
- fractal_server/app/schemas/v2/project.py,sha256=uqBreoS0UAkbVEJJS2HkSdjCCWfFIkv6N70TWk9HgxA,868
122
+ fractal_server/app/schemas/v2/job.py,sha256=KhxQOfncpE_SAu7Wed8CXS2G6onh0v875GkotBvKBTY,4304
123
+ fractal_server/app/schemas/v2/manifest.py,sha256=tMNKtwVUBhVyAmBHK6f2agzvdKuYhuTP-e2cG9t66y0,7045
124
+ fractal_server/app/schemas/v2/project.py,sha256=ulgCmUnX0w-0jrSjVYIT7sxeK95CSNGh2msXydhsgYI,885
125
125
  fractal_server/app/schemas/v2/status.py,sha256=SQaUpQkjFq5c5k5J4rOjNhuQaDOEg8lksPhkKmPU5VU,332
126
- fractal_server/app/schemas/v2/task.py,sha256=OUCNQQUULmWSOdPm8Dz8E0ivG1XOcvO4dxz-osSa9R0,7248
127
- fractal_server/app/schemas/v2/task_collection.py,sha256=NFIcfTAhFN5LMxmyJCat7CKxUXq2CLEuWl5Hs0siZl8,6561
128
- fractal_server/app/schemas/v2/task_group.py,sha256=vFF850kJRmmcxt2sn7nrhm-OWJHRhYu_XOQP5LNiXyU,3850
129
- fractal_server/app/schemas/v2/workflow.py,sha256=qmKJZ9xZ6-sN41XdocZ7K6hum_pUfaMuKOJs_TlFCRQ,2211
126
+ fractal_server/app/schemas/v2/task.py,sha256=lPXxhwvPLjXuoZGdVSLZq3wTChfBbP7V-uTEpQa1HoU,5753
127
+ fractal_server/app/schemas/v2/task_collection.py,sha256=dLu4sy-su5k5vDJqCZdJMW8mLT5TX2SV60l_RAvKhwY,5930
128
+ fractal_server/app/schemas/v2/task_group.py,sha256=A3SFHNHLKPJyrnDz-wbnQvycetafKltp6UsH1u-euwA,3850
129
+ fractal_server/app/schemas/v2/workflow.py,sha256=ZpM43zTMyLRnEUtkbr_J5DYP00NwjItaC8gweB7GGAA,2172
130
130
  fractal_server/app/schemas/v2/workflowtask.py,sha256=qMvwlnFCsnyD8uv8HJ4cFy2-QMm2ETUFlTIbxIFUWxk,8056
131
131
  fractal_server/app/security/__init__.py,sha256=e2cveg5hQpieGD3bSPd5GTOMthvJ-HXH3buSb9WVfEU,14096
132
- fractal_server/app/security/signup_email.py,sha256=CR1VbsGFNshxsWquLDZPbUAYnGzkCHeJChtncq63RBc,1434
132
+ fractal_server/app/security/signup_email.py,sha256=Xd6QYxcdmg0PHpDwmUE8XQmPcOj3Xjy5oROcIMhmltM,1472
133
133
  fractal_server/app/user_settings.py,sha256=OP1yiYKtPadxwM51_Q0hdPk3z90TCN4z1BLpQsXyWiU,1316
134
- fractal_server/config.py,sha256=eYo-c3Zt4rkC45mewLYOeFZSA_7FF4Wmm6zDvX1dpt4,28549
134
+ fractal_server/config.py,sha256=mdVsXHo3bCBMyTErro2kN2CKV2547XTHWoaAAiawq94,28561
135
135
  fractal_server/data_migrations/README.md,sha256=_3AEFvDg9YkybDqCLlFPdDmGJvr6Tw7HRI14aZ3LOIw,398
136
136
  fractal_server/data_migrations/tools.py,sha256=LeMeASwYGtEqd-3wOLle6WARdTGAimoyMmRbbJl-hAM,572
137
137
  fractal_server/gunicorn_fractal.py,sha256=u6U01TLGlXgq1v8QmEpLih3QnsInZD7CqphgJ_GrGzc,1230
@@ -155,11 +155,9 @@ fractal_server/migrations/versions/5bf02391cfef_v2.py,sha256=axhNkr_H6R4rRbY7oGY
155
155
  fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py,sha256=Q-DsMzG3IcUV2Ol1dhJWosDvKERamBE6QvA2zzS5zpQ,1632
156
156
  fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py,sha256=mbWuCkTpRAdGbRhW7lhXs_e5S6O37UAcCN6JfoY5H8A,1353
157
157
  fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py,sha256=NSCuhANChsg76vBkShBl-9tQ4VEHubOjtAv1etHhlvY,2684
158
- fractal_server/migrations/versions/87cd72a537a2_add_historyitem_table.py,sha256=xxAftQYyQ2C_7qiuPcG5FeVmhFQGznxfCglsfk2CjiU,2092
159
158
  fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py,sha256=68y9-fpSuKx6KPtM_9n8Ho0I1qwa8IoG-yJqXUYQrGg,1111
160
159
  fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py,sha256=6pgODDtyAxevZvAJBj9IJ41inhV1RpwbpZr_qfPPu1A,1115
161
160
  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
163
161
  fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py,sha256=eKTZm3EgUgapXBxO0RuHkEfTKic-TZG3ADaMpGLuc0k,1057
164
162
  fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py,sha256=0im6TxDr53sKKcjiPgeH4ftVRGnRXZSh2lPbRQ1Ir9w,883
165
163
  fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py,sha256=syONdZNf4-OnAcWIsbzXpYwpXPsXZ4SsmjwVvmVG0PU,2256
@@ -174,6 +172,7 @@ fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_colum
174
172
  fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py,sha256=lOggSvzGWqQvnxxFuSM6W50Ui49R918A-uBuiZJ0pNM,963
175
173
  fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py,sha256=jilQW3QIqYQ4Q6hCnUiG7UtNMpA41ujqrB3tPFiPM1Q,1221
176
174
  fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py,sha256=9BwqUS9Gf7UW_KjrzHbtViC880qhD452KAytkHWWZyk,746
175
+ fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py,sha256=TDWCaIoM0Q4SpRWmR9zr_rdp3lJXhCfBPTMhtrP5xYE,3950
177
176
  fractal_server/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
178
177
  fractal_server/ssh/__init__.py,sha256=sVUmzxf7_DuXG1xoLQ1_00fo5NPhi2LJipSmU5EAkPs,124
179
178
  fractal_server/ssh/_fabric.py,sha256=lNy4IX1I4We6VoWa4Bz4fUPuApLMSoejpyE6I3jDZeM,22869
@@ -193,7 +192,7 @@ fractal_server/tasks/v2/ssh/collect.py,sha256=-wqqGMapjD1hQz1vphwXmZaD4qzziMetc6
193
192
  fractal_server/tasks/v2/ssh/deactivate.py,sha256=EAVH2HtyvmIFXqUwsGYhlJcAcVh_MvIOaKDY8AyBODw,11400
194
193
  fractal_server/tasks/v2/ssh/reactivate.py,sha256=8Rnbbny7TjMEAHhboqfgxBVZZK5UNNmh4Ud-0y3jaVM,7970
195
194
  fractal_server/tasks/v2/templates/1_create_venv.sh,sha256=PK0jdHKtQpda1zULebBaVPORt4t6V17wa4N1ohcj5ac,548
196
- fractal_server/tasks/v2/templates/2_pip_install.sh,sha256=Gpk2io8u9YaflFUlQu2NgkDQw5AA4m4AOVG1sB4yrHQ,1822
195
+ fractal_server/tasks/v2/templates/2_pip_install.sh,sha256=Md2LPt3BJ7IfN0USF2uivl4rP8OwbzJOUepGAr_Cicg,1836
197
196
  fractal_server/tasks/v2/templates/3_pip_freeze.sh,sha256=JldREScEBI4cD_qjfX4UK7V4aI-FnX9ZvVNxgpSOBFc,168
198
197
  fractal_server/tasks/v2/templates/4_pip_show.sh,sha256=qm1vPy6AkKhWDjCJGXS8LqCLYO3KsAyRK325ZsFcF6U,1747
199
198
  fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh,sha256=q-6ZUvA6w6FDVEoSd9O63LaJ9tKZc7qAFH72SGPrd_k,284
@@ -202,12 +201,12 @@ fractal_server/tasks/v2/utils_background.py,sha256=W_RvihI1aiYPJNsPo8z4wKuA_bPs0
202
201
  fractal_server/tasks/v2/utils_database.py,sha256=iLbwkxMxTCgpyKe1JQzdfIR3zBfxohgmLwSdGps1AUo,1274
203
202
  fractal_server/tasks/v2/utils_package_names.py,sha256=RDg__xrvQs4ieeVzmVdMcEh95vGQYrv9Hfal-5EDBM8,2393
204
203
  fractal_server/tasks/v2/utils_python_interpreter.py,sha256=5_wrlrTqXyo1YuLZvAW9hrSoh5MyLOzdPVUlUwM7uDQ,955
205
- fractal_server/tasks/v2/utils_templates.py,sha256=07TZpJ0Mh_A4lXVXrrH2o1VLFFGwxeRumA6DdgMgCWk,2947
204
+ fractal_server/tasks/v2/utils_templates.py,sha256=Kc_nSzdlV6KIsO0CQSPs1w70zLyENPqJeTQEFiz4bOg,3124
206
205
  fractal_server/urls.py,sha256=QjIKAC1a46bCdiPMu3AlpgFbcv6a4l3ABcd5xz190Og,471
207
206
  fractal_server/utils.py,sha256=PMwrxWFxRTQRl1b9h-NRIbFGPKqpH_hXnkAT3NfZdpY,3571
208
207
  fractal_server/zip_tools.py,sha256=GjDgo_sf6V_DDg6wWeBlZu5zypIxycn_l257p_YVKGc,4876
209
- fractal_server-2.14.0a3.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
210
- fractal_server-2.14.0a3.dist-info/METADATA,sha256=F2fjhacHy-6hFP43F8JNom4iV9-WNRiO6CiCye5KzLI,4550
211
- fractal_server-2.14.0a3.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
212
- fractal_server-2.14.0a3.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
213
- fractal_server-2.14.0a3.dist-info/RECORD,,
208
+ fractal_server-2.14.0a4.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
209
+ fractal_server-2.14.0a4.dist-info/METADATA,sha256=dnHmj3wrxhQa2uhKzb4A9tJ2sSWtvj6kPEiTSO26NBQ,4550
210
+ fractal_server-2.14.0a4.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
211
+ fractal_server-2.14.0a4.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
212
+ fractal_server-2.14.0a4.dist-info/RECORD,,
@@ -1,130 +0,0 @@
1
- import os
2
- import threading
3
- import time
4
- import traceback
5
- from itertools import count
6
- from typing import Optional
7
-
8
- from ._check_jobs_status import get_finished_jobs
9
- from fractal_server.app.runner.exceptions import JobExecutionError
10
- from fractal_server.logger import set_logger
11
-
12
- logger = set_logger(__name__)
13
-
14
-
15
- class FractalSlurmSudoWaitThread(threading.Thread):
16
- """
17
- Thread that monitors a pool of SLURM jobs
18
-
19
- This class is a custom re-implementation of the waiting thread class from:
20
-
21
- > clusterfutures <https://github.com/sampsyo/clusterfutures>
22
- > Original Copyright
23
- > Copyright 2021 Adrian Sampson <asampson@cs.washington.edu>
24
- > License: MIT
25
-
26
- Attributes:
27
- slurm_user:
28
- shutdown_file:
29
- shutdown_callback:
30
- slurm_poll_interval:
31
- waiting:
32
- shutdown:
33
- lock:
34
- """
35
-
36
- slurm_user: str
37
- shutdown_file: Optional[str] = None
38
- shutdown_callback: callable
39
- slurm_poll_interval: int = 30
40
- waiting: dict[tuple[str, ...], str]
41
- shutdown: bool
42
- _lock: threading.Lock
43
-
44
- def __init__(self, callback: callable, interval=1):
45
- threading.Thread.__init__(self, daemon=True)
46
- self.callback = callback
47
- self.interval = interval
48
- self.waiting = {}
49
- self._lock = threading.Lock() # To protect the .waiting dict
50
- self.shutdown = False
51
- self.active_job_ids = []
52
-
53
- def wait(
54
- self,
55
- *,
56
- filenames: tuple[str, ...],
57
- jobid: str,
58
- ):
59
- """
60
- Add a a new job to the set of jobs being waited for.
61
-
62
- A job consists of a tuple of filenames and a callback value (i.e. a
63
- SLURM job ID).
64
-
65
- Note that (with respect to clusterfutures) we replaced `filename` with
66
- `filenames`.
67
- """
68
- if self.shutdown:
69
- error_msg = "Cannot call `wait` method after executor shutdown."
70
- logger.warning(error_msg)
71
- raise JobExecutionError(info=error_msg)
72
- with self._lock:
73
- self.waiting[filenames] = jobid
74
-
75
- def check_shutdown(self, i):
76
- """
77
- Do one shutdown-file-existence check.
78
-
79
- Note: the `i` parameter allows subclasses like `SlurmWaitThread` to do
80
- something on every Nth check.
81
-
82
- Changed from clusterfutures:
83
- * Do not check for output-pickle-file existence (we rather rely on
84
- `cfut.slurm.jobs_finished`);
85
- * Check for the existence of shutdown-file.
86
- """
87
- if self.shutdown_file and os.path.exists(self.shutdown_file):
88
- logger.info(
89
- f"Detected executor-shutdown file {str(self.shutdown_file)}"
90
- )
91
- self.shutdown = True
92
-
93
- def run(self):
94
- """
95
- Overrides the original clusterfutures.FileWaitThread.run, adding a call
96
- to self.shutdown_callback.
97
-
98
- Changed from clusterfutures:
99
- * We do not rely on output-file-existence checks to verify whether a
100
- job is complete.
101
-
102
- Note that `shutdown_callback` only takes care of cleaning up the
103
- FractalSlurmExecutor variables, and then the `return` here is enough to
104
- fully clean up the `FractalFileWaitThread` object.
105
- """
106
- for i in count():
107
- if self.shutdown:
108
- self.shutdown_callback()
109
- return
110
- with self._lock:
111
- self.check(i)
112
- time.sleep(self.interval)
113
-
114
- def check(self, i):
115
- self.check_shutdown(i)
116
- if i % (self.slurm_poll_interval // self.interval) == 0:
117
- try:
118
- finished_jobs = get_finished_jobs(self.waiting.values())
119
- except Exception:
120
- # Don't abandon completion checking if jobs_finished errors
121
- traceback.print_exc()
122
- return
123
-
124
- if not finished_jobs:
125
- return
126
-
127
- id_to_filenames = {v: k for (k, v) in self.waiting.items()}
128
- for finished_id in finished_jobs:
129
- self.callback(finished_id)
130
- self.waiting.pop(id_to_filenames[finished_id])