Python Workers GA: port FastAPI or Hyperdrive without to_js glue

Cloudflare made Python Workers generally available on September 21, 2026. GA here means Python is a first-class, fully supported language on the Cloudflare Developer Platform — not a side experiment. You bring Python code, libraries, and design patterns you already know, and connect them to Workers AI, R2, D1, Hyperdrive, Durable Objects, Queues, Workflows, and the rest of the platform. You can run FastAPI, Django, and Flask inside Python Workers. You can also create a Python Worker inside another Worker using Dynamic Workers.
The buyer question for an owned repo is narrower than the launch list. First promote FastAPI, Hyperdrive, or LangChain plus Workers AI — and which bindings land in Wrangler in that same PR. Do not spray every binding into config on day one. Pick the surface that unblocks the workload you already own, commit that binding, and prove the Pythonic path before you widen the graph.

What GA changes for bindings
Before GA polish, Cloudflare bindings in Python Workers often needed explicit conversion at the RPC boundary. Sending a Python dictionary into a Queue meant glue like to_js with a dict_converter so JavaScript received an object. That forced Python developers to keep the JavaScript environment in mind while writing Workers, and it was a common source of error for humans and AI agents.
The runtime and Python SDK now encapsulate that type conversion. The same send is Pythonic:
self.env.QUEUE.send({"key": "value"})That line is the migration gate. If your Worker still imports pyodide.ffi.to_js only to push dicts into Queue, R2, or similar bindings, delete that glue in the same change that bumps you onto GA-shaped bindings. Keep Wrangler (or your config equivalent) as the source of truth for which bindings exist — the code should read self.env.<BINDING> without a JS translation layer.
Port FastAPI without standing up uvicorn
If your owned API is already FastAPI (or another ASGI app), the Workers path is a thin connector, not a rewrite of handlers. In a native process you would run uvicorn main:app. In Python Workers, Cloudflare’s workers.asgi package bridges the same app:
from workers import asgi
class Default(WorkerEntrypoint):
async def fetch(self, request):
return await asgi.fetch(app, request, self.env)
# or equivalently
Default = asgi.entrypoint(app)Synchronous frameworks such as Django use workers.wsgi the same way: Default = wsgi.entrypoint(app).
Under the hood, WSGI and ASGI are the contracts that keep framework code server-agnostic. On Workers, the platform itself is the web server. Global load balancing and scaling already live in the network, so you do not run uvicorn or Gunicorn inside the Worker. The connectors translate the incoming native request into ASGI or WSGI structures and pipe the response back with minimal overhead. Any Python web framework that speaks WSGI or ASGI can use the same bridge — not only FastAPI, Django, or Flask.
For a repo that already ships FastAPI routes, first promote means: add the ASGI entrypoint, wire env from request.scope["env"] (or the entrypoint helper) where handlers need bindings, and declare only the bindings those handlers call. A minimal Workers AI call from FastAPI looks like reading env from the request scope and awaiting env.AI.run(...) — the launch post shows that pattern with @cf/openai/gpt-oss-120b. Treat that as proof that framework code and platform bindings share one process, not as a requirement to call Workers AI on every route.

11 production screens. Login, database, payments — all wired.
The SaaS Dashboard Kit ships everything already connected. Nothing to set up. Live demo at saas.otf-kit.dev.
Hyperdrive when the blocker was TCP
Relational Python apps were stuck when Python Workers lacked TCP sockets. Drivers such as aiomysql and asyncpg rely on the standard library socket module. Inside WebAssembly, POSIX networking syscalls were stubs that failed. Cloudflare implemented those socket system calls using the Workers connect API, translating open and read operations into the JavaScript calls the Workers runtime already uses. Drivers do not need to know about that bridge.
That is what makes Hyperdrive usable from Python Workers. Connect the database in Hyperdrive, then declare the binding in Wrangler:
"hyperdrive": [
{
"binding": "HYPERDRIVE_MYSQL",
"id": "<your-hyperdrive-id>"
}
]Connect with the driver you already know:
hd = self.env.HYPERDRIVE_MYSQL
conn = await aiomysql.connect(
host=hd.host,
port=int(hd.port),
user=hd.user,
password=hd.password,
db=hd.database,
ssl=None,
)If your owned service’s pain is Postgres or MySQL latency and connection churn at the edge, Hyperdrive is the first promote — not FastAPI cosmetics. Commit the Hyperdrive binding and a single read path before you port the whole ORM surface. Cloudflare documents which packages are supported for Hyperdrive in Python Workers; stay inside that list instead of assuming every wheel works.
Wasm packages, PEP 783, and the agent stack
Packages with native C, C++, or Rust extensions must be cross-compiled to WebAssembly to run in Python Workers. Historically there was no standard way to do that for arbitrary packages, so Cloudflare compiled and hosted a limited set. That limited what you could import.
Cloudflare proposed PEP 783, which standardizes a platform called PyEmscripten for Python in browser-class runtimes. After more than a year of discussion, the proposal was accepted so maintainers can build and publish for PyEmscripten across environments that implement it. The Pyodide build toolchain was stabilized for package maintainers, and PyEmscripten support was added to cibuildwheel. Adoption is still in progress; if a package is missing, the launch post points to Discord or GitHub rather than promising every wheel today.
Separately, AI libraries such as openai, langchain, and mcp historically leaned on HTTP clients (requests, httpx) that broke when low-level sockets were missing. Upstream work routes those clients through the JavaScript fetch API in Wasm environments. Combined with the socket bridge above, the networking stack works inside Python Workers. You can run those libraries natively and combine them with Workers AI or proxy through Cloudflare AI Gateway.
LangChain on Workers AI via langchain-cloudflare looks like this shape:
llm = ChatCloudflareWorkersAI(
model_name="@cf/meta/llama-3.3-70b-instruct-fp8-fast",
binding=self.env.AI,
max_tokens=64,
)
chain = prompt | llm | StrOutputParser()
result = await chain.ainvoke({"profession": "electrician"})If your owned agent already speaks LangChain, first promote is the AI binding plus a pinned model name in config — not a Queue graph. Keep the model string and binding name in-repo so agents and humans do not invent a different Workers AI id at deploy time.

