@@ -8,7 +8,7 @@ description: Worker Bindings that allow for interaction with other Cloudflare Re
88next : false
99---
1010
11- import { DirectoryListing , WranglerConfig } from " ~/components" ;
11+ import { DirectoryListing , TabItem , Tabs , WranglerConfig } from " ~/components" ;
1212
1313Bindings allow your Worker to interact with resources on the Cloudflare Developer Platform. Bindings provide better performance and less restrictions when accessing resources from Workers than the [ REST APIs] ( /api/ ) which are intended for non-Workers applications.
1414
@@ -36,16 +36,35 @@ When you declare a binding on your Worker, you grant it a specific capability, s
3636
3737</WranglerConfig >
3838
39+ <Tabs > <TabItem label = " JavaScript" icon = " seti:javascript" >
40+
3941``` js
4042export default {
4143 async fetch (request , env ) {
44+ const url = new URL (request .url );
4245 const key = url .pathname .slice (1 );
4346 await env .MY_BUCKET .put (key, request .body );
4447 return new Response (` Put ${ key} successfully!` );
4548 },
4649};
4750```
4851
52+ </TabItem > <TabItem label = " Python" icon = " seti:python" >
53+
54+ ``` python
55+ from workers import WorkerEntrypoint, Response
56+ from urllib.parse import urlparse
57+
58+ class Default (WorkerEntrypoint ):
59+ async def fetch (self , request ):
60+ url = urlparse(request.url)
61+ key = url.path.slice(1 )
62+ await self .env.MY_BUCKET .put(key, request.body)
63+ return Response(f " Put { key} successfully! " )
64+ ```
65+
66+ </TabItem ></Tabs >
67+
4968You can think of a binding as a permission and an API in one piece. With bindings, you never have to add secret keys or tokens to your Worker in order to access resources on your Cloudflare account — the permission is embedded within the API itself. The underlying secret is never exposed to your Worker's code, and therefore can't be accidentally leaked.
5069
5170## Making changes to bindings
@@ -99,27 +118,47 @@ Bindings are located on the `env` object, which can be accessed in several ways:
99118* It is as class property on [ WorkerEntrypoint] ( /workers/runtime-apis/bindings/service-bindings/rpc/#bindings-env ) ,
100119 [ DurableObject] ( /durable-objects/ ) , and [ Workflow] ( /workflows/ ) :
101120
121+ <Tabs > <TabItem label = " JavaScript" icon = " seti:javascript" >
102122 ``` js
103123 export class MyDurableObject extends DurableObject {
104124 async sayHello () {
105125 return ` Hi, ${ this .env .NAME } !` ;
106126 }
107127 }
108128 ```
129+ </TabItem > <TabItem label = " Python" icon = " seti:python" >
130+ ``` python
131+ from workers import WorkerEntrypoint, Response
132+
133+ class Default (WorkerEntrypoint ):
134+ async def fetch (self , request ):
135+ return Response(f " Hi { self .env.NAME } " )
136+ ```
137+ </TabItem ></Tabs >
138+
109139
110140* It can be imported from ` cloudflare:workers ` :
111141
142+ <Tabs > <TabItem label = " JavaScript" icon = " seti:javascript" >
112143 ``` js
113144 import { env } from " cloudflare:workers" ;
114145 console .log (` Hi, ${ env .Name } ` );
115146 ```
147+ </TabItem > <TabItem label = " Python" icon = " seti:python" >
148+ ``` python
149+ from workers import import_from_javascript
150+ env = import_from_javascript(" cloudflare:workers" ).env
151+ print (f " Hi, { env.NAME } " )
152+ ```
153+ </TabItem ></Tabs >
116154
117155### Importing ` env ` as a global
118156
119157Importing ` env ` from ` cloudflare:workers ` is useful when you need to access a binding
120158such as [ secrets] ( /workers/configuration/secrets/ ) or [ environment variables] ( /workers/configuration/environment-variables/ )
121159in top-level global scope. For example, to initialize an API client:
122160
161+ <Tabs > <TabItem label = " JavaScript" icon = " seti:javascript" >
123162``` js
124163import { env } from " cloudflare:workers" ;
125164import ApiClient from " example-api-client" ;
@@ -134,6 +173,19 @@ export default {
134173 },
135174};
136175```
176+ </TabItem > <TabItem label = " Python" icon = " seti:python" >
177+ ``` python
178+ from workers import WorkerEntrypoint, env
179+ from example_api_client import ApiClient
180+
181+ api_client = ApiClient(api_key = env.API_KEY )
182+ LOG_LEVEL = getattr (env, " LOG_LEVEL" , " info" )
183+
184+ class Default (WorkerEntrypoint ):
185+ async def fetch (self , request ):
186+ # ...
187+ ```
188+ </TabItem ></Tabs >
137189
138190Workers do not allow I/O from outside a request context. This means that even
139191though ` env ` is accessible from the top-level scope, you will not be able to access
@@ -144,6 +196,7 @@ call `env.NAMESPACE.get` to get a [Durable Object stub](/durable-objects/api/stu
144196top-level context. However, calling methods on the Durable Object stub, making [ calls to a KV store] ( /kv/api/ ) ,
145197and [ calling to other Workers] ( /workers/runtime-apis/bindings/service-bindings ) will not work.
146198
199+ <Tabs > <TabItem label = " JavaScript" icon = " seti:javascript" >
147200``` js
148201import { env } from " cloudflare:workers" ;
149202
@@ -158,11 +211,26 @@ export default {
158211 },
159212};
160213```
214+ </TabItem > <TabItem label = " Python" icon = " seti:python" >
215+ ``` python
216+ from workers import Response, WorkerEntrypoint, env
217+
218+ # This would fail!
219+ # env.KV.get('my-key')
220+
221+ class Default (WorkerEntrypoint ):
222+ async def fetch (self , request ):
223+ # This works
224+ mv_val = await env.KV .get(" my-key" )
225+ return Response(my_val)
226+ ```
227+ </TabItem ></Tabs >
161228
162229Additionally, importing ` env ` from ` cloudflare:workers ` lets you avoid passing ` env `
163230as an argument through many function calls if you need to access a binding from a deeply-nested
164231function. This can be helpful in a complex codebase.
165232
233+ <Tabs > <TabItem label = " JavaScript" icon = " seti:javascript" >
166234``` js
167235import { env } from " cloudflare:workers" ;
168236
@@ -183,6 +251,24 @@ function getName() {
183251 return env .MY_NAME ;
184252}
185253```
254+ </TabItem > <TabItem label = " Python" icon = " seti:python" >
255+ ``` python
256+ from workers import Response, WorkerEntrypoint, env
257+
258+ class Default (WorkerEntrypoint ):
259+ def fetch (req ):
260+ return Response(say_hello())
261+
262+ # env is not an argument to say_hello...
263+ def say_hello ():
264+ my_name = get_name()
265+ return f " Hello, { myName} "
266+
267+ # ...nor is it an argument to getName
268+ def get_name ():
269+ return env.MY_NAME
270+ ```
271+ </TabItem ></Tabs >
186272
187273:::note
188274While using ` env ` from ` cloudflare:workers ` may be simpler to write than passing it
@@ -199,6 +285,7 @@ Imagine a user has defined the [environment variable](/workers/configuration/env
199285` env.NAME ` would print "Alice". Using the ` withEnv ` function, you can override the value of
200286"NAME".
201287
288+ <Tabs > <TabItem label = " JavaScript" icon = " seti:javascript" >
202289``` js
203290import { env , withEnv } from " cloudflare:workers" ;
204291
@@ -220,5 +307,24 @@ export default {
220307 },
221308};
222309```
310+ </TabItem > <TabItem label = " Python" icon = " seti:python" >
311+ ``` python
312+ from workers import Response, WorkerEntrypoint, env, patch_env
313+
314+ def log_name ():
315+ print (env.NAME )
316+
317+ class Default (WorkerEntrypoint ):
318+ async def fetch (req ):
319+ # this will log "Alice"
320+ log_name()
321+
322+ with patch_env(NAME = " Bob" ):
323+ # this will log "Bob"
324+ log_name()
325+
326+ # ...etc...
327+ ```
328+ </TabItem ></Tabs >
223329
224330This can be useful when testing code that relies on an imported ` env ` object.
0 commit comments