fractal-server 2.14.5__py3-none-any.whl → 2.14.6__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.
- fractal_server/__init__.py +1 -1
- fractal_server/app/db/__init__.py +2 -2
- fractal_server/app/models/security.py +8 -8
- fractal_server/app/models/user_settings.py +8 -10
- fractal_server/app/models/v2/accounting.py +2 -3
- fractal_server/app/models/v2/dataset.py +1 -2
- fractal_server/app/models/v2/history.py +3 -4
- fractal_server/app/models/v2/job.py +10 -11
- fractal_server/app/models/v2/project.py +1 -2
- fractal_server/app/models/v2/task.py +13 -14
- fractal_server/app/models/v2/task_group.py +15 -16
- fractal_server/app/models/v2/workflow.py +1 -2
- fractal_server/app/models/v2/workflowtask.py +6 -7
- fractal_server/app/routes/admin/v2/accounting.py +3 -4
- fractal_server/app/routes/admin/v2/job.py +13 -14
- fractal_server/app/routes/admin/v2/project.py +2 -4
- fractal_server/app/routes/admin/v2/task.py +11 -13
- fractal_server/app/routes/admin/v2/task_group.py +15 -17
- fractal_server/app/routes/admin/v2/task_group_lifecycle.py +5 -8
- fractal_server/app/routes/api/v2/__init__.py +2 -0
- fractal_server/app/routes/api/v2/_aux_functions.py +7 -9
- fractal_server/app/routes/api/v2/_aux_functions_history.py +1 -1
- fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +1 -3
- fractal_server/app/routes/api/v2/_aux_functions_tasks.py +5 -6
- fractal_server/app/routes/api/v2/dataset.py +6 -8
- fractal_server/app/routes/api/v2/history.py +5 -8
- fractal_server/app/routes/api/v2/images.py +2 -3
- fractal_server/app/routes/api/v2/job.py +5 -6
- fractal_server/app/routes/api/v2/pre_submission_checks.py +1 -3
- fractal_server/app/routes/api/v2/project.py +2 -4
- fractal_server/app/routes/api/v2/status_legacy.py +2 -4
- fractal_server/app/routes/api/v2/submit.py +3 -4
- fractal_server/app/routes/api/v2/task.py +6 -7
- fractal_server/app/routes/api/v2/task_collection.py +11 -13
- fractal_server/app/routes/api/v2/task_collection_custom.py +4 -4
- fractal_server/app/routes/api/v2/task_group.py +6 -8
- fractal_server/app/routes/api/v2/task_group_lifecycle.py +6 -9
- fractal_server/app/routes/api/v2/task_version_update.py +270 -0
- fractal_server/app/routes/api/v2/workflow.py +5 -6
- fractal_server/app/routes/api/v2/workflow_import.py +3 -5
- fractal_server/app/routes/api/v2/workflowtask.py +2 -114
- fractal_server/app/routes/auth/current_user.py +2 -2
- fractal_server/app/routes/pagination.py +2 -3
- fractal_server/app/runner/exceptions.py +15 -16
- fractal_server/app/runner/executors/base_runner.py +3 -3
- fractal_server/app/runner/executors/call_command_wrapper.py +1 -1
- fractal_server/app/runner/executors/local/get_local_config.py +2 -3
- fractal_server/app/runner/executors/local/runner.py +1 -1
- fractal_server/app/runner/executors/slurm_common/_batching.py +2 -3
- fractal_server/app/runner/executors/slurm_common/_slurm_config.py +27 -29
- fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +11 -14
- fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +2 -3
- fractal_server/app/runner/executors/slurm_common/remote.py +2 -2
- fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/run_subprocess.py +2 -3
- fractal_server/app/runner/executors/slurm_ssh/runner.py +3 -4
- fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +1 -2
- fractal_server/app/runner/executors/slurm_sudo/runner.py +6 -7
- fractal_server/app/runner/set_start_and_last_task_index.py +2 -5
- fractal_server/app/runner/shutdown.py +5 -11
- fractal_server/app/runner/task_files.py +3 -5
- fractal_server/app/runner/v2/_local.py +3 -4
- fractal_server/app/runner/v2/_slurm_ssh.py +4 -5
- fractal_server/app/runner/v2/_slurm_sudo.py +7 -8
- fractal_server/app/runner/v2/runner.py +4 -5
- fractal_server/app/runner/v2/runner_functions.py +4 -5
- fractal_server/app/runner/v2/submit_workflow.py +7 -10
- fractal_server/app/runner/v2/task_interface.py +2 -3
- fractal_server/app/runner/versions.py +1 -2
- fractal_server/app/schemas/user.py +2 -4
- fractal_server/app/schemas/user_group.py +1 -2
- fractal_server/app/schemas/user_settings.py +19 -21
- fractal_server/app/schemas/v2/dataset.py +2 -3
- fractal_server/app/schemas/v2/dumps.py +13 -15
- fractal_server/app/schemas/v2/history.py +6 -7
- fractal_server/app/schemas/v2/job.py +17 -18
- fractal_server/app/schemas/v2/manifest.py +12 -13
- fractal_server/app/schemas/v2/status_legacy.py +2 -2
- fractal_server/app/schemas/v2/task.py +29 -30
- fractal_server/app/schemas/v2/task_collection.py +8 -9
- fractal_server/app/schemas/v2/task_group.py +22 -23
- fractal_server/app/schemas/v2/workflow.py +1 -2
- fractal_server/app/schemas/v2/workflowtask.py +27 -29
- fractal_server/app/security/__init__.py +10 -12
- fractal_server/config.py +32 -33
- fractal_server/images/models.py +2 -4
- fractal_server/images/tools.py +4 -7
- fractal_server/logger.py +3 -5
- fractal_server/ssh/_fabric.py +37 -12
- fractal_server/string_tools.py +2 -2
- fractal_server/syringe.py +1 -1
- fractal_server/tasks/v2/local/collect.py +2 -3
- fractal_server/tasks/v2/local/deactivate.py +1 -1
- fractal_server/tasks/v2/local/reactivate.py +1 -1
- fractal_server/tasks/v2/ssh/collect.py +256 -245
- fractal_server/tasks/v2/ssh/deactivate.py +210 -187
- fractal_server/tasks/v2/ssh/reactivate.py +154 -146
- fractal_server/tasks/v2/utils_background.py +2 -3
- fractal_server/types/__init__.py +1 -2
- fractal_server/types/validators/_filter_validators.py +1 -2
- fractal_server/utils.py +4 -5
- fractal_server/zip_tools.py +1 -1
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.6.dist-info}/METADATA +2 -3
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.6.dist-info}/RECORD +107 -107
- fractal_server/app/history/__init__.py +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.6.dist-info}/LICENSE +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.6.dist-info}/WHEEL +0 -0
- {fractal_server-2.14.5.dist-info → fractal_server-2.14.6.dist-info}/entry_points.txt +0 -0
@@ -14,7 +14,8 @@ from fractal_server.app.schemas.v2 import TaskGroupActivityActionV2
|
|
14
14
|
from fractal_server.app.schemas.v2.task_group import TaskGroupActivityStatusV2
|
15
15
|
from fractal_server.logger import reset_logger_handlers
|
16
16
|
from fractal_server.logger import set_logger
|
17
|
-
from fractal_server.ssh._fabric import
|
17
|
+
from fractal_server.ssh._fabric import SingleUseFractalSSH
|
18
|
+
from fractal_server.ssh._fabric import SSHConfig
|
18
19
|
from fractal_server.tasks.utils import get_log_path
|
19
20
|
from fractal_server.tasks.v2.utils_background import get_current_log
|
20
21
|
from fractal_server.tasks.v2.utils_python_interpreter import (
|
@@ -28,7 +29,7 @@ def reactivate_ssh(
|
|
28
29
|
*,
|
29
30
|
task_group_activity_id: int,
|
30
31
|
task_group_id: int,
|
31
|
-
|
32
|
+
ssh_config: SSHConfig,
|
32
33
|
tasks_base_dir: str,
|
33
34
|
) -> None:
|
34
35
|
"""
|
@@ -40,7 +41,7 @@ def reactivate_ssh(
|
|
40
41
|
Arguments:
|
41
42
|
task_group_id:
|
42
43
|
task_group_activity_id:
|
43
|
-
|
44
|
+
ssh_config:
|
44
45
|
tasks_base_dir:
|
45
46
|
Only used as a `safe_root` in `remove_dir`, and typically set to
|
46
47
|
`user_settings.ssh_tasks_dir`.
|
@@ -55,150 +56,157 @@ def reactivate_ssh(
|
|
55
56
|
log_file_path=log_file_path,
|
56
57
|
)
|
57
58
|
|
58
|
-
with
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
replacements = get_collection_replacements(
|
112
|
-
task_group=task_group,
|
113
|
-
python_bin=get_python_interpreter_v2(
|
114
|
-
python_version=task_group.python_version
|
115
|
-
),
|
116
|
-
)
|
117
|
-
|
118
|
-
# Prepare replacements for templates
|
119
|
-
pip_freeze_file_local = f"{tmpdir}/pip_freeze.txt"
|
120
|
-
pip_freeze_file_remote = (
|
121
|
-
Path(task_group.path) / "_tmp_pip_freeze.txt"
|
122
|
-
).as_posix()
|
123
|
-
with open(pip_freeze_file_local, "w") as f:
|
124
|
-
f.write(task_group.pip_freeze)
|
125
|
-
fractal_ssh.send_file(
|
126
|
-
local=pip_freeze_file_local, remote=pip_freeze_file_remote
|
127
|
-
)
|
128
|
-
replacements.append(
|
129
|
-
("__PIP_FREEZE_FILE__", pip_freeze_file_remote)
|
130
|
-
)
|
131
|
-
|
132
|
-
# Define script_dir_remote and create it if missing
|
133
|
-
script_dir_remote = (
|
134
|
-
Path(task_group.path) / SCRIPTS_SUBFOLDER
|
135
|
-
).as_posix()
|
136
|
-
fractal_ssh.mkdir(folder=script_dir_remote, parents=True)
|
137
|
-
|
138
|
-
# Prepare common arguments for `_customize_and_run_template`
|
139
|
-
common_args = dict(
|
140
|
-
replacements=replacements,
|
141
|
-
script_dir_local=(
|
142
|
-
Path(tmpdir) / SCRIPTS_SUBFOLDER
|
143
|
-
).as_posix(),
|
144
|
-
script_dir_remote=script_dir_remote,
|
145
|
-
prefix=(
|
146
|
-
f"{int(time.time())}_"
|
147
|
-
f"{TaskGroupActivityActionV2.REACTIVATE.value}"
|
148
|
-
),
|
149
|
-
fractal_ssh=fractal_ssh,
|
150
|
-
logger_name=LOGGER_NAME,
|
151
|
-
)
|
152
|
-
|
153
|
-
# Create remote directory for scripts
|
154
|
-
fractal_ssh.mkdir(folder=script_dir_remote)
|
155
|
-
|
156
|
-
logger.info("start - create venv")
|
157
|
-
_customize_and_run_template(
|
158
|
-
template_filename="1_create_venv.sh",
|
159
|
-
**common_args,
|
160
|
-
)
|
161
|
-
logger.info("end - create venv")
|
162
|
-
activity.log = get_current_log(log_file_path)
|
163
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
164
|
-
|
165
|
-
logger.info("start - install from pip freeze")
|
166
|
-
_customize_and_run_template(
|
167
|
-
template_filename="6_pip_install_from_freeze.sh",
|
168
|
-
**common_args,
|
169
|
-
)
|
170
|
-
logger.info("end - install from pip freeze")
|
171
|
-
activity.log = get_current_log(log_file_path)
|
172
|
-
activity.status = TaskGroupActivityStatusV2.OK
|
173
|
-
activity.timestamp_ended = get_timestamp()
|
174
|
-
activity = add_commit_refresh(obj=activity, db=db)
|
175
|
-
task_group.active = True
|
176
|
-
task_group = add_commit_refresh(obj=task_group, db=db)
|
177
|
-
logger.info("END")
|
178
|
-
|
179
|
-
reset_logger_handlers(logger)
|
180
|
-
|
181
|
-
except Exception as reactivate_e:
|
182
|
-
# Delete corrupted venv_path
|
59
|
+
with SingleUseFractalSSH(
|
60
|
+
ssh_config=ssh_config,
|
61
|
+
logger_name=LOGGER_NAME,
|
62
|
+
) as fractal_ssh:
|
63
|
+
|
64
|
+
with next(get_sync_db()) as db:
|
65
|
+
|
66
|
+
# Get main objects from db
|
67
|
+
activity = db.get(TaskGroupActivityV2, task_group_activity_id)
|
68
|
+
task_group = db.get(TaskGroupV2, task_group_id)
|
69
|
+
if activity is None or task_group is None:
|
70
|
+
# Use `logging` directly
|
71
|
+
logging.error(
|
72
|
+
"Cannot find database rows with "
|
73
|
+
f"{task_group_id=} and {task_group_activity_id=}:\n"
|
74
|
+
f"{task_group=}\n{activity=}. Exit."
|
75
|
+
)
|
76
|
+
return
|
77
|
+
|
78
|
+
# Log some info
|
79
|
+
logger.info("START")
|
80
|
+
for key, value in task_group.model_dump().items():
|
81
|
+
logger.debug(f"task_group.{key}: {value}")
|
82
|
+
|
83
|
+
# Check that SSH connection works
|
84
|
+
try:
|
85
|
+
fractal_ssh.check_connection()
|
86
|
+
except Exception as e:
|
87
|
+
logger.error("Cannot establish SSH connection.")
|
88
|
+
fail_and_cleanup(
|
89
|
+
task_group=task_group,
|
90
|
+
task_group_activity=activity,
|
91
|
+
logger_name=LOGGER_NAME,
|
92
|
+
log_file_path=log_file_path,
|
93
|
+
exception=e,
|
94
|
+
db=db,
|
95
|
+
)
|
96
|
+
return
|
97
|
+
|
98
|
+
# Check that the (remote) task_group venv_path does not exist
|
99
|
+
if fractal_ssh.remote_exists(task_group.venv_path):
|
100
|
+
error_msg = f"{task_group.venv_path} already exists."
|
101
|
+
logger.error(error_msg)
|
102
|
+
fail_and_cleanup(
|
103
|
+
task_group=task_group,
|
104
|
+
task_group_activity=activity,
|
105
|
+
logger_name=LOGGER_NAME,
|
106
|
+
log_file_path=log_file_path,
|
107
|
+
exception=FileExistsError(error_msg),
|
108
|
+
db=db,
|
109
|
+
)
|
110
|
+
return
|
111
|
+
|
183
112
|
try:
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
113
|
+
activity.status = TaskGroupActivityStatusV2.ONGOING
|
114
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
115
|
+
|
116
|
+
# Prepare replacements for templates
|
117
|
+
replacements = get_collection_replacements(
|
118
|
+
task_group=task_group,
|
119
|
+
python_bin=get_python_interpreter_v2(
|
120
|
+
python_version=task_group.python_version
|
121
|
+
),
|
188
122
|
)
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
123
|
+
|
124
|
+
# Prepare replacements for templates
|
125
|
+
pip_freeze_file_local = f"{tmpdir}/pip_freeze.txt"
|
126
|
+
pip_freeze_file_remote = (
|
127
|
+
Path(task_group.path) / "_tmp_pip_freeze.txt"
|
128
|
+
).as_posix()
|
129
|
+
with open(pip_freeze_file_local, "w") as f:
|
130
|
+
f.write(task_group.pip_freeze)
|
131
|
+
fractal_ssh.send_file(
|
132
|
+
local=pip_freeze_file_local,
|
133
|
+
remote=pip_freeze_file_remote,
|
134
|
+
)
|
135
|
+
replacements.append(
|
136
|
+
("__PIP_FREEZE_FILE__", pip_freeze_file_remote)
|
137
|
+
)
|
138
|
+
|
139
|
+
# Define script_dir_remote and create it if missing
|
140
|
+
script_dir_remote = (
|
141
|
+
Path(task_group.path) / SCRIPTS_SUBFOLDER
|
142
|
+
).as_posix()
|
143
|
+
fractal_ssh.mkdir(folder=script_dir_remote, parents=True)
|
144
|
+
|
145
|
+
# Prepare common arguments for _customize_and_run_template
|
146
|
+
common_args = dict(
|
147
|
+
replacements=replacements,
|
148
|
+
script_dir_local=(
|
149
|
+
Path(tmpdir) / SCRIPTS_SUBFOLDER
|
150
|
+
).as_posix(),
|
151
|
+
script_dir_remote=script_dir_remote,
|
152
|
+
prefix=(
|
153
|
+
f"{int(time.time())}_"
|
154
|
+
f"{TaskGroupActivityActionV2.REACTIVATE}"
|
155
|
+
),
|
156
|
+
fractal_ssh=fractal_ssh,
|
157
|
+
logger_name=LOGGER_NAME,
|
194
158
|
)
|
195
159
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
160
|
+
# Create remote directory for scripts
|
161
|
+
fractal_ssh.mkdir(folder=script_dir_remote)
|
162
|
+
|
163
|
+
logger.info("start - create venv")
|
164
|
+
_customize_and_run_template(
|
165
|
+
template_filename="1_create_venv.sh",
|
166
|
+
**common_args,
|
167
|
+
)
|
168
|
+
logger.info("end - create venv")
|
169
|
+
activity.log = get_current_log(log_file_path)
|
170
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
171
|
+
|
172
|
+
logger.info("start - install from pip freeze")
|
173
|
+
_customize_and_run_template(
|
174
|
+
template_filename="6_pip_install_from_freeze.sh",
|
175
|
+
**common_args,
|
176
|
+
)
|
177
|
+
logger.info("end - install from pip freeze")
|
178
|
+
activity.log = get_current_log(log_file_path)
|
179
|
+
activity.status = TaskGroupActivityStatusV2.OK
|
180
|
+
activity.timestamp_ended = get_timestamp()
|
181
|
+
activity = add_commit_refresh(obj=activity, db=db)
|
182
|
+
task_group.active = True
|
183
|
+
task_group = add_commit_refresh(obj=task_group, db=db)
|
184
|
+
logger.info("END")
|
185
|
+
|
186
|
+
reset_logger_handlers(logger)
|
187
|
+
|
188
|
+
except Exception as reactivate_e:
|
189
|
+
# Delete corrupted venv_path
|
190
|
+
try:
|
191
|
+
logger.info(
|
192
|
+
f"Now delete folder {task_group.venv_path}"
|
193
|
+
)
|
194
|
+
fractal_ssh.remove_folder(
|
195
|
+
folder=task_group.venv_path,
|
196
|
+
safe_root=tasks_base_dir,
|
197
|
+
)
|
198
|
+
logger.info(f"Deleted folder {task_group.venv_path}")
|
199
|
+
except Exception as rm_e:
|
200
|
+
logger.error(
|
201
|
+
"Removing folder failed.\n"
|
202
|
+
f"Original error:\n{str(rm_e)}"
|
203
|
+
)
|
204
|
+
|
205
|
+
fail_and_cleanup(
|
206
|
+
task_group=task_group,
|
207
|
+
task_group_activity=activity,
|
208
|
+
logger_name=LOGGER_NAME,
|
209
|
+
log_file_path=log_file_path,
|
210
|
+
exception=reactivate_e,
|
211
|
+
db=db,
|
212
|
+
)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from pathlib import Path
|
2
|
-
from typing import Optional
|
3
2
|
from typing import TypeVar
|
4
3
|
|
5
4
|
from sqlalchemy.orm import Session as DBSyncSession
|
@@ -53,7 +52,7 @@ def _prepare_tasks_metadata(
|
|
53
52
|
package_manifest: ManifestV2,
|
54
53
|
python_bin: Path,
|
55
54
|
package_root: Path,
|
56
|
-
package_version:
|
55
|
+
package_version: str | None = None,
|
57
56
|
) -> list[TaskCreateV2]:
|
58
57
|
"""
|
59
58
|
Based on the package manifest and additional info, prepare the task list.
|
@@ -101,5 +100,5 @@ def _prepare_tasks_metadata(
|
|
101
100
|
|
102
101
|
|
103
102
|
def get_current_log(logger_file_path: str) -> str:
|
104
|
-
with open(logger_file_path
|
103
|
+
with open(logger_file_path) as f:
|
105
104
|
return f.read()
|
fractal_server/types/__init__.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from typing import Annotated
|
2
2
|
from typing import Any
|
3
|
-
from typing import Optional
|
4
3
|
from typing import Union
|
5
4
|
|
6
5
|
from pydantic import AfterValidator
|
@@ -70,7 +69,7 @@ ImageAttributes = Annotated[
|
|
70
69
|
AfterValidator(valdict_keys),
|
71
70
|
]
|
72
71
|
ImageAttributesWithNone = Annotated[
|
73
|
-
dict[str,
|
72
|
+
dict[str, ImageAttributeValue | None],
|
74
73
|
AfterValidator(valdict_keys),
|
75
74
|
]
|
76
75
|
AttributeFilters = Annotated[
|
@@ -1,11 +1,10 @@
|
|
1
1
|
from typing import Any
|
2
|
-
from typing import Union
|
3
2
|
|
4
3
|
from ._common_validators import valdict_keys
|
5
4
|
|
6
5
|
|
7
6
|
def validate_attribute_filters(
|
8
|
-
attribute_filters: dict[str, list[
|
7
|
+
attribute_filters: dict[str, list[int | float | str | bool]]
|
9
8
|
) -> dict[str, list[Any]]:
|
10
9
|
attribute_filters = valdict_keys(attribute_filters)
|
11
10
|
for key, values in attribute_filters.items():
|
fractal_server/utils.py
CHANGED
@@ -19,7 +19,6 @@ import subprocess # nosec
|
|
19
19
|
from datetime import datetime
|
20
20
|
from datetime import timezone
|
21
21
|
from pathlib import Path
|
22
|
-
from typing import Optional
|
23
22
|
|
24
23
|
from .logger import get_logger
|
25
24
|
from .string_tools import validate_cmd
|
@@ -35,8 +34,8 @@ def get_timestamp() -> datetime:
|
|
35
34
|
async def execute_command_async(
|
36
35
|
*,
|
37
36
|
command: str,
|
38
|
-
cwd:
|
39
|
-
logger_name:
|
37
|
+
cwd: Path | None = None,
|
38
|
+
logger_name: str | None = None,
|
40
39
|
) -> str:
|
41
40
|
"""
|
42
41
|
Execute arbitrary command
|
@@ -82,8 +81,8 @@ async def execute_command_async(
|
|
82
81
|
def execute_command_sync(
|
83
82
|
*,
|
84
83
|
command: str,
|
85
|
-
logger_name:
|
86
|
-
allow_char:
|
84
|
+
logger_name: str | None = None,
|
85
|
+
allow_char: str | None = None,
|
87
86
|
) -> str:
|
88
87
|
"""
|
89
88
|
Execute arbitrary command
|
fractal_server/zip_tools.py
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: fractal-server
|
3
|
-
Version: 2.14.
|
3
|
+
Version: 2.14.6
|
4
4
|
Summary: Backend component of the Fractal analytics platform
|
5
5
|
License: BSD-3-Clause
|
6
6
|
Author: Tommaso Comparin
|
7
7
|
Author-email: tommaso.comparin@exact-lab.it
|
8
|
-
Requires-Python: >=3.
|
8
|
+
Requires-Python: >=3.11,<3.13
|
9
9
|
Classifier: License :: OSI Approved :: BSD License
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: Programming Language :: Python :: 3.10
|
12
11
|
Classifier: Programming Language :: Python :: 3.11
|
13
12
|
Classifier: Programming Language :: Python :: 3.12
|
14
13
|
Requires-Dist: alembic (>=1.13.1,<2.0.0)
|