workers-py 1.3.0__py3-none-any.whl → 1.5.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 CHANGED
@@ -4,13 +4,11 @@ import sys
4
4
  import textwrap
5
5
  import click
6
6
 
7
- from pywrangler.utils import setup_logging, write_success
7
+ from .utils import setup_logging, write_success, WRANGLER_COMMAND
8
8
 
9
9
  setup_logging()
10
10
  logger = logging.getLogger("pywrangler")
11
11
 
12
- WRANGLER_COMMAND = ["npx", "--yes", "wrangler"]
13
-
14
12
 
15
13
  class ProxyToWranglerGroup(click.Group):
16
14
  def get_help(self, ctx):
@@ -57,6 +55,11 @@ class ProxyToWranglerGroup(click.Group):
57
55
  if cmd_name in ["dev", "publish", "deploy", "versions"]:
58
56
  ctx.invoke(sync_command, force=False, directly_requested=False)
59
57
 
58
+ if cmd_name == "dev":
59
+ from pywrangler.sync import check_wrangler_version
60
+
61
+ check_wrangler_version()
62
+
60
63
  _proxy_to_wrangler(cmd_name, remaining_args)
61
64
  sys.exit(0)
62
65
 
@@ -90,6 +93,26 @@ def app(ctx, debug=False):
90
93
  logger.setLevel(logging.DEBUG)
91
94
 
92
95
 
96
+ @app.command("types")
97
+ @click.option(
98
+ "-o",
99
+ "--outdir",
100
+ type=click.Path(writable=True),
101
+ help="The output directory to write the generated types. Default: .venv/lib/python3.vv/site-packages/js-stubs",
102
+ )
103
+ @click.option(
104
+ "-c",
105
+ "--config",
106
+ type=click.Path(exists=True, dir_okay=False, readable=True),
107
+ help="Path to Wrangler configuration file",
108
+ )
109
+ def types_command(outdir=None, config=None):
110
+ from .types import wrangler_types
111
+
112
+ wrangler_types(outdir, config)
113
+ raise click.exceptions.Exit(code=0)
114
+
115
+
93
116
  @app.command("sync")
94
117
  @click.option("--force", is_flag=True, help="Force sync even if no changes detected")
95
118
  def sync_command(force=False, directly_requested=True):
pywrangler/sync.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  import os
3
+ import re
3
4
  import shutil
4
5
  import tempfile
5
6
  from contextlib import contextmanager
@@ -229,6 +230,7 @@ def create_workers_venv():
229
230
 
230
231
 
231
232
  MIN_UV_VERSION = (0, 8, 10)
233
+ MIN_WRANGLER_VERSION = (4, 42, 1)
232
234
 
233
235
 
234
236
  def check_uv_version():
@@ -243,6 +245,48 @@ def check_uv_version():
243
245
  raise click.exceptions.Exit(code=1)
244
246
 
245
247
 
248
+ def check_wrangler_version():
249
+ """
250
+ Check that the installed wrangler version is at least 4.42.1.
251
+
252
+ Raises:
253
+ click.exceptions.Exit: If wrangler is not installed or version is too old.
254
+ """
255
+ result = run_command(
256
+ ["npx", "--yes", "wrangler", "--version"], capture_output=True, check=False
257
+ )
258
+ if result.returncode != 0:
259
+ logger.error("Failed to get wrangler version. Is wrangler installed?")
260
+ logger.error("Install wrangler with: npm install wrangler@latest")
261
+ raise click.exceptions.Exit(code=1)
262
+
263
+ # Parse version from output like "wrangler 4.42.1" or " ⛅️ wrangler 4.42.1"
264
+ version_line = result.stdout.strip()
265
+ # Extract version number using regex
266
+ version_match = re.search(r"wrangler\s+(\d+)\.(\d+)\.(\d+)", version_line)
267
+
268
+ if not version_match:
269
+ logger.error(f"Could not parse wrangler version from: {version_line}")
270
+ logger.error("Install wrangler with: npm install wrangler@latest")
271
+ raise click.exceptions.Exit(code=1)
272
+
273
+ major, minor, patch = map(int, version_match.groups())
274
+ current_version = (major, minor, patch)
275
+
276
+ if current_version < MIN_WRANGLER_VERSION:
277
+ min_version_str = ".".join(str(x) for x in MIN_WRANGLER_VERSION)
278
+ current_version_str = ".".join(str(x) for x in current_version)
279
+ logger.error(
280
+ f"wrangler version at least {min_version_str} required, have {current_version_str}."
281
+ )
282
+ logger.error("Update wrangler with: npm install wrangler@latest")
283
+ raise click.exceptions.Exit(code=1)
284
+
285
+ logger.debug(
286
+ f"wrangler version {'.'.join(str(x) for x in current_version)} is sufficient"
287
+ )
288
+
289
+
246
290
  def create_pyodide_venv():
247
291
  if PYODIDE_VENV_PATH.is_dir():
