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.
@@ -1 +1 @@
1
- __VERSION__ = "2.3.0a1"
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
- if res.returncode != 0:
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
- try:
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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fractal-server
3
- Version: 2.3.0a1
3
+ Version: 2.3.0a2
4
4
  Summary: Server 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,4 +1,4 @@
1
- fractal_server/__init__.py,sha256=-AWvxo9_iEn6AeN7kh3LOcvbooEszyPH4VcZe0uRR2w,24
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=eGCUN2Qr6iSTD5YMM-v_tMSXD7HpLlo5XIxULJHcJT0,4950
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=TU7Bl6qZNAgAkY63PtLte0SO0WctHb6uqX3iv7ezbt8,6053
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.0a1.dist-info/LICENSE,sha256=QKAharUuhxL58kSoLizKJeZE3mTCBnX6ucmz8W0lxlk,1576
196
- fractal_server-2.3.0a1.dist-info/METADATA,sha256=ygT18QSalCHoGqzBvEUf8I1qTl9hyXcI5pBmiao9XCQ,4427
197
- fractal_server-2.3.0a1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
198
- fractal_server-2.3.0a1.dist-info/entry_points.txt,sha256=8tV2kynvFkjnhbtDnxAqImL6HMVKsopgGfew0DOp5UY,58
199
- fractal_server-2.3.0a1.dist-info/RECORD,,
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,,