fractal-server 2.3.0a1__py3-none-any.whl → 2.3.0a2__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/routes/api/v2/task_collection_custom.py +32 -28
- fractal_server/app/schemas/v2/task_collection.py +19 -18
- {fractal_server-2.3.0a1.dist-info → fractal_server-2.3.0a2.dist-info}/METADATA +1 -1
- {fractal_server-2.3.0a1.dist-info → fractal_server-2.3.0a2.dist-info}/RECORD +8 -8
- {fractal_server-2.3.0a1.dist-info → fractal_server-2.3.0a2.dist-info}/LICENSE +0 -0
- {fractal_server-2.3.0a1.dist-info → fractal_server-2.3.0a2.dist-info}/WHEEL +0 -0
- {fractal_server-2.3.0a1.dist-info → fractal_server-2.3.0a2.dist-info}/entry_points.txt +0 -0
fractal_server/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__VERSION__ = "2.3.
|
1
|
+
__VERSION__ = "2.3.0a2"
|
@@ -49,15 +49,33 @@ async def collect_task_custom(
|
|
49
49
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
50
50
|
detail="Cannot infer 'package_root' with 'slurm_ssh' backend.",
|
51
51
|
)
|
52
|
+
package_name_underscore = task_collect.package_name.replace("-", "_")
|
53
|
+
# Note that python_command is then used as part of a subprocess.run
|
54
|
+
# statement: be careful with mixing `'` and `"`.
|
55
|
+
python_command = (
|
56
|
+
"import importlib.util; "
|
57
|
+
"from pathlib import Path; "
|
58
|
+
"init_path=importlib.util.find_spec"
|
59
|
+
f'("{package_name_underscore}").origin; '
|
60
|
+
"print(Path(init_path).parent.as_posix())"
|
61
|
+
)
|
62
|
+
logger.debug(
|
63
|
+
f"Now running {python_command=} through "
|
64
|
+
"{task_collect.python_interpreter}."
|
65
|
+
)
|
52
66
|
res = subprocess.run( # nosec
|
53
67
|
shlex.split(
|
54
|
-
f"{task_collect.python_interpreter} "
|
55
|
-
f"-m pip show {task_collect.package_name}"
|
68
|
+
f"{task_collect.python_interpreter} -c '{python_command}'"
|
56
69
|
),
|
57
70
|
capture_output=True,
|
58
71
|
encoding="utf8",
|
59
72
|
)
|
60
|
-
|
73
|
+
|
74
|
+
if (
|
75
|
+
res.returncode != 0
|
76
|
+
or res.stdout is None
|
77
|
+
or ("\n" in res.stdout.strip("\n"))
|
78
|
+
):
|
61
79
|
raise HTTPException(
|
62
80
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
63
81
|
detail=(
|
@@ -66,23 +84,7 @@ async def collect_task_custom(
|
|
66
84
|
f"Original error: {res.stderr}"
|
67
85
|
),
|
68
86
|
)
|
69
|
-
|
70
|
-
package_root_dir = next(
|
71
|
-
it.split()[1]
|
72
|
-
for it in res.stdout.split("\n")
|
73
|
-
if it.startswith("Location")
|
74
|
-
)
|
75
|
-
except Exception as e:
|
76
|
-
raise HTTPException(
|
77
|
-
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
78
|
-
detail=(
|
79
|
-
"Command 'pip show' gave an unexpected response:\n"
|
80
|
-
"the output should contain 'Location /path/to/package', "
|
81
|
-
f"instead returned: {res.stdout}.\n"
|
82
|
-
f"Original error: {str(e)}"
|
83
|
-
),
|
84
|
-
)
|
85
|
-
package_root = Path(package_root_dir) / task_collect.package_name
|
87
|
+
package_root = Path(res.stdout.strip("\n"))
|
86
88
|
else:
|
87
89
|
package_root = Path(task_collect.package_root)
|
88
90
|
|
@@ -113,23 +115,25 @@ async def collect_task_custom(
|
|
113
115
|
res = db.execute(stm)
|
114
116
|
overlapping_sources_v2 = res.scalars().all()
|
115
117
|
if overlapping_sources_v2:
|
118
|
+
overlapping_tasks_v2_source_and_id = [
|
119
|
+
f"TaskV2 with ID {task.id} already has source='{task.source}'"
|
120
|
+
for task in overlapping_sources_v2
|
121
|
+
]
|
116
122
|
raise HTTPException(
|
117
123
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
118
|
-
detail=(
|
119
|
-
"Some sources already used by some TaskV2: "
|
120
|
-
f"{overlapping_sources_v2}"
|
121
|
-
),
|
124
|
+
detail="\n".join(overlapping_tasks_v2_source_and_id),
|
122
125
|
)
|
123
126
|
stm = select(TaskV1).where(TaskV1.source.in_(sources))
|
124
127
|
res = db.execute(stm)
|
125
128
|
overlapping_sources_v1 = res.scalars().all()
|
126
129
|
if overlapping_sources_v1:
|
130
|
+
overlapping_tasks_v1_source_and_id = [
|
131
|
+
f"TaskV1 with ID {task.id} already has source='{task.source}'\n"
|
132
|
+
for task in overlapping_sources_v1
|
133
|
+
]
|
127
134
|
raise HTTPException(
|
128
135
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
129
|
-
detail=(
|
130
|
-
"Some sources already used by some TaskV1: "
|
131
|
-
f"{overlapping_sources_v1}"
|
132
|
-
),
|
136
|
+
detail="\n".join(overlapping_tasks_v1_source_and_id),
|
133
137
|
)
|
134
138
|
|
135
139
|
task_list_db: list[TaskV2] = _insert_tasks(
|
@@ -56,15 +56,16 @@ class TaskCollectPipV2(BaseModel):
|
|
56
56
|
python_version: Optional[Literal["3.9", "3.10", "3.11", "3.12"]] = None
|
57
57
|
pinned_package_versions: Optional[dict[str, str]] = None
|
58
58
|
|
59
|
+
_package = validator("package", allow_reuse=True)(valstr("package"))
|
60
|
+
_package_version = validator("package_version", allow_reuse=True)(
|
61
|
+
valstr("package_version")
|
62
|
+
)
|
59
63
|
_pinned_package_versions = validator(
|
60
64
|
"pinned_package_versions", allow_reuse=True
|
61
65
|
)(valdictkeys("pinned_package_versions"))
|
62
66
|
_package_extras = validator("package_extras", allow_reuse=True)(
|
63
67
|
valstr("package_extras")
|
64
68
|
)
|
65
|
-
_python_version = validator("python_version", allow_reuse=True)(
|
66
|
-
valstr("python_version")
|
67
|
-
)
|
68
69
|
|
69
70
|
@validator("package")
|
70
71
|
def package_validator(cls, value):
|
@@ -114,6 +115,21 @@ class TaskCollectCustomV2(BaseModel):
|
|
114
115
|
package_name: Optional[str]
|
115
116
|
version: Optional[str]
|
116
117
|
|
118
|
+
# Valstr
|
119
|
+
_python_interpreter = validator("python_interpreter", allow_reuse=True)(
|
120
|
+
valstr("python_interpreter")
|
121
|
+
)
|
122
|
+
_source = validator("source", allow_reuse=True)(valstr("source"))
|
123
|
+
_package_root = validator("package_root", allow_reuse=True)(
|
124
|
+
valstr("package_root", accept_none=True)
|
125
|
+
)
|
126
|
+
_package_name = validator("package_name", allow_reuse=True)(
|
127
|
+
valstr("package_name", accept_none=True)
|
128
|
+
)
|
129
|
+
_version = validator("version", allow_reuse=True)(
|
130
|
+
valstr("version", accept_none=True)
|
131
|
+
)
|
132
|
+
|
117
133
|
@root_validator(pre=True)
|
118
134
|
def one_of_package_root_or_name(cls, values):
|
119
135
|
package_root = values.get("package_root")
|
@@ -154,21 +170,6 @@ class TaskCollectCustomV2(BaseModel):
|
|
154
170
|
)
|
155
171
|
return value
|
156
172
|
|
157
|
-
# Valstr
|
158
|
-
_python_interpreter = validator("python_interpreter", allow_reuse=True)(
|
159
|
-
valstr("python_interpreter")
|
160
|
-
)
|
161
|
-
_source = validator("source", allow_reuse=True)(valstr("source"))
|
162
|
-
_package_root = validator("package_root", allow_reuse=True)(
|
163
|
-
valstr("package_root", accept_none=True)
|
164
|
-
)
|
165
|
-
_package_name = validator("package_name", allow_reuse=True)(
|
166
|
-
valstr("package_name", accept_none=True)
|
167
|
-
)
|
168
|
-
_version = validator("version", allow_reuse=True)(
|
169
|
-
valstr("version", accept_none=True)
|
170
|
-
)
|
171
|
-
|
172
173
|
|
173
174
|
class CollectionStateReadV2(BaseModel):
|
174
175
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
fractal_server/__init__.py,sha256=-
|
1
|
+
fractal_server/__init__.py,sha256=-7gSN0r8k13Hgml0ZA7i3bfRDaNoC2Xlx1lqiv1d1uY,24
|
2
2
|
fractal_server/__main__.py,sha256=CocbzZooX1UtGqPi55GcHGNxnrJXFg5tUU5b3wyFCyo,4958
|
3
3
|
fractal_server/alembic.ini,sha256=MWwi7GzjzawI9cCAK1LW7NxIBQDUqD12-ptJoq5JpP0,3153
|
4
4
|
fractal_server/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -45,7 +45,7 @@ fractal_server/app/routes/api/v2/status.py,sha256=osLexiMOSqmYcEV-41tlrwt9ofyFbt
|
|
45
45
|
fractal_server/app/routes/api/v2/submit.py,sha256=bgGDGPT57oVlUgoI0p3cBuSBim8PqCGLZw8VPEbqjZs,8732
|
46
46
|
fractal_server/app/routes/api/v2/task.py,sha256=bRTtGgL8BBGbT7csVeRB-a54clgU2xHydi5XpcByDxg,8297
|
47
47
|
fractal_server/app/routes/api/v2/task_collection.py,sha256=AvUb6_JVxuxtaa3Nk1qN1x7D_gb13xkfVOXhgEGLwWk,10743
|
48
|
-
fractal_server/app/routes/api/v2/task_collection_custom.py,sha256=
|
48
|
+
fractal_server/app/routes/api/v2/task_collection_custom.py,sha256=3DclNe_AaG01ktBaVy5X6PjnceKgBBwXvKcvHV-9P9A,5196
|
49
49
|
fractal_server/app/routes/api/v2/task_collection_ssh.py,sha256=UJDk2ijGRbB314HbscoU5SEkb9C63gV7HME7JiBB7Qw,3809
|
50
50
|
fractal_server/app/routes/api/v2/task_legacy.py,sha256=P_VJv9v0yzFUBuS-DQHhMVSOe20ecGJJcFBqiiFciOM,1628
|
51
51
|
fractal_server/app/routes/api/v2/workflow.py,sha256=2GlcYNjpvCdjwC_Kn7y0UP16B3pOLSNXBvIVsVDtDKM,11863
|
@@ -135,7 +135,7 @@ fractal_server/app/schemas/v2/manifest.py,sha256=N37IWohcfO3_y2l8rVM0h_1nZq7m4Iz
|
|
135
135
|
fractal_server/app/schemas/v2/project.py,sha256=u7S4B-bote1oGjzAGiZ-DuQIyeRAGqJsI71Tc1EtYE0,736
|
136
136
|
fractal_server/app/schemas/v2/status.py,sha256=SQaUpQkjFq5c5k5J4rOjNhuQaDOEg8lksPhkKmPU5VU,332
|
137
137
|
fractal_server/app/schemas/v2/task.py,sha256=7IfxiZkaVqlARy7WYE_H8m7j_IEcuQaZORUrs6b5YuY,4672
|
138
|
-
fractal_server/app/schemas/v2/task_collection.py,sha256=
|
138
|
+
fractal_server/app/schemas/v2/task_collection.py,sha256=8PG1bOqkfQqORMN0brWf6mHDmijt0bBW-mZsF7cSxUs,6129
|
139
139
|
fractal_server/app/schemas/v2/workflow.py,sha256=Zzx3e-qgkH8le0FUmAx9UrV5PWd7bj14PPXUh_zgZXM,1827
|
140
140
|
fractal_server/app/schemas/v2/workflowtask.py,sha256=atVuVN4aXsVEOmSd-vyg-8_8OnPmqx-gT75rXcn_AlQ,6552
|
141
141
|
fractal_server/app/security/__init__.py,sha256=2-QbwuR-nsuHM_uwKS_WzYvkhnuhO5jUv8UVROetyVk,11169
|
@@ -192,8 +192,8 @@ fractal_server/tasks/v2/templates/_5_pip_show.sh,sha256=3onbKZ0PJkkYronP4_tdMBoA
|
|
192
192
|
fractal_server/tasks/v2/utils.py,sha256=JOyCacb6MNvrwfLNTyLwcz8y79J29YuJeJ2MK5kqXRM,1657
|
193
193
|
fractal_server/urls.py,sha256=5o_qq7PzKKbwq12NHSQZDmDitn5RAOeQ4xufu-2v9Zk,448
|
194
194
|
fractal_server/utils.py,sha256=b7WwFdcFZ8unyT65mloFToYuEDXpQoHRcmRNqrhd_dQ,2115
|
195
|
-
fractal_server-2.3.
|
196
|
-
fractal_server-2.3.
|
197
|
-
fractal_server-2.3.
|
198
|
-
fractal_server-2.3.
|
199
|
-
fractal_server-2.3.
|
195
|
+
fractal_server-2.3.0a2.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
|
196
|
+
fractal_server-2.3.0a2.dist-info/METADATA,sha256=hUMPCeItWLj1fcMcRSLAJmyJuO7uspL2pzgx_XyJlRQ,4427
|
197
|
+
fractal_server-2.3.0a2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
198
|
+
fractal_server-2.3.0a2.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
|
199
|
+
fractal_server-2.3.0a2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|