248
292
  logger.debug(
@@ -333,10 +377,9 @@ def _install_requirements_to_vendor(requirements: list[str]):
333
377
 
334
378
 
335
379
  def _install_requirements_to_venv(requirements: list[str]):
336
- # Create a requirements file for .venv-workers that includes webtypy and pyodide-py
380
+ # Create a requirements file for .venv-workers that includes pyodide-py
337
381
  relative_venv_workers_path = VENV_WORKERS_PATH.relative_to(PROJECT_ROOT)
338
382
  requirements = requirements.copy()
339
- requirements.append("webtypy")
340
383
  requirements.append("pyodide-py")
341
384
 
342
385
  logger.info(
pywrangler/types.py ADDED
@@ -0,0 +1,45 @@
1
+ from .utils import WRANGLER_COMMAND, run_command
2
+ from tempfile import TemporaryDirectory
3
+ from pathlib import Path
4
+ import logging
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+ TSCONFIG = """
9
+ {
10
+ "compilerOptions": {
11
+ "target": "esnext",
12
+ "module": "esnext",
13
+ "moduleResolution": "nodenext",
14
+ "lib": ["esnext"]
15
+ },
16
+ "include": ["worker-configuration.d.ts"]
17
+ }
18
+ """
19
+
20
+ PACKAGE_JSON = """
21
+ {
22
+ "dependencies": {
23
+ "typescript": "^5.3.2"
24
+ }
25
+ }
26
+ """
27
+
28
+
29
+ def wrangler_types(outdir_arg: str | None, config: str | None, /):
30
+ args = ["types"]
31
+ if config:
32
+ args += ["--config", config]
33
+ if outdir_arg is None:
34
+ outdir = Path("src")
35
+ else:
36
+ outdir = Path(outdir_arg)
37
+ stubs_dir = outdir / "js-stubs"
38
+ stubs_dir.mkdir(parents=True, exist_ok=True)
39
+ with TemporaryDirectory() as tmp_str:
40
+ tmp = Path(tmp_str)
41
+ run_command(WRANGLER_COMMAND + args + [tmp / "worker-configuration.d.ts"])
42
+ (tmp / "tsconfig.json").write_text(TSCONFIG)
43
+ (tmp / "package.json").write_text(PACKAGE_JSON)
44
+ run_command(["npm", "-C", tmp, "install"])
45
+ run_command(["npx", "@pyodide/ts-to-python", tmp, stubs_dir / "__init__.pyi"])
pywrangler/utils.py CHANGED
@@ -6,6 +6,8 @@ import click
6
6
  from rich.logging import Console, RichHandler
7
7
  from rich.theme import Theme
8
8
 
9
+ WRANGLER_COMMAND = ["npx", "--yes", "wrangler"]
10
+
9
11
  logger = logging.getLogger(__name__)
10
12
 
11
13
  SUCCESS_LEVEL = 100
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: workers-py
3
- Version: 1.3.0
3
+ Version: 1.5.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
@@ -11,6 +11,7 @@ Requires-Python: >=3.10
11
11
  Requires-Dist: click<9.0.0,>=8.0.0
12
12
  Requires-Dist: pyjson5>=1.6.0
13
13
  Requires-Dist: pyodide-cli
14
+ Requires-Dist: pyodide-py
14
15
  Requires-Dist: rich>=13.0.0
15
16
  Provides-Extra: build
16
17
  Requires-Dist: uv~=0.5.23; extra == 'build'
@@ -0,0 +1,11 @@
1
+ pywrangler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ pywrangler/__main__.py,sha256=BnrUM7YiBmlM4HAn2MI9hP1kVNtzeK_kEgQhRy5HTq0,38
3
+ pywrangler/cli.py,sha256=yKLn7GU9lWuw0Lhc6XPl5N9SlJ6y5KNGRQtZJT6a8LM,5728
4
+ pywrangler/metadata.py,sha256=vttmaCtouSr9ADj8ncvNGqeaWEGFP8pamH2T6ohFjnA,408
5
+ pywrangler/sync.py,sha256=CAJdZRZb_xGBX0c4pskfJFrKt8cq6wBpDtPbrWnVJeQ,14248
6
+ pywrangler/types.py,sha256=RyOTVFFC75vJ0NxGzXWJGouRpQ5k4gsf3Jsiq-i_ans,1174
7
+ pywrangler/utils.py,sha256=Vtg0qenIWArGXPhI2jL_4c8tUQByUqQKUVzGbCeoqrw,3318
8
+ workers_py-1.5.0.dist-info/METADATA,sha256=SzUilHhIKFo2gP42JrQzh5CONGXek4wC1OvuGfYkAas,1854
9
+ workers_py-1.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
10
+ workers_py-1.5.0.dist-info/entry_points.txt,sha256=pt6X-Nv5-gSiKUwrnvLwzlSXs9yP37m7zdTAi8f6nAM,50
11
+ workers_py-1.5.0.dist-info/RECORD,,
@@ -1,10 +0,0 @@
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/metadata.py,sha256=vttmaCtouSr9ADj8ncvNGqeaWEGFP8pamH2T6ohFjnA,408
5
- pywrangler/sync.py,sha256=ZzsRY8VsGOQufuQpJ0DxnPH3wXzTu5Myyh8wXs21oXA,12570
6
- pywrangler/utils.py,sha256=wfkT7GbKtgtjHXtV3AjNeb25ohdAfrprdZIlqqidiQU,3269
7
- workers_py-1.3.0.dist-info/METADATA,sha256=Xnj3ud5RhYdFFkndX_urC-jD3YWv_aUHQv2ckr_qiqA,1828
8
- workers_py-1.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
9
- workers_py-1.3.0.dist-info/entry_points.txt,sha256=pt6X-Nv5-gSiKUwrnvLwzlSXs9yP37m7zdTAi8f6nAM,50
10
- workers_py-1.3.0.dist-info/RECORD,,