Self-contained reproductions of Python Workers bugs. Each numbered directory is an independent project that demonstrates a specific issue and its workaround or, after an upstream fix lands, serves as a regression test.
- Lessons learned: dated platform and CI findings.
- Shared engineering guidance: reusable rules shared with the examples repository.
- Ruff rollout retrospective: cross-project evidence and remaining coverage gaps.
git clone https://github.com/cloudflare/python-workers-issuescdinto an issue directory (e.g.cd 2-fastapi-r2-streaming)uv run pywrangler dev- Press the
bkey to open a browser tab and make a request to the Worker
From the repo root, uv run pytest -vv starts pywrangler dev for each local reproduction and prints a Results summary.
- Active issues are marked
xfail(strict=True). The expected outcome isXFAIL(the bug still reproduces). If the bug stops reproducing, the test reportsXPASS(strict)and the run fails, which is the signal to move the issue to Resolved Issues and remove the marker. - Resolved issues are plain regression tests: if the bug comes back, the test fails.
- Each
pywrangler devgets 30 s to printReady on(300 s for2-fastapi-r2-streamingwhenCIis set). CI warms every directory withuv run pywrangler dev --helpbefore the tests, so the budget does not depend on test order. A cold local directory has to vendor packages and fetch wrangler first, so warm it the same way or setPYWRANGLER_DEV_TIMEOUT=<seconds>. - CI also runs
uv run ruff check .andSKIP=ruff uv run pre-commit run --all-files(ruff format, codespell and file hygiene hooks) in the same job.
3-httpx-headers/— The pywrangler-bundled httpx replaces httpcore with ajsfetch.pytransport that strips theUser-Agentheader to avoid browser CORS preflights. Workers aren't browsers — this causes 403s from APIs like GitHub that requireUser-Agent. Workaround: usejs.fetch()directly.4-r2-large-binary-roundtrip/— Returning large R2 objects (>~10MB) through a Python ASGI response crashes the Worker. The data crosses the Pyodide FFI boundary twice (JS→Python→JS), doubling memory usage in Wasm linear memory. Workaround: bypass Python by passing R2'sbodyReadableStream directly to a JSResponse.
2-fastapi-r2-streaming/— Fixed by addingworkers-runtime-sdk>=1.1.1. The Workers ASGI adapter now consumes all chunks fromStreamingResponseasync generators instead of truncating R2 content after the first chunk.
5-sync-http-libraries/—requestsandurllib3can make synchronous outbound HTTP requests from Python Workers handlers.
- Python Workers are in open beta. You can use packages in your Workers by using the pywrangler tool.
- You must add the
python_workerscompatibility flag to your Worker while Python Workers are in open beta.
We'd love your feedback. Join the #python-workers channel in the Cloudflare Developers Discord and let us know what you'd like to see next.
The Apache 2.0 license.