fractal-server 2.16.5__py3-none-any.whl → 2.17.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 (113) hide show
  1. fractal_server/__init__.py +1 -1
  2. fractal_server/__main__.py +129 -22
  3. fractal_server/app/db/__init__.py +9 -11
  4. fractal_server/app/models/security.py +7 -3
  5. fractal_server/app/models/user_settings.py +0 -4
  6. fractal_server/app/models/v2/__init__.py +4 -0
  7. fractal_server/app/models/v2/job.py +3 -4
  8. fractal_server/app/models/v2/profile.py +16 -0
  9. fractal_server/app/models/v2/project.py +3 -0
  10. fractal_server/app/models/v2/resource.py +130 -0
  11. fractal_server/app/models/v2/task_group.py +3 -0
  12. fractal_server/app/routes/admin/v2/__init__.py +4 -0
  13. fractal_server/app/routes/admin/v2/_aux_functions.py +55 -0
  14. fractal_server/app/routes/admin/v2/profile.py +86 -0
  15. fractal_server/app/routes/admin/v2/resource.py +229 -0
  16. fractal_server/app/routes/admin/v2/task_group_lifecycle.py +48 -82
  17. fractal_server/app/routes/api/__init__.py +26 -7
  18. fractal_server/app/routes/api/v2/_aux_functions.py +27 -1
  19. fractal_server/app/routes/api/v2/_aux_functions_history.py +2 -2
  20. fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +3 -3
  21. fractal_server/app/routes/api/v2/_aux_functions_tasks.py +7 -7
  22. fractal_server/app/routes/api/v2/project.py +5 -1
  23. fractal_server/app/routes/api/v2/submit.py +32 -24
  24. fractal_server/app/routes/api/v2/task.py +5 -0
  25. fractal_server/app/routes/api/v2/task_collection.py +36 -47
  26. fractal_server/app/routes/api/v2/task_collection_custom.py +11 -5
  27. fractal_server/app/routes/api/v2/task_collection_pixi.py +34 -40
  28. fractal_server/app/routes/api/v2/task_group_lifecycle.py +39 -82
  29. fractal_server/app/routes/api/v2/workflow_import.py +4 -3
  30. fractal_server/app/routes/auth/_aux_auth.py +3 -3
  31. fractal_server/app/routes/auth/current_user.py +45 -7
  32. fractal_server/app/routes/auth/oauth.py +1 -1
  33. fractal_server/app/routes/auth/users.py +9 -0
  34. fractal_server/app/routes/aux/_runner.py +2 -1
  35. fractal_server/app/routes/aux/validate_user_profile.py +62 -0
  36. fractal_server/app/routes/aux/validate_user_settings.py +12 -9
  37. fractal_server/app/schemas/user.py +20 -13
  38. fractal_server/app/schemas/user_settings.py +0 -4
  39. fractal_server/app/schemas/v2/__init__.py +11 -0
  40. fractal_server/app/schemas/v2/profile.py +72 -0
  41. fractal_server/app/schemas/v2/resource.py +117 -0
  42. fractal_server/app/security/__init__.py +6 -13
  43. fractal_server/app/security/signup_email.py +2 -2
  44. fractal_server/app/user_settings.py +2 -12
  45. fractal_server/config/__init__.py +23 -0
  46. fractal_server/config/_database.py +58 -0
  47. fractal_server/config/_email.py +170 -0
  48. fractal_server/config/_init_data.py +27 -0
  49. fractal_server/config/_main.py +216 -0
  50. fractal_server/config/_settings_config.py +7 -0
  51. fractal_server/images/tools.py +3 -3
  52. fractal_server/logger.py +3 -3
  53. fractal_server/main.py +14 -21
  54. fractal_server/migrations/versions/90f6508c6379_drop_useroauth_username.py +36 -0
  55. fractal_server/migrations/versions/a80ac5a352bf_resource_profile.py +195 -0
  56. fractal_server/runner/config/__init__.py +2 -0
  57. fractal_server/runner/config/_local.py +21 -0
  58. fractal_server/runner/config/_slurm.py +128 -0
  59. fractal_server/runner/config/slurm_mem_to_MB.py +63 -0
  60. fractal_server/runner/exceptions.py +4 -0
  61. fractal_server/runner/executors/base_runner.py +17 -7
  62. fractal_server/runner/executors/local/get_local_config.py +21 -86
  63. fractal_server/runner/executors/local/runner.py +48 -5
  64. fractal_server/runner/executors/slurm_common/_batching.py +2 -2
  65. fractal_server/runner/executors/slurm_common/base_slurm_runner.py +59 -25
  66. fractal_server/runner/executors/slurm_common/get_slurm_config.py +38 -54
  67. fractal_server/runner/executors/slurm_common/remote.py +1 -1
  68. fractal_server/runner/executors/slurm_common/{_slurm_config.py → slurm_config.py} +3 -254
  69. fractal_server/runner/executors/slurm_common/slurm_job_task_models.py +1 -1
  70. fractal_server/runner/executors/slurm_ssh/runner.py +12 -14
  71. fractal_server/runner/executors/slurm_sudo/_subprocess_run_as_user.py +2 -2
  72. fractal_server/runner/executors/slurm_sudo/runner.py +12 -12
  73. fractal_server/runner/v2/_local.py +36 -21
  74. fractal_server/runner/v2/_slurm_ssh.py +40 -4
  75. fractal_server/runner/v2/_slurm_sudo.py +41 -11
  76. fractal_server/runner/v2/db_tools.py +1 -1
  77. fractal_server/runner/v2/runner.py +3 -11
  78. fractal_server/runner/v2/runner_functions.py +42 -28
  79. fractal_server/runner/v2/submit_workflow.py +87 -108
  80. fractal_server/runner/versions.py +8 -3
  81. fractal_server/ssh/_fabric.py +6 -6
  82. fractal_server/tasks/config/__init__.py +3 -0
  83. fractal_server/tasks/config/_pixi.py +127 -0
  84. fractal_server/tasks/config/_python.py +51 -0
  85. fractal_server/tasks/v2/local/_utils.py +7 -7
  86. fractal_server/tasks/v2/local/collect.py +13 -5
  87. fractal_server/tasks/v2/local/collect_pixi.py +26 -10
  88. fractal_server/tasks/v2/local/deactivate.py +7 -1
  89. fractal_server/tasks/v2/local/deactivate_pixi.py +5 -1
  90. fractal_server/tasks/v2/local/delete.py +4 -0
  91. fractal_server/tasks/v2/local/reactivate.py +13 -5
  92. fractal_server/tasks/v2/local/reactivate_pixi.py +27 -9
  93. fractal_server/tasks/v2/ssh/_pixi_slurm_ssh.py +11 -10
  94. fractal_server/tasks/v2/ssh/_utils.py +6 -7
  95. fractal_server/tasks/v2/ssh/collect.py +19 -12
  96. fractal_server/tasks/v2/ssh/collect_pixi.py +34 -16
  97. fractal_server/tasks/v2/ssh/deactivate.py +12 -8
  98. fractal_server/tasks/v2/ssh/deactivate_pixi.py +14 -10
  99. fractal_server/tasks/v2/ssh/delete.py +12 -9
  100. fractal_server/tasks/v2/ssh/reactivate.py +18 -12
  101. fractal_server/tasks/v2/ssh/reactivate_pixi.py +36 -17
  102. fractal_server/tasks/v2/templates/4_pip_show.sh +4 -6
  103. fractal_server/tasks/v2/utils_database.py +2 -2
  104. fractal_server/tasks/v2/utils_python_interpreter.py +8 -16
  105. fractal_server/tasks/v2/utils_templates.py +7 -10
  106. fractal_server/utils.py +1 -1
  107. {fractal_server-2.16.5.dist-info → fractal_server-2.17.0a0.dist-info}/METADATA +5 -5
  108. {fractal_server-2.16.5.dist-info → fractal_server-2.17.0a0.dist-info}/RECORD +112 -90
  109. {fractal_server-2.16.5.dist-info → fractal_server-2.17.0a0.dist-info}/WHEEL +1 -1
  110. fractal_server/config.py +0 -906
  111. /fractal_server/{runner → app}/shutdown.py +0 -0
  112. {fractal_server-2.16.5.dist-info → fractal_server-2.17.0a0.dist-info}/entry_points.txt +0 -0
  113. {fractal_server-2.16.5.dist-info → fractal_server-2.17.0a0.dist-info/licenses}/LICENSE +0 -0
