workers-py 1.1.8__py3-none-any.whl → 1.2.0__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.
- pywrangler/cli.py +0 -2
- pywrangler/sync.py +101 -145
- {workers_py-1.1.8.dist-info → workers_py-1.2.0.dist-info}/METADATA +1 -1
- workers_py-1.2.0.dist-info/RECORD +9 -0
- workers_py-1.1.8.dist-info/RECORD +0 -9
- {workers_py-1.1.8.dist-info → workers_py-1.2.0.dist-info}/WHEEL +0 -0
- {workers_py-1.1.8.dist-info → workers_py-1.2.0.dist-info}/entry_points.txt +0 -0
pywrangler/cli.py
CHANGED
|
@@ -106,7 +106,6 @@ def sync_command(force=False, directly_requested=True):
|
|
|
106
106
|
create_pyodide_venv,
|
|
107
107
|
create_workers_venv,
|
|
108
108
|
parse_requirements,
|
|
109
|
-
install_pyodide_build,
|
|
110
109
|
install_requirements,
|
|
111
110
|
)
|
|
112
111
|
|
|
@@ -129,7 +128,6 @@ def sync_command(force=False, directly_requested=True):
|
|
|
129
128
|
create_workers_venv()
|
|
130
129
|
|
|
131
130
|
# Set up Pyodide virtual env
|
|
132
|
-
install_pyodide_build()
|
|
133
131
|
create_pyodide_venv()
|
|
134
132
|
|
|
135
133
|
# Generate requirements.txt from pyproject.toml by directly parsing the TOML file then install into vendor folder.
|
pywrangler/sync.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
3
|
import shutil
|
|
4
|
-
from pathlib import Path
|
|
5
4
|
import tempfile
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Literal
|
|
6
8
|
|
|
7
9
|
import click
|
|
8
10
|
|
|
@@ -58,8 +60,33 @@ def check_wrangler_config():
|
|
|
58
60
|
raise click.exceptions.Exit(code=1)
|
|
59
61
|
|
|
60
62
|
|
|
61
|
-
def _get_python_version():
|
|
62
|
-
|
|
63
|
+
def _get_python_version() -> Literal["3.12", "3.13"]:
|
|
64
|
+
res = os.environ.get("_PYWRANGLER_PYTHON_VERSION", "3.12")
|
|
65
|
+
match res:
|
|
66
|
+
case "3.12" | "3.13":
|
|
67
|
+
return res
|
|
68
|
+
case _:
|
|
69
|
+
raise ValueError(
|
|
70
|
+
f"Unexpected value for Python version '{res}', expected '3.12' or '3.13'"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _get_uv_pyodide_interp_name():
|
|
75
|
+
match _get_python_version():
|
|
76
|
+
case "3.12":
|
|
77
|
+
v = "3.12.7"
|
|
78
|
+
case "3.13":
|
|
79
|
+
v = "3.13.2"
|
|
80
|
+
return f"cpython-{v}-emscripten-wasm32-musl"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _get_pyodide_index():
|
|
84
|
+
match _get_python_version():
|
|
85
|
+
case "3.12":
|
|
86
|
+
v = "0.27.7"
|
|
87
|
+
case "3.13":
|
|
88
|
+
v = "0.28.3"
|
|
89
|
+
return "https://index.pyodide.org/" + v
|
|
63
90
|
|
|
64
91
|
|
|
65
92
|
def _get_venv_python_version() -> str | None:
|
|
@@ -125,65 +152,18 @@ def create_workers_venv():
|
|
|
125
152
|
)
|
|
126
153
|
|
|
127
154
|
|
|
128
|
-
def _get_pyodide_cli_path():
|
|
129
|
-
venv_bin_path = VENV_WORKERS_PATH / ("Scripts" if os.name == "nt" else "bin")
|
|
130
|
-
pyodide_cli_path = venv_bin_path / ("pyodide.exe" if os.name == "nt" else "pyodide")
|
|
131
|
-
return pyodide_cli_path
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def install_pyodide_build():
|
|
135
|
-
pyodide_cli_path = _get_pyodide_cli_path()
|
|
136
|
-
|
|
137
|
-
if pyodide_cli_path.is_file():
|
|
138
|
-
logger.debug(
|
|
139
|
-
f"pyodide-build CLI already found at {pyodide_cli_path} (skipping install.)"
|
|
140
|
-
)
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
logger.debug(
|
|
144
|
-
f"Installing pyodide-build in {VENV_WORKERS_PATH} using 'uv pip install'..."
|
|
145
|
-
)
|
|
146
|
-
venv_bin_path = pyodide_cli_path.parent
|
|
147
|
-
|
|
148
|
-
# Ensure the python executable path is correct for the venv
|
|
149
|
-
venv_python_executable = venv_bin_path / (
|
|
150
|
-
"python.exe" if os.name == "nt" else "python"
|
|
151
|
-
)
|
|
152
|
-
if not venv_python_executable.is_file():
|
|
153
|
-
logger.error(f"Python executable not found at {venv_python_executable}")
|
|
154
|
-
raise click.exceptions.Exit(code=1)
|
|
155
|
-
|
|
156
|
-
run_command(["uv", "pip", "install", "-p", str(venv_python_executable), "pip"])
|
|
157
|
-
|
|
158
|
-
run_command(
|
|
159
|
-
[
|
|
160
|
-
"uv",
|
|
161
|
-
"pip",
|
|
162
|
-
"install",
|
|
163
|
-
"-p",
|
|
164
|
-
str(venv_python_executable),
|
|
165
|
-
"pyodide-build==0.30.7",
|
|
166
|
-
]
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
|
|
170
155
|
def create_pyodide_venv():
|
|
171
|
-
pyodide_cli_path = _get_pyodide_cli_path()
|
|
172
156
|
if PYODIDE_VENV_PATH.is_dir():
|
|
173
157
|
logger.debug(
|
|
174
158
|
f"Pyodide virtual environment at {PYODIDE_VENV_PATH} already exists."
|
|
175
159
|
)
|
|
176
160
|
return
|
|
177
161
|
|
|
178
|
-
# Workaround to fix caching issue on some machines.
|
|
179
|
-
#
|
|
180
|
-
# Fix is here: pyodide/pyodide-build#239
|
|
181
|
-
logger.debug("Installing xbuildenv...")
|
|
182
|
-
run_command([str(pyodide_cli_path), "xbuildenv", "install"])
|
|
183
|
-
|
|
184
162
|
logger.debug(f"Creating Pyodide virtual environment at {PYODIDE_VENV_PATH}...")
|
|
185
163
|
PYODIDE_VENV_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
186
|
-
|
|
164
|
+
interp_name = _get_uv_pyodide_interp_name()
|
|
165
|
+
run_command(["uv", "python", "install", interp_name])
|
|
166
|
+
run_command(["uv", "venv", PYODIDE_VENV_PATH, "--python", interp_name])
|
|
187
167
|
|
|
188
168
|
|
|
189
169
|
def parse_requirements() -> list[str]:
|
|
@@ -202,6 +182,15 @@ def parse_requirements() -> list[str]:
|
|
|
202
182
|
raise click.exceptions.Exit(code=1)
|
|
203
183
|
|
|
204
184
|
|
|
185
|
+
@contextmanager
|
|
186
|
+
def temp_requirements_file(requirements: list[str]):
|
|
187
|
+
# Write dependencies to a requirements.txt-style temp file.
|
|
188
|
+
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as temp_file:
|
|
189
|
+
temp_file.write("\n".join(requirements))
|
|
190
|
+
temp_file.flush()
|
|
191
|
+
yield temp_file.name
|
|
192
|
+
|
|
193
|
+
|
|
205
194
|
def _install_requirements_to_vendor(requirements: list[str]):
|
|
206
195
|
vendor_path = PROJECT_ROOT / "python_modules"
|
|
207
196
|
logger.debug(f"Using vendor path: {vendor_path}")
|
|
@@ -212,97 +201,72 @@ def _install_requirements_to_vendor(requirements: list[str]):
|
|
|
212
201
|
)
|
|
213
202
|
return
|
|
214
203
|
|
|
215
|
-
#
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
# Install packages into vendor directory
|
|
224
|
-
vendor_path.mkdir(parents=True, exist_ok=True)
|
|
225
|
-
pyodide_venv_pip_path = (
|
|
226
|
-
PYODIDE_VENV_PATH
|
|
227
|
-
/ ("Scripts" if os.name == "nt" else "bin")
|
|
228
|
-
/ ("pip.exe" if os.name == "nt" else "pip")
|
|
229
|
-
)
|
|
230
|
-
relative_vendor_path = vendor_path.relative_to(PROJECT_ROOT)
|
|
231
|
-
logger.info(
|
|
232
|
-
f"Installing packages into [bold]{relative_vendor_path}[/bold] using Pyodide pip...",
|
|
233
|
-
extra={"markup": True},
|
|
234
|
-
)
|
|
204
|
+
# Install packages into vendor directory
|
|
205
|
+
vendor_path.mkdir(parents=True, exist_ok=True)
|
|
206
|
+
relative_vendor_path = vendor_path.relative_to(PROJECT_ROOT)
|
|
207
|
+
logger.info(
|
|
208
|
+
f"Installing packages into [bold]{relative_vendor_path}[/bold]...",
|
|
209
|
+
extra={"markup": True},
|
|
210
|
+
)
|
|
211
|
+
with temp_requirements_file(requirements) as requirements_file:
|
|
235
212
|
run_command(
|
|
236
213
|
[
|
|
237
|
-
|
|
214
|
+
"uv",
|
|
215
|
+
"pip",
|
|
238
216
|
"install",
|
|
239
|
-
"-
|
|
240
|
-
str(vendor_path),
|
|
217
|
+
"--no-build",
|
|
241
218
|
"-r",
|
|
242
|
-
|
|
243
|
-
|
|
219
|
+
requirements_file,
|
|
220
|
+
"--extra-index-url",
|
|
221
|
+
_get_pyodide_index(),
|
|
222
|
+
"--index-strategy",
|
|
223
|
+
"unsafe-best-match",
|
|
224
|
+
],
|
|
225
|
+
env=os.environ | {"VIRTUAL_ENV": PYODIDE_VENV_PATH},
|
|
226
|
+
)
|
|
227
|
+
pyv = _get_python_version()
|
|
228
|
+
shutil.rmtree(vendor_path)
|
|
229
|
+
shutil.copytree(
|
|
230
|
+
PYODIDE_VENV_PATH / f"lib/python{pyv}/site-packages", vendor_path
|
|
244
231
|
)
|
|
245
232
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
233
|
+
# Create a pyvenv.cfg file in python_modules to mark it as a virtual environment
|
|
234
|
+
(vendor_path / "pyvenv.cfg").touch()
|
|
235
|
+
VENDOR_TOKEN.touch()
|
|
249
236
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
237
|
+
logger.info(
|
|
238
|
+
f"Packages installed in [bold]{relative_vendor_path}[/bold].",
|
|
239
|
+
extra={"markup": True},
|
|
240
|
+
)
|
|
254
241
|
|
|
255
242
|
|
|
256
243
|
def _install_requirements_to_venv(requirements: list[str]):
|
|
257
244
|
# Create a requirements file for .venv-workers that includes webtypy and pyodide-py
|
|
258
|
-
|
|
259
|
-
|
|
245
|
+
relative_venv_workers_path = VENV_WORKERS_PATH.relative_to(PROJECT_ROOT)
|
|
260
246
|
requirements = requirements.copy()
|
|
261
247
|
requirements.append("webtypy")
|
|
262
248
|
requirements.append("pyodide-py")
|
|
263
249
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
250
|
+
logger.info(
|
|
251
|
+
f"Installing packages into [bold]{relative_venv_workers_path}[/bold]...",
|
|
252
|
+
extra={"markup": True},
|
|
253
|
+
)
|
|
254
|
+
with temp_requirements_file(requirements) as requirements_file:
|
|
255
|
+
run_command(
|
|
256
|
+
[
|
|
257
|
+
"uv",
|
|
258
|
+
"pip",
|
|
259
|
+
"install",
|
|
260
|
+
"-r",
|
|
261
|
+
requirements_file,
|
|
262
|
+
],
|
|
263
|
+
env=os.environ | {"VIRTUAL_ENV": VENV_WORKERS_PATH},
|
|
276
264
|
)
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
f"Installing packages into [bold]{relative_venv_workers_path}[/bold] using uv pip...",
|
|
283
|
-
extra={"markup": True},
|
|
284
|
-
)
|
|
285
|
-
run_command(
|
|
286
|
-
[
|
|
287
|
-
"uv",
|
|
288
|
-
"pip",
|
|
289
|
-
"install",
|
|
290
|
-
"-p",
|
|
291
|
-
venv_python_executable,
|
|
292
|
-
"-r",
|
|
293
|
-
str(temp_file_path),
|
|
294
|
-
]
|
|
295
|
-
)
|
|
296
|
-
VENV_WORKERS_TOKEN.write_text("")
|
|
297
|
-
logger.info(
|
|
298
|
-
f"Packages installed in [bold]{relative_venv_workers_path}[/bold].",
|
|
299
|
-
extra={"markup": True},
|
|
300
|
-
)
|
|
301
|
-
else:
|
|
302
|
-
logger.warning(
|
|
303
|
-
f"Python executable not found at {venv_python_executable}. Skipping installation in [bold]{relative_venv_workers_path}[/bold].",
|
|
304
|
-
extra={"markup": True},
|
|
305
|
-
)
|
|
265
|
+
VENV_WORKERS_TOKEN.touch()
|
|
266
|
+
logger.info(
|
|
267
|
+
f"Packages installed in [bold]{relative_venv_workers_path}[/bold].",
|
|
268
|
+
extra={"markup": True},
|
|
269
|
+
)
|
|
306
270
|
|
|
307
271
|
|
|
308
272
|
def install_requirements(requirements: list[str]):
|
|
@@ -310,6 +274,12 @@ def install_requirements(requirements: list[str]):
|
|
|
310
274
|
_install_requirements_to_venv(requirements)
|
|
311
275
|
|
|
312
276
|
|
|
277
|
+
def _is_out_of_date(token: Path, time: float) -> bool:
|
|
278
|
+
if not token.exists():
|
|
279
|
+
return True
|
|
280
|
+
return time > token.stat().st_mtime
|
|
281
|
+
|
|
282
|
+
|
|
313
283
|
def is_sync_needed():
|
|
314
284
|
"""
|
|
315
285
|
Checks if pyproject.toml has been modified since the last sync.
|
|
@@ -323,20 +293,6 @@ def is_sync_needed():
|
|
|
323
293
|
return True
|
|
324
294
|
|
|
325
295
|
pyproject_mtime = PYPROJECT_TOML_PATH.stat().st_mtime
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
return True
|
|
330
|
-
|
|
331
|
-
venv_mtime = VENV_WORKERS_TOKEN.stat().st_mtime
|
|
332
|
-
venv_needs_update = pyproject_mtime > venv_mtime
|
|
333
|
-
if venv_needs_update:
|
|
334
|
-
return True
|
|
335
|
-
|
|
336
|
-
# Check if vendor directory exists and get its timestamp
|
|
337
|
-
if not VENDOR_TOKEN.exists():
|
|
338
|
-
return True
|
|
339
|
-
|
|
340
|
-
vendor_mtime = VENDOR_TOKEN.stat().st_mtime
|
|
341
|
-
vendor_needs_update = pyproject_mtime > vendor_mtime
|
|
342
|
-
return vendor_needs_update
|
|
296
|
+
return _is_out_of_date(VENDOR_TOKEN, pyproject_mtime) or _is_out_of_date(
|
|
297
|
+
VENV_WORKERS_TOKEN, pyproject_mtime
|
|
298
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: workers-py
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A set of libraries and tools for Python Workers
|
|
5
5
|
Project-URL: Homepage, https://github.com/cloudflare/workers-py
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/cloudflare/workers-py/issues
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
pywrangler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
pywrangler/__main__.py,sha256=BnrUM7YiBmlM4HAn2MI9hP1kVNtzeK_kEgQhRy5HTq0,38
|
|
3
|
+
pywrangler/cli.py,sha256=3hMjtOOib3HaTqCkuMGQe7MbBZNnim2ByHcDY4JxFlw,5091
|
|
4
|
+
pywrangler/sync.py,sha256=4LbwXlzi7YXXhsgYT4unJOwX9DHSLI6sREcf7abJAks,9441
|
|
5
|
+
pywrangler/utils.py,sha256=wfkT7GbKtgtjHXtV3AjNeb25ohdAfrprdZIlqqidiQU,3269
|
|
6
|
+
workers_py-1.2.0.dist-info/METADATA,sha256=s9qthgJPRW1inmDvDDl_UR-V0KA-M_Hewwp6GJxjq04,1749
|
|
7
|
+
workers_py-1.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
8
|
+
workers_py-1.2.0.dist-info/entry_points.txt,sha256=pt6X-Nv5-gSiKUwrnvLwzlSXs9yP37m7zdTAi8f6nAM,50
|
|
9
|
+
workers_py-1.2.0.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
pywrangler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
pywrangler/__main__.py,sha256=BnrUM7YiBmlM4HAn2MI9hP1kVNtzeK_kEgQhRy5HTq0,38
|
|
3
|
-
pywrangler/cli.py,sha256=BnGGrdksWP-qBj-b0ipji-61Q0kZJohyr2KZZz-XG5s,5150
|
|
4
|
-
pywrangler/sync.py,sha256=vcaL_jOWCC6vWEaJnTnbnxgdgFeW30pndRcMRWOv5pw,11286
|
|
5
|
-
pywrangler/utils.py,sha256=wfkT7GbKtgtjHXtV3AjNeb25ohdAfrprdZIlqqidiQU,3269
|
|
6
|
-
workers_py-1.1.8.dist-info/METADATA,sha256=rE874u2Io40CgLK1JPBMO5eMTwyychzO14K_jO5Emrc,1749
|
|
7
|
-
workers_py-1.1.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
8
|
-
workers_py-1.1.8.dist-info/entry_points.txt,sha256=pt6X-Nv5-gSiKUwrnvLwzlSXs9yP37m7zdTAi8f6nAM,50
|
|
9
|
-
workers_py-1.1.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|