Foreign Function Interface (FFI)
Via Pyodide ↗, Python Workers provide a Foreign Function Interface (FFI) ↗ to JavaScript. This allows you to:
- Use bindings to resources on Cloudflare, including Workers AI, Vectorize, R2, KV, D1, Queues, Durable Objects, Service Bindings and more.
- Use JavaScript globals, like
Request,Response, andfetch(). - Use the full feature set of Cloudflare Workers — if an API is accessible in JavaScript, you can also access it in a Python Worker, writing exclusively Python code.
The details of Pyodide's Foreign Function Interface are documented here ↗, and Workers written in Python are able to take full advantage of this.
Bindings allow your Worker to interact with resources on the Cloudflare Developer Platform. When you declare a binding on your Worker, you grant it a specific capability, such as being able to read and write files to an R2 bucket.
For example, to access a KV namespace from a Python Worker, you would declare the following in your Worker's Wrangler configuration file:
{ "main": "./src/index.py", "kv_namespaces": [ { "binding": "FOO", "id": "<YOUR_KV_NAMESPACE_ID>" } ]}main = "./src/index.py"
[[kv_namespaces]]binding = "FOO"id = "<YOUR_KV_NAMESPACE_ID>"...and then call .get() on the binding object that is exposed on env:
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint): async def fetch(self, request): await self.env.FOO.put("bar", "baz") bar = await self.env.FOO.get("bar") return Response(bar) # returns "baz"Under the hood, env is actually a JavaScript object. When you call .FOO, you are accessing this property via a JsProxy ↗ — special proxy object that makes a JavaScript object behave like a Python object.
Occasionally, to interoperate with JavaScript APIs, you may need to convert a Python object to JavaScript. Pyodide provides a to_js function to facilitate this conversion.
from js import Objectfrom pyodide.ffi import to_js as _to_js
from workers import WorkerEntrypoint, Response
# to_js converts between Python dictionaries and JavaScript Objectsdef to_js(obj): return _to_js(obj, dict_converter=Object.fromEntries) ```For more details, see out the documentation on pyodide.ffi.to_js ↗.
When writing Workers in Python, you can access JavaScript globals by importing them from the js module. For example, note how Response is imported from js in the example below:
from workers import WorkerEntrypointfrom js import Response
class Default(WorkerEntrypoint): async def fetch(self, request): return Response.new("Hello World!")Refer to the Python examples to learn how to call into JavaScript functions from Python, including console.log and logging, providing options to Response, and parsing JSON.