Patterns worth copying after the first promote
Cloudflare’s python-workers-examples collection shows production-shaped combinations once the first binding works.
One pattern is asynchronous AI orchestration: accept a user request, drop it on a Queue, use Workflows to orchestrate image generation through Workers AI, and store the result in R2 — all in Python Workers. That graph needs Queue, Workflows, Workers AI, and R2 bindings declared together. Promote it only after a single-path FastAPI or Hyperdrive or LangChain slice is green; otherwise you debug four bindings at once.
Another pattern is real-time stream processing with Bluesky Jetstream: a Python Worker holds an ATProto/Bluesky Jetstream WebSocket, backed by a Durable Object so long-lived state keeps the connection alive. That promote is Durable Objects first, not Hyperdrive.
Dynamic Workers matter when one Worker must create another Python Worker at runtime. Treat that as a later promote: get the child entrypoint and its bindings correct in isolation before you generate Workers from Workers.
Which binding lands in-repo first
Answer the buyer question with the workload you already own:
- FastAPI / ASGI first when you have an existing ASGI or WSGI app and need global fetch handlers without running uvicorn. Bindings: only what those routes call (often
AI, later Queue or R2). Commitworkers.asgi(orworkers.wsgi) entrypoint plus Wrangler bindings in one PR. - Hyperdrive first when relational drivers were blocked on TCP. Binding:
HYPERDRIVE_*with host, port, user, password, database from the binding object. Prove oneaiomysql(or supported) query path before porting migrations. - LangChain + Workers AI first when the product is already an agent or chain. Binding:
AI, withChatCloudflareWorkersAI(or equivalent) and a model name pinned beside the Worker. Add Queue, Workflows, and R2 only when you adopt the async image pipeline pattern.
In every case, drop remaining to_js glue for dict payloads, keep binding names identical between Wrangler and env, and avoid declaring unused bindings “for later.” Unused bindings widen the blast radius for agents editing config. For timeout and retry discipline on outbound AI calls from owned backends, the same ownership habits in API timeouts and retries for owned AI backends still apply once openai or LangChain is talking through fetch.
Keep structured correlation like structured production logs agents can triage.
Builder checklist
- Confirm GA claims and code shapes on the primary Cloudflare post — Python first-class, Pythonic bindings, ASGI/WSGI connectors, Hyperdrive sockets, PEP 783 / cibuildwheel, LangChain Workers AI example.
- Choose one first promote: FastAPI/ASGI, Hyperdrive, or LangChain+Workers AI.
- Commit only the Wrangler bindings that promote needs; name them the same as
envaccess in code. - Delete
to_jsglue for Queue (and similar) dict sends in the same change. - Only then add Queue+Workflows+Workers AI+R2, Jetstream+Durable Objects, or Dynamic Workers from the examples repo.
Sources
- Python Workers are now generally available — Cloudflare Blog (September 21, 2026): GA meaning, Pythonic bindings, FastAPI/Django/Flask via
workers.asgi/workers.wsgi, Hyperdrive and TCP via Workers connect API, PEP 783 PyEmscripten and cibuildwheel,openai/langchain/mcp,ChatCloudflareWorkersAI, Dynamic Workers, and example patterns (Queue+Workflows+Workers AI+R2; Bluesky Jetstream + Durable Objects).
Ship the product, not the setup.
- 11 production screens — auth, billing, team, analytics, settings
- Real database, payments, and login — all wired on day 1
- AI configs pre-tuned so your agent extends instead of regenerates