fractal-server 2.15.1__py3-none-any.whl → 2.15.2__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.15.1"
1
+ __VERSION__ = "2.15.2"
@@ -45,13 +45,11 @@ class DB:
45
45
  settings = Inject(get_settings)
46
46
  settings.check_db()
47
47
 
48
- engine_kwargs_async = {"pool_pre_ping": True}
49
-
50
48
  cls._engine_async = create_async_engine(
51
49
  settings.DATABASE_ASYNC_URL,
52
50
  echo=settings.DB_ECHO,
53
51
  future=True,
54
- **engine_kwargs_async,
52
+ pool_pre_ping=True,
55
53
  )
56
54
  cls._async_session_maker = sessionmaker(
57
55
  cls._engine_async,
@@ -65,13 +63,11 @@ class DB:
65
63
  settings = Inject(get_settings)
66
64
  settings.check_db()
67
65
 
68
- engine_kwargs_sync = {}
69
-
70
66
  cls._engine_sync = create_engine(
71
67
  settings.DATABASE_SYNC_URL,
72
68
  echo=settings.DB_ECHO,
73
69
  future=True,
74
- **engine_kwargs_sync,
70
+ pool_pre_ping=True,
75
71
  )
76
72
 
77
73
  cls._sync_session_maker = sessionmaker(
@@ -156,8 +156,15 @@ async def update_job(
156
156
  detail=f"Cannot set job status to {job_update.status}",
157
157
  )
158
158
 
159
+ timestamp = get_timestamp()
159
160
  setattr(job, "status", job_update.status)
160
- setattr(job, "end_timestamp", get_timestamp())
161
+ setattr(job, "end_timestamp", timestamp)
162
+ setattr(
163
+ job,
164
+ "log",
165
+ f"{job.log or ''}\nThis job was manually marked as "
166
+ f"'{JobStatusTypeV2.FAILED}' by an admin ({timestamp.isoformat()}).",
167
+ )
161
168
  await db.commit()
162
169
  await db.refresh(job)
163
170
  await db.close()
@@ -325,6 +325,24 @@ def _get_submitted_jobs_statement() -> SelectOfScalar:
325
325
  return stm
326
326
 
327
327
 
328
+ async def _workflow_has_submitted_job(
329
+ workflow_id: int,
330
+ db: AsyncSession,
331
+ ) -> bool:
332
+
333
+ res = await db.execute(
334
+ select(JobV2.id)
335
+ .where(JobV2.status == JobStatusTypeV2.SUBMITTED)
336
+ .where(JobV2.workflow_id == workflow_id)
337
+ .limit(1)
338
+ )
339
+ submitted_jobs = res.scalar_one_or_none()
340
+ if submitted_jobs is not None:
341
+ return True
342
+
343
+ return False
344
+
345
+
328
346
  async def _workflow_insert_task(
329
347
  *,
330
348
  workflow_id: int,
@@ -22,6 +22,7 @@ from ._aux_functions import _check_workflow_exists
22
22
  from ._aux_functions import _get_project_check_owner
23
23
  from ._aux_functions import _get_submitted_jobs_statement
24
24
  from ._aux_functions import _get_workflow_check_owner
25
+ from ._aux_functions import _workflow_has_submitted_job
25
26
  from ._aux_functions_tasks import _add_warnings_to_workflow_tasks
26
27
  from fractal_server.app.models import UserOAuth
27
28
  from fractal_server.app.models.v2 import TaskGroupV2
@@ -146,6 +147,18 @@ async def update_workflow(
146
147
 
147
148
  for key, value in patch.model_dump(exclude_unset=True).items():
148
149
  if key == "reordered_workflowtask_ids":
150
+
151
+ if await _workflow_has_submitted_job(
152
+ workflow_id=workflow_id, db=db
153
+ ):
154
+ raise HTTPException(
155
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
156
+ detail=(
157
+ "Cannot re-order WorkflowTasks while a Job is running "
158
+ "for this Workflow."
159
+ ),
160
+ )
161
+
149
162
  current_workflowtask_ids = [
150
163
  wftask.id for wftask in workflow.task_list
151
164
  ]
@@ -10,6 +10,7 @@ from ....db import AsyncSession
10
10
  from ....db import get_async_db
11
11
  from ._aux_functions import _get_workflow_check_owner
12
12
  from ._aux_functions import _get_workflow_task_check_owner
13
+ from ._aux_functions import _workflow_has_submitted_job
13
14
  from ._aux_functions import _workflow_insert_task
14
15
  from ._aux_functions_tasks import _check_type_filters_compatibility
15
16
  from ._aux_functions_tasks import _get_task_read_access
@@ -224,6 +225,15 @@ async def delete_workflowtask(
224
225
  db=db,
225
226
  )
226
227
 
228
+ if await _workflow_has_submitted_job(workflow_id=workflow_id, db=db):
229
+ raise HTTPException(
230
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
231
+ detail=(
232
+ "Cannot delete a WorkflowTask while a Job is running for this "
233
+ "Workflow."
234
+ ),
235
+ )
236
+
227
237
  # Delete WorkflowTask
228
238
  await db.delete(db_workflow_task)
229
239
  await db.commit()
@@ -137,6 +137,34 @@ class BaseSlurmRunner(BaseRunner):
137
137
  def run_squeue(self, *, job_ids: list[str], **kwargs) -> str:
138
138
  raise NotImplementedError("Implement in child class.")
139
139
 
140
+ def _is_squeue_error_recoverable(self, exception: BaseException) -> True:
141
+ """
142
+ Determine whether a `squeue` error is considered recoverable.
143
+
144
+ A _recoverable_ error is one which will disappear after some time,
145
+ without any specific action from the `fractal-server` side.
146
+
147
+ Note: if this function returns `True` for an error that does not
148
+ actually recover, this leads to an infinite loop where
149
+ `fractal-server` keeps polling `squeue` information forever.
150
+
151
+ More info at
152
+ https://github.com/fractal-analytics-platform/fractal-server/issues/2682
153
+
154
+ Args:
155
+ exception: The exception raised by `self.run_squeue`.
156
+ Returns:
157
+ Whether the error is considered recoverable.
158
+ """
159
+ str_exception = str(exception)
160
+ if (
161
+ "slurm_load_jobs" in str_exception
162
+ and "Socket timed out on send/recv operation" in str_exception
163
+ ):
164
+ return True
165
+ else:
166
+ return False
167
+
140
168
  def _get_finished_jobs(self, job_ids: list[str]) -> set[str]:
141
169
  # If there is no Slurm job to check, return right away
142
170
  if not job_ids:
@@ -161,12 +189,26 @@ class BaseSlurmRunner(BaseRunner):
161
189
  {stdout.split()[0]: stdout.split()[1]}
162
190
  )
163
191
  except Exception as e:
164
- logger.warning(
165
- "[_get_finished_jobs] `squeue` failed for "
166
- f"{job_id=}, mark job as completed. "
192
+ msg = (
193
+ f"[_get_finished_jobs] `squeue` failed for {job_id=}. "
167
194
  f"Original error: {str(e)}."
168
195
  )
169
- slurm_statuses.update({str(job_id): "COMPLETED"})
196
+ logger.warning(msg)
197
+ if self._is_squeue_error_recoverable(e):
198
+ logger.warning(
199
+ "[_get_finished_jobs] Recoverable `squeue` "
200
+ f"error - mark {job_id=} as FRACTAL_UNDEFINED and"
201
+ " retry later."
202
+ )
203
+ slurm_statuses.update(
204
+ {str(job_id): "FRACTAL_UNDEFINED"}
205
+ )
206
+ else:
207
+ logger.warning(
208
+ "[_get_finished_jobs] Non-recoverable `squeue`"
209
+ f"error - mark {job_id=} as completed."
210
+ )
211
+ slurm_statuses.update({str(job_id): "COMPLETED"})
170
212
 
171
213
  # If a job is not in `squeue` output, mark it as completed.
172
214
  finished_jobs = {
@@ -1,6 +1,5 @@
1
1
  import argparse
2
2
  import json
3
- import logging
4
3
  import os
5
4
  import sys
6
5
 
@@ -32,7 +31,6 @@ def worker(
32
31
  # Create output folder, if missing
33
32
  out_dir = os.path.dirname(out_fname)
34
33
  if not os.path.exists(out_dir):
35
- logging.debug(f"_slurm.remote.worker: create {out_dir=}")
36
34
  os.mkdir(out_dir)
37
35
 
38
36
  # Execute the job and capture exceptions
@@ -40,10 +38,8 @@ def worker(
40
38
  with open(in_fname) as f:
41
39
  input_data = json.load(f)
42
40
 
43
- server_python_version = input_data["python_version"]
44
- server_fractal_server_version = input_data["fractal_server_version"]
45
-
46
41
  # Fractal-server version must be identical
42
+ server_fractal_server_version = input_data["fractal_server_version"]
47
43
  worker_fractal_server_version = __VERSION__
48
44
  if worker_fractal_server_version != server_fractal_server_version:
49
45
  raise FractalVersionMismatch(
@@ -51,11 +47,16 @@ def worker(
51
47
  f"{worker_fractal_server_version=}"
52
48
  )
53
49
 
54
- # Python version mismatch only raises a warning
55
- worker_python_version = tuple(sys.version_info[:3])
50
+ # Get `worker_python_version` as a `list` since this is the type of
51
+ # `server_python_version` after a JSON dump/load round trip.
52
+ worker_python_version = list(sys.version_info[:3])
53
+
54
+ # Print a warning for Python version mismatch
55
+ server_python_version = input_data["python_version"]
56
56
  if worker_python_version != server_python_version:
57
57
  if worker_python_version[:2] != server_python_version[:2]:
58
- logging.warning(
58
+ print(
59
+ "WARNING: "
59
60
  f"{server_python_version=} but {worker_python_version=}."
60
61
  )
61
62
 
@@ -116,7 +117,6 @@ if __name__ == "__main__":
116
117
  required=True,
117
118
  )
118
119
  parsed_args = parser.parse_args()
119
- logging.debug(f"{parsed_args=}")
120
120
 
121
121
  kwargs = dict(
122
122
  in_fname=parsed_args.input_file,
@@ -20,7 +20,6 @@ from pathlib import Path
20
20
  from ....ssh._fabric import FractalSSH
21
21
  from ...models.v2 import DatasetV2
22
22
  from ...models.v2 import WorkflowV2
23
- from ..exceptions import JobExecutionError
24
23
  from ..executors.slurm_common.get_slurm_config import get_slurm_config
25
24
  from ..executors.slurm_ssh.runner import SlurmSSHRunner
26
25
  from ..set_start_and_last_task_index import set_start_and_last_task_index
@@ -64,18 +63,6 @@ def process_workflow(
64
63
  if isinstance(worker_init, str):
65
64
  worker_init = worker_init.split("\n")
66
65
 
67
- # Create main remote folder
68
- try:
69
- fractal_ssh.mkdir(folder=str(workflow_dir_remote))
70
- logger.info(f"Created {str(workflow_dir_remote)} via SSH.")
71
- except Exception as e:
72
- error_msg = (
73
- f"Could not create {str(workflow_dir_remote)} via SSH.\n"
74
- f"Original error: {str(e)}."
75
- )
76
- logger.error(error_msg)
77
- raise JobExecutionError(info=error_msg)
78
-
79
66
  with SlurmSSHRunner(
80
67
  fractal_ssh=fractal_ssh,
81
68
  root_dir_local=workflow_dir_local,
@@ -165,7 +165,11 @@ class FractalSSH:
165
165
  raise e
166
166
 
167
167
  def _run(
168
- self, *args, label: str, lock_timeout: float | None = None, **kwargs
168
+ self,
169
+ *args,
170
+ label: str,
171
+ lock_timeout: float | None = None,
172
+ **kwargs,
169
173
  ) -> Any:
170
174
  actual_lock_timeout = self.default_lock_timeout
171
175
  if lock_timeout is not None:
@@ -353,6 +357,7 @@ class FractalSSH:
353
357
  label=f"run {cmd}",
354
358
  lock_timeout=actual_lock_timeout,
355
359
  hide=True,
360
+ in_stream=False,
356
361
  )
357
362
  t_1 = time.perf_counter()
358
363
  self.logger.info(
@@ -161,7 +161,7 @@ def collect_local_pixi(
161
161
 
162
162
  # Make task folder 755
163
163
  source_dir = Path(task_group.path, SOURCE_DIR_NAME).as_posix()
164
- command = f"chmod 755 {source_dir} -R"
164
+ command = f"chmod -R 755 {source_dir}"
165
165
  execute_command_sync(
166
166
  command=command,
167
167
  logger_name=LOGGER_NAME,
@@ -145,7 +145,7 @@ def reactivate_local_pixi(
145
145
 
146
146
  # Make task folder 755
147
147
  source_dir = Path(task_group.path, SOURCE_DIR_NAME).as_posix()
148
- command = f"chmod 755 {source_dir} -R"
148
+ command = f"chmod -R 755 {source_dir}"
149
149
  execute_command_sync(
150
150
  command=command,
151
151
  logger_name=LOGGER_NAME,
@@ -221,7 +221,7 @@ def collect_ssh_pixi(
221
221
  source_dir = Path(
222
222
  task_group.path, SOURCE_DIR_NAME
223
223
  ).as_posix()
224
- fractal_ssh.run_command(cmd=f"chmod 755 {source_dir} -R")
224
+ fractal_ssh.run_command(cmd=f"chmod -R 755 {source_dir}")
225
225
 
226
226
  # Read and validate remote manifest file
227
227
  manifest_path_remote = (
@@ -196,7 +196,7 @@ def reactivate_ssh_pixi(
196
196
  activity.log = get_current_log(log_file_path)
197
197
  activity = add_commit_refresh(obj=activity, db=db)
198
198
 
199
- fractal_ssh.run_command(cmd=f"chmod 755 {source_dir} -R")
199
+ fractal_ssh.run_command(cmd=f"chmod -R 755 {source_dir}")
200
200
 
201
201
  # Finalize (write metadata to DB)
202
202
  activity.status = TaskGroupActivityStatusV2.OK
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fractal-server
3
- Version: 2.15.1
3
+ Version: 2.15.2
4
4
  Summary: Backend component of the Fractal analytics platform
5
5
  License: BSD-3-Clause
6
6
  Author: Tommaso Comparin
@@ -1,8 +1,8 @@
1
- fractal_server/__init__.py,sha256=6A0nKt1r_WHhSOgKEGX5ueD-wRkklKFCyvI9s88a16s,23
1
+ fractal_server/__init__.py,sha256=3aUOEwrozdEb6uIH3H2d1pXz5bTLTWOObIlVGVMgxVc,23
2
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
- fractal_server/app/db/__init__.py,sha256=EFzcf6iKemWlOSRj4vtDT63hAE9HBYWh4abYOdDwzMo,2907
5
+ fractal_server/app/db/__init__.py,sha256=U2gwpNyy79iMsK1lg43LRl9z-MW8wiOaICJ7GGdA4yo,2814
6
6
  fractal_server/app/models/__init__.py,sha256=xJWiGAwpXmCpnFMC4c_HTqoUCzMOXrakoGLUH_uMvdA,415
7
7
  fractal_server/app/models/linkusergroup.py,sha256=3KkkE4QIUAlTrBAZs_tVy0pGvAxUAq6yOEjflct_z2M,678
8
8
  fractal_server/app/models/linkuserproject.py,sha256=hvaxh3Lkiy2uUCwB8gvn8RorCpvxSSdzWdCS_U1GL7g,315
@@ -23,14 +23,14 @@ fractal_server/app/routes/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
23
23
  fractal_server/app/routes/admin/v2/__init__.py,sha256=_5lqb6-M8-fZqE1HRMep6pAFYRUKMxrvbZOKs-RXWkw,933
24
24
  fractal_server/app/routes/admin/v2/accounting.py,sha256=YPWwCWylXrJpV4bq_dJ3t6Kn5uuveTrFx-5w1wzfETU,3594
25
25
  fractal_server/app/routes/admin/v2/impersonate.py,sha256=gc4lshfEPFR6W2asH7aKu6hqE6chzusdhAUVV9p51eU,1131
26
- fractal_server/app/routes/admin/v2/job.py,sha256=EOnW645RaacyNof55O_NV_4ONyb7ihM9ORTPb0v68xY,7373
26
+ fractal_server/app/routes/admin/v2/job.py,sha256=VcyXHYjieOKnTAi1NsiO_bK3A6UufUwX2lmWCwa4sa0,7585
27
27
  fractal_server/app/routes/admin/v2/project.py,sha256=MA_LdoEuSuisSGRO43TapMuJ080y5iaUGSAUgKuuKOg,1188
28
28
  fractal_server/app/routes/admin/v2/task.py,sha256=93QIbWZNnqaBhG9R9-RStDX2mpqRNN3G7BIb0KM-jeE,4312
29
29
  fractal_server/app/routes/admin/v2/task_group.py,sha256=biibAvMPD2w-267eyTm3wH2s3mITjiS5gYzwCCwmLbI,7099
30
30
  fractal_server/app/routes/admin/v2/task_group_lifecycle.py,sha256=2J3M9VXWD_0j9jRTZ5APuUXl9E-aVv0qF8K02vvcO3s,9150
31
31
  fractal_server/app/routes/api/__init__.py,sha256=B8l6PSAhR10iZqHEiyTat-_0tkeKdrCigIE6DJGP5b8,638
32
32
  fractal_server/app/routes/api/v2/__init__.py,sha256=D3sRRsqkmZO6kBxUjg40q0aRDsnuXI4sOOfn0xF9JsM,2820
33
- fractal_server/app/routes/api/v2/_aux_functions.py,sha256=P5exwdiNm0ZxtoGw4wxvm_-u8e83gXz8iYEVFuUq_cU,12792
33
+ fractal_server/app/routes/api/v2/_aux_functions.py,sha256=oavMb8HM4lWKMW7_Iyx8Sc9AHKpbmFyyqcPqQLstP_I,13192
34
34
  fractal_server/app/routes/api/v2/_aux_functions_history.py,sha256=Z23xwvBaVEEQ5B-JsWZJpjj4_QqoXqHYONztnbAH6gw,4425
35
35
  fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py,sha256=GpKfw9yj01LmOAuNMTOreU1PFkCKpjK5oCt7_wp35-A,6741
36
36
  fractal_server/app/routes/api/v2/_aux_functions_task_version_update.py,sha256=WLDOYCnb6fnS5avKflyx6yN24Vo1n5kJk5ZyiKbzb8Y,1175
@@ -51,9 +51,9 @@ fractal_server/app/routes/api/v2/task_collection_pixi.py,sha256=LS5xOYRRvI25TyvP
51
51
  fractal_server/app/routes/api/v2/task_group.py,sha256=Wmp5Rt6NQm8_EbdJyi3XOkTXxJTTd4MNIy0ja6K-ifA,9205
52
52
  fractal_server/app/routes/api/v2/task_group_lifecycle.py,sha256=-uS_z8E3__t_twEqhZOzcEcAxZsgnpg-c7Ya9RF3_bs,9998
53
53
  fractal_server/app/routes/api/v2/task_version_update.py,sha256=o8W_C0I84X0u8gAMnCvi8ChiVAKrb5WzUBuJLSuujCA,8235
54
- fractal_server/app/routes/api/v2/workflow.py,sha256=gwMtpfUY_JiTv5_R_q1I9WNkp6nTqEVtYx8jWNJRxcU,10227
54
+ fractal_server/app/routes/api/v2/workflow.py,sha256=SfjegoVO4DaGmDD7OPhWNLkcvZhJKwNX4DTQAcVKk9Q,10699
55
55
  fractal_server/app/routes/api/v2/workflow_import.py,sha256=kOGDaCj0jCGK1WSYGbnUjtUg2U1YxUY9UMH-2ilqJg4,9027
56
- fractal_server/app/routes/api/v2/workflowtask.py,sha256=KQU9rSQNhc6TRFdUYM09zty8Bu150sKvcLGz_tX4Fgo,7548
56
+ fractal_server/app/routes/api/v2/workflowtask.py,sha256=5_SQAG8ztDnaaRXwKalcO69HVpSl-QbrhiI7fCP3YRI,7924
57
57
  fractal_server/app/routes/auth/__init__.py,sha256=fao6CS0WiAjHDTvBzgBVV_bSXFpEAeDBF6Z6q7rRkPc,1658
58
58
  fractal_server/app/routes/auth/_aux_auth.py,sha256=UZgauY0V6mSqjte_sYI1cBl2h8bcbLaeWzgpl1jdJlk,4883
59
59
  fractal_server/app/routes/auth/current_user.py,sha256=EjkwMxUA0l6FLbDJdertHGnuOoSS-HEysmm6l5FkAlY,5903
@@ -81,9 +81,9 @@ fractal_server/app/runner/executors/slurm_common/__init__.py,sha256=47DEQpj8HBSa
81
81
  fractal_server/app/runner/executors/slurm_common/_batching.py,sha256=gbHZIxt90GjUwhB9_UInwVqpX-KdxRQMDeXzUagdL3U,8816
82
82
  fractal_server/app/runner/executors/slurm_common/_job_states.py,sha256=nuV-Zba38kDrRESOVB3gaGbrSPZc4q7YGichQaeqTW0,238
83
83
  fractal_server/app/runner/executors/slurm_common/_slurm_config.py,sha256=U9BONnnwn8eDqDevwUtFSBcvIsxvNgDHirhcQGJ9t9E,15947
84
- fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py,sha256=iXRlTuPvBqqq_I-WYF2IRocPEayMCBxCSJkn_eop6t4,36226
84
+ fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py,sha256=1Sh56lb7NERVtsBMvVs4K7nVHhMy_KDbwquPl1ub8vE,37937
85
85
  fractal_server/app/runner/executors/slurm_common/get_slurm_config.py,sha256=jhoFHauWJm55bIC_v7pFylbK8WgcRJemGu2OjUiRbpQ,7377
86
- fractal_server/app/runner/executors/slurm_common/remote.py,sha256=xWnI6WktHR_7cxUme72ztIeBb4osnbZNu6J2azWn9K8,3765
86
+ fractal_server/app/runner/executors/slurm_common/remote.py,sha256=LHK2Ram8X8q6jNSCxnnwKUwmSJMsyQyRem_VjH53qdw,3811
87
87
  fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py,sha256=K4SdJOKsUWzDlnkb8Ug_UmTx6nBMsTqn9_oKqwE4XDI,3520
88
88
  fractal_server/app/runner/executors/slurm_ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
89
  fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py,sha256=SyW6t4egvbiARph2YkFjc88Hj94fCamZVi50L7ph8VM,996
@@ -98,7 +98,7 @@ fractal_server/app/runner/shutdown.py,sha256=ViSNJyXWU_iWPSDOOMGNh_iQdUFrdPh_jvf
98
98
  fractal_server/app/runner/task_files.py,sha256=V_7aZhu6-c6Y-0XUe-5cZVDrdnXEJhp8pQoUMtx6ko0,4041
99
99
  fractal_server/app/runner/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
100
  fractal_server/app/runner/v2/_local.py,sha256=tTJgABK-zAZmmRzoie_MPNTXJx_zBAXiZiiWl1CC2qo,3035
101
- fractal_server/app/runner/v2/_slurm_ssh.py,sha256=VN89sFwqi139m9wpO1LmExIYIVhmYbEoMgtX7kLAMhE,3302
101
+ fractal_server/app/runner/v2/_slurm_ssh.py,sha256=JlDngsVSOUNqEubDl-5jkIxQQmV4mhTqbMbJVY_rL6M,2840
102
102
  fractal_server/app/runner/v2/_slurm_sudo.py,sha256=Gvsh4tUlc1_3KdF3B7zEqs-YIntC_joLtTGSNFbKKSs,2939
103
103
  fractal_server/app/runner/v2/db_tools.py,sha256=du5dKhMMFMErQXbGIgu9JvO_vtMensodyPsyDeqz1yQ,3324
104
104
  fractal_server/app/runner/v2/deduplicate_list.py,sha256=IVTE4abBU1bUprFTkxrTfYKnvkNTanWQ-KWh_etiT08,645
@@ -185,7 +185,7 @@ fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.p
185
185
  fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py,sha256=TDWCaIoM0Q4SpRWmR9zr_rdp3lJXhCfBPTMhtrP5xYE,3950
186
186
  fractal_server/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
187
187
  fractal_server/ssh/__init__.py,sha256=sVUmzxf7_DuXG1xoLQ1_00fo5NPhi2LJipSmU5EAkPs,124
188
- fractal_server/ssh/_fabric.py,sha256=3Q0nlXctEXtRspQvg00wzCOyYK-0fAJlCowQuXEMk9I,25118
188
+ fractal_server/ssh/_fabric.py,sha256=7fCxTYqkAOaTTm67trfYdYQenOsI4EfrRQoG6x3M5kk,25188
189
189
  fractal_server/string_tools.py,sha256=qLB5u6-4QxXPiZrUeWn_cEo47axj4OXFzDd47kNTIWw,1847
190
190
  fractal_server/syringe.py,sha256=3YJeIALH-wibuJ9R5VMNYUWh7x1-MkWT0SqGcWG5MY8,2795
191
191
  fractal_server/tasks/__init__.py,sha256=kadmVUoIghl8s190_Tt-8f-WBqMi8u8oU4Pvw39NHE8,23
@@ -194,19 +194,19 @@ fractal_server/tasks/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
194
194
  fractal_server/tasks/v2/local/__init__.py,sha256=S842wRersYKBKjc7xbmj0ov8b5i1YuCHa2f_yYuxcaI,312
195
195
  fractal_server/tasks/v2/local/_utils.py,sha256=p2KJ4BvEwJxahICpzbvzrc5-ciLCFnLXWPCwdNGi-3Q,2495
196
196
  fractal_server/tasks/v2/local/collect.py,sha256=MQncScKbWv3g9lrjF8WOhzuEoTEOOgS02RqOJno5csI,11897
197
- fractal_server/tasks/v2/local/collect_pixi.py,sha256=i24MS7yxV0_sHkZJ8rd148n8TGqCPo6Zob5LPks3odk,10753
197
+ fractal_server/tasks/v2/local/collect_pixi.py,sha256=coV9SqOf5rz2dgUFG7uVisPFS0xvXEubFwU7rb3QHe8,10753
198
198
  fractal_server/tasks/v2/local/deactivate.py,sha256=LoEs2TUoHQOq3JfxufW6zroXD-Xx_b-hLtdigEBi1JU,9732
199
199
  fractal_server/tasks/v2/local/deactivate_pixi.py,sha256=_ycvnLIZ8zUFB3fZbCzDlNudh-SSetl4UkyFrClCcUU,3494
200
200
  fractal_server/tasks/v2/local/reactivate.py,sha256=Q43DOadNeFyyfgNP67lUqaXmZsS6onv67XwxH_-5ANA,5756
201
- fractal_server/tasks/v2/local/reactivate_pixi.py,sha256=wF_3gcMWO_8ArJFo4iYh-51LDZDF_1OuYYHrY9eUSL8,7320
201
+ fractal_server/tasks/v2/local/reactivate_pixi.py,sha256=X1gdeuFGPtohjWEZ7OX2v8m6aI7Z93M-y64FqtYjApg,7320
202
202
  fractal_server/tasks/v2/ssh/__init__.py,sha256=vX5aIM9Hbn2T_cIP_LrZ5ekRqJzYm_GSfp-4Iv7kqeI,300
203
203
  fractal_server/tasks/v2/ssh/_utils.py,sha256=ktVH7psQSAhh353fVUe-BwiBZHzTdgXnR-Xv_vfuX0Y,3857
204
204
  fractal_server/tasks/v2/ssh/collect.py,sha256=M9gFD1h9Q1Z-BFQq65dI0vFs6HPCkKQzOkxaLddmChY,14334
205
- fractal_server/tasks/v2/ssh/collect_pixi.py,sha256=q68GSL9yvezqOEc-zt4Ko1d7ZhTlJugoGspRA8JPiJw,13801
205
+ fractal_server/tasks/v2/ssh/collect_pixi.py,sha256=MYxHY5P69P7DdM4uC8FAsAoQBuqr8UJdDti0CPHAn_U,13801
206
206
  fractal_server/tasks/v2/ssh/deactivate.py,sha256=XAIy84cLT9MSTMiN67U-wfOjxMm5s7lmrGwhW0qp7BU,12439
207
207
  fractal_server/tasks/v2/ssh/deactivate_pixi.py,sha256=K0yK_NPUqhFMj6cp6G_0Kfn0Yo7oQux4kT5dFPulnos,4748
208
208
  fractal_server/tasks/v2/ssh/reactivate.py,sha256=NJIgMNFKaXMhbvK0iZOsMwMtsms6Boj9f8N4L01X9Bo,8271
209
- fractal_server/tasks/v2/ssh/reactivate_pixi.py,sha256=o86FNB8pX9Sv_ROrCOJQqxIfDUhJqzzmo3JKsSfCNlA,9784
209
+ fractal_server/tasks/v2/ssh/reactivate_pixi.py,sha256=Vay6kfsrc5XKx2WJVTu_pLhgpuHZDdnrEB6Er8XchYo,9784
210
210
  fractal_server/tasks/v2/templates/1_create_venv.sh,sha256=PK0jdHKtQpda1zULebBaVPORt4t6V17wa4N1ohcj5ac,548
211
211
  fractal_server/tasks/v2/templates/2_pip_install.sh,sha256=jMJPQJXHKznO6fxOOXtFXKPdCmTf1VLLWj_JL_ZdKxo,1644
212
212
  fractal_server/tasks/v2/templates/3_pip_freeze.sh,sha256=JldREScEBI4cD_qjfX4UK7V4aI-FnX9ZvVNxgpSOBFc,168
@@ -230,8 +230,8 @@ fractal_server/types/validators/_workflow_task_arguments_validators.py,sha256=HL
230
230
  fractal_server/urls.py,sha256=QjIKAC1a46bCdiPMu3AlpgFbcv6a4l3ABcd5xz190Og,471
231
231
  fractal_server/utils.py,sha256=Vn35lApt1T1J8nc09sAVqd10Cy0sa3dLipcljI-hkuk,2185
232
232
  fractal_server/zip_tools.py,sha256=tqz_8f-vQ9OBRW-4OQfO6xxY-YInHTyHmZxU7U4PqZo,4885
233
- fractal_server-2.15.1.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
234
- fractal_server-2.15.1.dist-info/METADATA,sha256=kxk3S8JxO5PKXtG0HSpS2jLbnQ0JMF-WHZjrqHxPatY,4243
235
- fractal_server-2.15.1.dist-info/WHEEL,sha256=7dDg4QLnNKTvwIDR9Ac8jJaAmBC_owJrckbC0jjThyA,88
236
- fractal_server-2.15.1.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
237
- fractal_server-2.15.1.dist-info/RECORD,,
233
+ fractal_server-2.15.2.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
234
+ fractal_server-2.15.2.dist-info/METADATA,sha256=ey4BDGRNNq1SLK-pmXThhvEbXwbgyB2jWyTOI3ADuC4,4243
235
+ fractal_server-2.15.2.dist-info/WHEEL,sha256=7dDg4QLnNKTvwIDR9Ac8jJaAmBC_owJrckbC0jjThyA,88
236
+ fractal_server-2.15.2.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
237
+ fractal_server-2.15.2.dist-info/RECORD,,