@@ -10,6 +10,8 @@ from ._utils import _copy_wheel_file_ssh
10
10
  from ._utils import _customize_and_run_template
11
11
  from ._utils import check_ssh_or_fail_and_cleanup
12
12
  from fractal_server.app.db import get_sync_db
13
+ from fractal_server.app.models import Profile
14
+ from fractal_server.app.models import Resource
13
15
  from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
14
16
  from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
15
17
  from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
@@ -28,8 +30,8 @@ def deactivate_ssh(
28
30
  *,
29
31
  task_group_activity_id: int,
30
32
  task_group_id: int,
31
- ssh_config: SSHConfig,
32
- tasks_base_dir: str,
33
+ resource: Resource,
34
+ profile: Profile,
33
35
  ) -> None:
34
36
  """
35
37
  Deactivate a task group venv.
@@ -37,13 +39,10 @@ def deactivate_ssh(
37
39
  This function is run as a background task, therefore exceptions must be
38
40
  handled.
39
41
 
40
- Arguments:
42
+ Args:
41
43
  task_group_id:
42
44
  task_group_activity_id:
43
45
  ssh_config:
44
- tasks_base_dir:
45
- Only used as a `safe_root` in `remove_dir`, and typically set to
46
- `user_settings.ssh_tasks_dir`.
47
46
  """
48
47
 
49
48
  LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
@@ -66,7 +65,11 @@ def deactivate_ssh(
66
65
  return
67
66
 
68
67
  with SingleUseFractalSSH(
69
- ssh_config=ssh_config,
68
+ ssh_config=SSHConfig(
69
+ user=profile.username,
70
+ host=resource.host,
71
+ key_path=profile.ssh_key_path,
72
+ ),
70
73
  logger_name=LOGGER_NAME,
71
74
  ) as fractal_ssh:
72
75
  try:
@@ -110,6 +113,7 @@ def deactivate_ssh(
110
113
  replacements = get_collection_replacements(
111
114
  task_group=task_group,
112
115
  python_bin="/not/applicable",
116
+ resource=resource,
113
117
  )
114
118
 
115
119
  # Define script_dir_remote and create it if missing
@@ -255,7 +259,7 @@ def deactivate_ssh(
255
259
  logger.info(f"Now removing {task_group.venv_path}.")
256
260
  fractal_ssh.remove_folder(
257
261
  folder=task_group.venv_path,
258
- safe_root=tasks_base_dir,
262
+ safe_root=profile.tasks_remote_dir,
259
263
  )
260
264
  logger.info(f"All good, {task_group.venv_path} removed.")
261
265
  activity.status = TaskGroupActivityStatusV2.OK
@@ -7,6 +7,8 @@ from ..utils_background import get_activity_and_task_group
7
7
  from ..utils_pixi import SOURCE_DIR_NAME
8
8
  from ._utils import check_ssh_or_fail_and_cleanup
9
9
  from fractal_server.app.db import get_sync_db
10
+ from fractal_server.app.models import Profile
11
+ from fractal_server.app.models import Resource
10
12
  from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
11
13
  from fractal_server.logger import reset_logger_handlers
12
14
  from fractal_server.logger import set_logger
@@ -21,8 +23,8 @@ def deactivate_ssh_pixi(
21
23
  *,
22
24
  task_group_activity_id: int,
23
25
  task_group_id: int,
24
- ssh_config: SSHConfig,
25
- tasks_base_dir: str,
26
+ resource: Resource,
27
+ profile: Profile,
26
28
  ) -> None:
27
29
  """
28
30
  Deactivate a pixi task group venv.
@@ -30,13 +32,11 @@ def deactivate_ssh_pixi(
30
32
  This function is run as a background task, therefore exceptions must be
31
33
  handled.
32
34
 
33
- Arguments:
34
- task_group_id:
35
+ Args:
35
36
  task_group_activity_id:
36
- ssh_config:
37
- tasks_base_dir:
38
- Only used as a `safe_root` in `remove_dir`, and typically set to
39
- `user_settings.ssh_tasks_dir`.
37
+ task_group_id:
38
+ resource:
39
+ profile:
40
40
  """
41
41
 
42
42
  LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
@@ -59,7 +59,11 @@ def deactivate_ssh_pixi(
59
59
  return
60
60
 
61
61
  with SingleUseFractalSSH(
62
- ssh_config=ssh_config,
62
+ ssh_config=SSHConfig(
63
+ host=resource.host,
64
+ user=profile.username,
65
+ key_path=profile.ssh_key_path,
66
+ ),
63
67
  logger_name=LOGGER_NAME,
64
68
  ) as fractal_ssh:
65
69
  try:
@@ -101,7 +105,7 @@ def deactivate_ssh_pixi(
101
105
  logger.info(f"Now removing {source_dir}.")
102
106
  fractal_ssh.remove_folder(
103
107
  folder=source_dir,
104
- safe_root=tasks_base_dir,
108
+ safe_root=profile.tasks_remote_dir,
105
109
  )
106
110
  logger.info(f"All good, {source_dir} removed.")
107
111
  activity.status = TaskGroupActivityStatusV2.OK
@@ -6,6 +6,8 @@ from ..utils_background import fail_and_cleanup
6
6
  from ..utils_background import get_activity_and_task_group
7
7
  from ._utils import check_ssh_or_fail_and_cleanup
8
8
  from fractal_server.app.db import get_sync_db
9
+ from fractal_server.app.models import Profile
10
+ from fractal_server.app.models import Resource
9
11
  from fractal_server.app.schemas.v2 import TaskGroupActivityStatusV2
10
12
  from fractal_server.app.schemas.v2 import TaskGroupV2OriginEnum
11
13
  from fractal_server.logger import reset_logger_handlers
@@ -21,8 +23,8 @@ def delete_ssh(
21
23
  *,
22
24
  task_group_activity_id: int,
23
25
  task_group_id: int,
24
- ssh_config: SSHConfig,
25
- tasks_base_dir: str,
26
+ resource: Resource,
27
+ profile: Profile,
26
28
  ) -> None:
27
29
  """
28
30
  Delete a task group.
@@ -30,13 +32,10 @@ def delete_ssh(
30
32
  This function is run as a background task, therefore exceptions must be
31
33
  handled.
32
34
 
33
- Arguments:
35
+ Args:
34
36
  task_group_id:
35
37
  task_group_activity_id:
36
38
  ssh_config:
37
- tasks_base_dir:
38
- Only used as a `safe_root` in `remove_dir`, and typically set to
39
- `user_settings.ssh_tasks_dir`.
40
39
  """
41
40
 
42
41
  LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
@@ -59,7 +58,11 @@ def delete_ssh(
59
58
  return
60
59
 
61
60
  with SingleUseFractalSSH(
62
- ssh_config=ssh_config,
61
+ ssh_config=SSHConfig(
62
+ host=resource.host,
63
+ user=profile.username,
64
+ key_path=profile.ssh_key_path,
65
+ ),
63
66
  logger_name=LOGGER_NAME,
64
67
  ) as fractal_ssh:
65
68
  try:
@@ -86,11 +89,11 @@ def delete_ssh(
86
89
  if task_group.origin != TaskGroupV2OriginEnum.OTHER:
87
90
  logger.debug(
88
91
  f"Removing remote {task_group.path=} "
89
- f"(with {tasks_base_dir=})."
92
+ f"(with {profile.tasks_remote_dir=})."
90
93
  )
91
94
  fractal_ssh.remove_folder(
92
95
  folder=task_group.path,
93
- safe_root=tasks_base_dir,
96
+ safe_root=profile.tasks_remote_dir,
94
97
  )
95
98
  logger.debug(f"Remote {task_group.path=} removed.")
96
99
 
@@ -9,6 +9,8 @@ from ..utils_templates import get_collection_replacements
9
9
  from ._utils import _customize_and_run_template
10
10
  from ._utils import check_ssh_or_fail_and_cleanup
11
11
  from fractal_server.app.db import get_sync_db
12
+ from fractal_server.app.models import Profile
13
+ from fractal_server.app.models import Resource
12
14
  from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
13
15
  from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
14
16
  from fractal_server.logger import reset_logger_handlers
@@ -18,7 +20,7 @@ from fractal_server.ssh._fabric import SSHConfig
18
20
  from fractal_server.tasks.utils import get_log_path
19
21
  from fractal_server.tasks.v2.utils_background import get_current_log
20
22
  from fractal_server.tasks.v2.utils_python_interpreter import (
21
- get_python_interpreter_v2,
23
+ get_python_interpreter,
22
24
  )
23
25
  from fractal_server.tasks.v2.utils_templates import SCRIPTS_SUBFOLDER
24
26
  from fractal_server.utils import get_timestamp
@@ -28,8 +30,8 @@ def reactivate_ssh(
28
30
  *,
29
31
  task_group_activity_id: int,
30
32
  task_group_id: int,
31
- ssh_config: SSHConfig,
32
- tasks_base_dir: str,
33
+ resource: Resource,
34
+ profile: Profile,
33
35
  ) -> None:
34
36
  """
35
37
  Reactivate a task group venv.
@@ -37,13 +39,10 @@ def reactivate_ssh(
37
39
  This function is run as a background task, therefore exceptions must be
38
40
  handled.
39
41
 
40
- Arguments:
42
+ Args:
41
43
  task_group_id:
42
44
  task_group_activity_id:
43
45
  ssh_config:
44
- tasks_base_dir:
45
- Only used as a `safe_root` in `remove_dir`, and typically set to
46
- `user_settings.ssh_tasks_dir`.
47
46
  """
48
47
 
49
48
  LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
@@ -67,7 +66,11 @@ def reactivate_ssh(
67
66
  return
68
67
 
69
68
  with SingleUseFractalSSH(
70
- ssh_config=ssh_config,
69
+ ssh_config=SSHConfig(
70
+ host=resource.host,
71
+ user=profile.username,
72
+ key_path=profile.ssh_key_path,
73
+ ),
71
74
  logger_name=LOGGER_NAME,
72
75
  ) as fractal_ssh:
73
76
  try:
@@ -102,11 +105,14 @@ def reactivate_ssh(
102
105
  activity = add_commit_refresh(obj=activity, db=db)
103
106
 
104
107
  # Prepare replacements for templates
108
+ python_bin = get_python_interpreter(
109
+ python_version=task_group.python_version,
110
+ resource=resource,
111
+ )
105
112
  replacements = get_collection_replacements(
106
113
  task_group=task_group,
107
- python_bin=get_python_interpreter_v2(
108
- python_version=task_group.python_version
109
- ),
114
+ python_bin=python_bin,
115
+ resource=resource,
110
116
  )
111
117
 
112
118
  # Prepare replacements for templates
@@ -181,7 +187,7 @@ def reactivate_ssh(
181
187
  )
182
188
  fractal_ssh.remove_folder(
183
189
  folder=task_group.venv_path,
184
- safe_root=tasks_base_dir,
190
+ safe_root=profile.tasks_remote_dir,
185
191
  )
186
192
  logger.info(f"Deleted folder {task_group.venv_path}")
187
193
  except Exception as rm_e:
@@ -9,14 +9,14 @@ from ._pixi_slurm_ssh import run_script_on_remote_slurm
9
9
  from ._utils import check_ssh_or_fail_and_cleanup
10
10
  from ._utils import edit_pyproject_toml_in_place_ssh
11
11
  from fractal_server.app.db import get_sync_db
12
+ from fractal_server.app.models import Profile
13
+ from fractal_server.app.models import Resource
12
14
  from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
13
15
  from fractal_server.app.schemas.v2 import TaskGroupActivityStatusV2
14
- from fractal_server.config import get_settings
15
16
  from fractal_server.logger import reset_logger_handlers
16
17
  from fractal_server.logger import set_logger
17
18
  from fractal_server.ssh._fabric import SingleUseFractalSSH
18
19
  from fractal_server.ssh._fabric import SSHConfig
19
- from fractal_server.syringe import Inject
20
20
  from fractal_server.tasks.utils import get_log_path
21
21
  from fractal_server.tasks.v2.ssh._utils import _customize_and_run_template
22
22
  from fractal_server.tasks.v2.ssh._utils import _customize_and_send_template
@@ -30,8 +30,8 @@ def reactivate_ssh_pixi(
30
30
  *,
31
31
  task_group_activity_id: int,
32
32
  task_group_id: int,
33
- ssh_config: SSHConfig,
34
- tasks_base_dir: str,
33
+ resource: Resource,
34
+ profile: Profile,
35
35
  ) -> None:
36
36
  """
37
37
  Reactivate a task group venv.
@@ -39,13 +39,11 @@ def reactivate_ssh_pixi(
39
39
  This function is run as a background task, therefore exceptions must be
40
40
  handled.
41
41
 
42
- Arguments:
42
+ Args:
43
43
  task_group_id:
44
44
  task_group_activity_id:
45
- ssh_config:
46
- tasks_base_dir:
47
- Only used as a `safe_root` in `remove_dir`, and typically set to
48
- `user_settings.ssh_tasks_dir`.
45
+ resource:
46
+ profile:
49
47
  """
50
48
 
51
49
  LOGGER_NAME = f"{__name__}.ID{task_group_activity_id}"
@@ -69,7 +67,11 @@ def reactivate_ssh_pixi(
69
67
  return
70
68
 
71
69
  with SingleUseFractalSSH(
72
- ssh_config=ssh_config,
70
+ ssh_config=SSHConfig(
71
+ host=resource.host,
72
+ user=profile.username,
73
+ key_path=profile.ssh_key_path,
74
+ ),
73
75
  logger_name=LOGGER_NAME,
74
76
  ) as fractal_ssh:
75
77
  try:
@@ -103,11 +105,12 @@ def reactivate_ssh_pixi(
103
105
  )
104
106
  return
105
107
 
106
- settings = Inject(get_settings)
107
108
  replacements = {
108
109
  (
109
110
  "__PIXI_HOME__",
110
- settings.pixi.versions[task_group.pixi_version],
111
+ resource.tasks_pixi_config["versions"][
112
+ task_group.pixi_version
113
+ ],
111
114
  ),
112
115
  ("__PACKAGE_DIR__", task_group.path),
113
116
  ("__TAR_GZ_PATH__", task_group.archive_path),
@@ -119,15 +122,27 @@ def reactivate_ssh_pixi(
119
122
  ("__FROZEN_OPTION__", "--frozen"),
120
123
  (
121
124
  "__TOKIO_WORKER_THREADS__",
122
- str(settings.pixi.TOKIO_WORKER_THREADS),
125
+ str(
126
+ resource.tasks_pixi_config[
127
+ "TOKIO_WORKER_THREADS"
128
+ ]
129
+ ),
123
130
  ),
124
131
  (
125
132
  "__PIXI_CONCURRENT_SOLVES__",
126
- str(settings.pixi.PIXI_CONCURRENT_SOLVES),
133
+ str(
134
+ resource.tasks_pixi_config[
135
+ "PIXI_CONCURRENT_SOLVES"
136
+ ]
137
+ ),
127
138
  ),
128
139
  (
129
140
  "__PIXI_CONCURRENT_DOWNLOADS__",
130
- str(settings.pixi.PIXI_CONCURRENT_DOWNLOADS),
141
+ str(
142
+ resource.tasks_pixi_config[
143
+ "PIXI_CONCURRENT_DOWNLOADS"
144
+ ]
145
+ ),
131
146
  ),
132
147
  }
133
148
 
@@ -172,6 +187,7 @@ def reactivate_ssh_pixi(
172
187
  edit_pyproject_toml_in_place_ssh(
173
188
  fractal_ssh=fractal_ssh,
174
189
  pyproject_toml_path=pyproject_toml_path,
190
+ resource=resource,
175
191
  )
176
192
  # Write pixi.lock into `source_dir`
177
193
  pixi_lock_local = Path(tmpdir, "pixi.lock").as_posix()
@@ -217,13 +233,16 @@ def reactivate_ssh_pixi(
217
233
  remote_script3_path,
218
234
  f"chmod -R 755 {source_dir}",
219
235
  ],
220
- slurm_config=settings.pixi.SLURM_CONFIG,
236
+ slurm_config=resource.tasks_pixi_config[
237
+ "SLURM_CONFIG"
238
+ ],
221
239
  fractal_ssh=fractal_ssh,
222
240
  logger_name=LOGGER_NAME,
223
241
  prefix=common_args["prefix"],
224
242
  db=db,
225
243
  activity=activity,
226
244
  log_file_path=log_file_path,
245
+ poll_interval=resource.jobs_poll_interval,
227
246
  )
228
247
  activity.log = get_current_log(log_file_path)
229
248
  activity = add_commit_refresh(obj=activity, db=db)
@@ -244,7 +263,7 @@ def reactivate_ssh_pixi(
244
263
  logger.info(f"Now delete folder {source_dir}")
245
264
  fractal_ssh.remove_folder(
246
265
  folder=source_dir,
247
- safe_root=tasks_base_dir,
266
+ safe_root=profile.tasks_remote_dir,
248
267
  )
249
268
  logger.info(f"Deleted folder {source_dir}")
250
269
  except Exception as rm_e:
@@ -17,21 +17,19 @@ VENVPYTHON=${PACKAGE_ENV_DIR}/bin/python
17
17
  write_log "Python interpreter: $VENVPYTHON"
18
18
  echo
19
19
 
20
- # FIXME: only run pip-show once!
21
-
22
20
  # Extract information about paths
23
21
  # WARNING: this block will fail for paths which include whitespace characters
24
22
  write_log "START pip show"
25
- $VENVPYTHON -m pip show ${PACKAGE_NAME}
23
+ PIP_SHOW_OUTPUT=$($VENVPYTHON -m pip show ${PACKAGE_NAME})
26
24
  write_log "END pip show"
27
25
  echo
28
- PACKAGE_NAME=$($VENVPYTHON -m pip show "$PACKAGE_NAME" | grep "Name:" | cut -d ":" -f 2 | tr -d "[:space:]")
26
+ PACKAGE_NAME=$(echo "$PIP_SHOW_OUTPUT" | grep "Name:" | cut -d ":" -f 2 | tr -d "[:space:]")
29
27
  write_log "Package name: $PACKAGE_NAME"
30
28
  echo
31
- PACKAGE_VERSION=$($VENVPYTHON -m pip show "$PACKAGE_NAME" | grep "Version:" | cut -d ":" -f 2 | tr -d "[:space:]")
29
+ PACKAGE_VERSION=$(echo "$PIP_SHOW_OUTPUT" | grep "Version:" | cut -d ":" -f 2 | tr -d "[:space:]")
32
30
  write_log "Package version: $PACKAGE_VERSION"
33
31
  echo
34
- PACKAGE_PARENT_FOLDER=$($VENVPYTHON -m pip show "$PACKAGE_NAME" | grep "Location:" | cut -d ":" -f 2 | tr -d "[:space:]")
32
+ PACKAGE_PARENT_FOLDER=$(echo "$PIP_SHOW_OUTPUT" | grep "Location:" | cut -d ":" -f 2 | tr -d "[:space:]")
35
33
  write_log "Package parent folder: $PACKAGE_PARENT_FOLDER"
36
34
  echo
37
35
  MANIFEST_RELATIVE_PATH=$($VENVPYTHON -m pip show "$PACKAGE_NAME" --files | grep "__FRACTAL_MANIFEST__.json" | tr -d "[:space:]")
@@ -15,7 +15,7 @@ def create_db_tasks_and_update_task_group_sync(
15
15
  """
16
16
  Create a `TaskGroupV2` with N `TaskV2`s, and insert them into the database.
17
17
 
18
- Arguments:
18
+ Args:
19
19
  task_group_id: ID of an existing `TaskGroupV2` object.
20
20
  task_list: List of `TaskCreateV2` objects to be inserted into the db.
21
21
  db: Synchronous database session
@@ -42,7 +42,7 @@ async def create_db_tasks_and_update_task_group_async(
42
42
  """
43
43
  Create a `TaskGroupV2` with N `TaskV2`s, and insert them into the database.
44
44
 
45
- Arguments:
45
+ Args:
46
46
  task_group_id: ID of an existing `TaskGroupV2` object.
47
47
  task_list: List of `TaskCreateV2` objects to be inserted into the db.
48
48
  db: Synchronous database session
@@ -1,11 +1,9 @@
1
- from typing import Literal
1
+ from fractal_server.app.models import Resource
2
2
 
3
- from fractal_server.config import get_settings
4
- from fractal_server.syringe import Inject
5
3
 
6
-
7
- def get_python_interpreter_v2(
8
- python_version: Literal["3.9", "3.10", "3.11", "3.12"],
4
+ def get_python_interpreter(
5
+ python_version: str,
6
+ resource: Resource,
9
7
  ) -> str:
10
8
  """
11
9
  Return the path to the Python interpreter
@@ -21,13 +19,7 @@ def get_python_interpreter_v2(
21
19
  interpreter: string representing the python executable or its path
22
20
  """
23
21
 
24
- if python_version not in ["3.9", "3.10", "3.11", "3.12", "3.13"]:
25
- raise ValueError(f"Invalid {python_version=}.")
26
-
27
- settings = Inject(get_settings)
28
- version_underscore = python_version.replace(".", "_")
29
- key = f"FRACTAL_TASKS_PYTHON_{version_underscore}"
30
- value = getattr(settings, key)
31
- if value is None:
32
- raise ValueError(f"Requested {python_version=}, but {key}={value}.")
33
- return value
22
+ python_path = resource.tasks_python_config["versions"].get(python_version)
23
+ if python_path is None:
24
+ raise ValueError(f"Requested {python_version=} is not available.")
25
+ return python_path
@@ -1,9 +1,8 @@
1
1
  from pathlib import Path
2
2
 
3
+ from fractal_server.app.models import Resource
3
4
  from fractal_server.app.models.v2 import TaskGroupV2
4
- from fractal_server.config import get_settings
5
5
  from fractal_server.logger import set_logger
6
- from fractal_server.syringe import Inject
7
6
 
8
7
  TEMPLATES_DIR = Path(__file__).parent / "templates"
9
8
 
@@ -12,7 +11,7 @@ SCRIPTS_SUBFOLDER = "scripts"
12
11
  logger = set_logger(__name__)
13
12
 
14
13
 
15
- def _check_pixi_frozen_option(replacements: list[tuple[str, str]]):
14
+ def _check_pixi_frozen_option(replacements: set[tuple[str, str]]):
16
15
  try:
17
16
  replacement = next(
18
17
  rep for rep in replacements if rep[0] == "__FROZEN_OPTION__"
@@ -28,7 +27,7 @@ def customize_template(
28
27
  template_name: str,
29
28
  replacements: set[tuple[str, str]],
30
29
  script_path: str,
31
- ) -> str:
30
+ ) -> None:
32
31
  """
33
32
  Customize a bash-script template and write it to disk.
34
33
 
@@ -84,16 +83,14 @@ def parse_script_pip_show_stdout(stdout: str) -> dict[str, str]:
84
83
 
85
84
 
86
85
  def get_collection_replacements(
87
- *, task_group: TaskGroupV2, python_bin: str
88
- ) -> dict[str, str]:
89
- settings = Inject(get_settings)
90
-
86
+ *, task_group: TaskGroupV2, python_bin: str, resource: Resource
87
+ ) -> list[tuple[str, str]]:
91
88
  replacements = [
92
89
  ("__PACKAGE_NAME__", task_group.pkg_name),
93
90
  ("__PACKAGE_ENV_DIR__", task_group.venv_path),
94
91
  ("__PYTHON__", python_bin),
95
92
  ("__INSTALL_STRING__", task_group.pip_install_string),
96
- ("__FRACTAL_PIP_CACHE_DIR_ARG__", settings.PIP_CACHE_DIR_ARG),
93
+ ("__FRACTAL_PIP_CACHE_DIR_ARG__", resource.pip_cache_dir_arg),
97
94
  (
98
95
  "__PINNED_PACKAGE_LIST_PRE__",
99
96
  task_group.pinned_package_versions_pre_string,
@@ -104,6 +101,6 @@ def get_collection_replacements(
104
101
  ),
105
102
  ]
106
103
  logger.info(
107
- f"Cache-dir argument for `pip install`: {settings.PIP_CACHE_DIR_ARG}"
104
+ f"Cache-dir argument for `pip install`: {resource.pip_cache_dir_arg}"
108
105
  )
109
106
  return replacements
fractal_server/utils.py CHANGED
@@ -41,7 +41,7 @@ def execute_command_sync(
41
41
  If the command returns a return code different from zero, a `RuntimeError`
42
42
  is raised.
43
43
 
44
- Arguments:
44
+ Args:
45
45
  command: Command to be executed.
46
46
  logger_name: Name of the logger.
47
47
  allow_char: Argument propagated to `validate_cmd`.
@@ -1,12 +1,12 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: fractal-server
3
- Version: 2.16.5
3
+ Version: 2.17.0a0
4
4
  Summary: Backend component of the Fractal analytics platform
5
- License: BSD-3-Clause
5
+ License-Expression: BSD-3-Clause
6
+ License-File: LICENSE
6
7
  Author: Tommaso Comparin
7
8
  Author-email: tommaso.comparin@exact-lab.it
8
9
  Requires-Python: >=3.11,<3.14
9
- Classifier: License :: OSI Approved :: BSD License
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
@@ -19,7 +19,7 @@ Requires-Dist: fastapi-users[oauth] (>=14,<15)
19
19
  Requires-Dist: gunicorn (>=23.0,<24.0)
20
20
  Requires-Dist: packaging (>=25.0.0,<26.0.0)
21
21
  Requires-Dist: psycopg[binary] (>=3.1.0,<4.0.0)
22
- Requires-Dist: pydantic (>=2.11.0,<2.12.0)
22
+ Requires-Dist: pydantic (>=2.12.0,<2.13.0)
23
23
  Requires-Dist: pydantic-settings (==2.11.0)
24
24
  Requires-Dist: python-dotenv (>=1.1.0,<1.2.0)
25
25
  Requires-Dist: sqlalchemy[asyncio] (>=2.0.23,<2.1)