Skip to content

Commit d5588f2

Browse files
committed
Add Python code to Durable Object get-started.mdx.
1 parent 8c29672 commit d5588f2

File tree

2 files changed

+152
-21
lines changed

2 files changed

+152
-21
lines changed

src/components/TypeScriptExample.astro

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ const props = z
1313
filename: z.string().optional(),
1414
playground: z.boolean().default(false),
1515
code: z.custom<ComponentProps<typeof Code>>().optional(),
16+
omitTabs: z.boolean().optional(),
1617
})
1718
.strict();
1819
19-
const { filename, playground, code } = props.parse(Astro.props);
20+
const { filename, playground, code, omitTabs } = props.parse(Astro.props);
2021
2122
const slot = await Astro.slots.render("default");
2223
@@ -41,19 +42,55 @@ if (!raw) {
4142
raw = raw.replace(/\u007f/g, "\n");
4243
4344
const js = await format(tsBlankSpace(raw), { parser: "babel", useTabs: true });
44-
---
4545
46-
<Tabs syncKey="workersExamples">
47-
<TabItem label="JavaScript" icon="seti:javascript">
48-
<Code
49-
{...code}
50-
lang="js"
51-
code={js}
52-
title={filename?.replace(".ts", ".js")}
53-
meta={playground ? "playground" : undefined}
54-
/>
55-
</TabItem>
56-
<TabItem label="TypeScript" icon="seti:typescript">
57-
<Code {...code} lang="ts" code={raw} title={filename} />
58-
</TabItem>
59-
</Tabs>
46+
const includeTabsDefinition = !omitTabs;
47+
48+
// Define tab config array
49+
const tabs = [
50+
{
51+
label: "JavaScript",
52+
icon: "seti:javascript",
53+
lang: "js",
54+
code: js,
55+
title: filename?.replace(".ts", ".js"),
56+
meta: playground ? "playground" : undefined,
57+
},
58+
{
59+
label: "TypeScript",
60+
icon: "seti:typescript",
61+
lang: "ts",
62+
code: raw,
63+
title: filename,
64+
meta: undefined
65+
},
66+
] as const;
67+
---
68+
{includeTabsDefinition ? (
69+
<Tabs syncKey="workersExamples">
70+
{tabs.map(tab => (
71+
<TabItem label={tab.label} icon={tab.icon}>
72+
<Code
73+
{...code}
74+
lang={tab.lang}
75+
code={tab.code}
76+
title={tab.title}
77+
meta={tab.meta}
78+
/>
79+
</TabItem>
80+
))}
81+
</Tabs>
82+
) : (
83+
<>
84+
{tabs.map(tab => (
85+
<TabItem label={tab.label} icon={tab.icon}>
86+
<Code
87+
{...code}
88+
lang={tab.lang}
89+
code={tab.code}
90+
title={tab.title}
91+
meta={tab.meta}
92+
/>
93+
</TabItem>
94+
))}
95+
</>
96+
)}

src/content/docs/durable-objects/get-started.mdx

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ If you do not use JavaScript or TypeScript, you will need a [shim](https://devel
7272

7373
Your `MyDurableObject` class will have a constructor with two parameters. The first parameter, `ctx`, passed to the class constructor contains state specific to the Durable Object, including methods for accessing storage. The second parameter, `env`, contains any bindings you have associated with the Worker when you uploaded it.
7474

75-
<TypeScriptExample>
75+
<Tabs syncKey="workersExamples">
76+
77+
<TypeScriptExample omitTabs={true}>
7678
```ts
7779
export class MyDurableObject extends DurableObject<Env> {
7880
constructor(ctx: DurableObjectState, env: Env) {
@@ -83,19 +85,35 @@ export class MyDurableObject extends DurableObject<Env> {
8385
```
8486
</TypeScriptExample>
8587

88+
<TabItem label="Python" icon="seti:python">
89+
90+
```python
91+
from workers import DurableObject
92+
93+
class MyDurableObject(DurableObject):
94+
def __init__(ctx, env):
95+
super().__init__(ctx, env)
96+
```
97+
98+
</TabItem>
99+
100+
</Tabs>
101+
86102
Workers communicate with a Durable Object using [remote-procedure call](/workers/runtime-apis/rpc/#_top). Public methods on a Durable Object class are exposed as [RPC methods](/durable-objects/best-practices/create-durable-object-stubs-and-send-requests/) to be called by another Worker.
87103

88104
Your file should now look like:
89105

90-
<TypeScriptExample>
106+
<Tabs syncKey="workersExamples">
107+
108+
<TypeScriptExample omitTabs={true}>
91109
```ts
92110
export class MyDurableObject extends DurableObject<Env> {
93111
constructor(ctx: DurableObjectState, env: Env) {
94112
// Required, as we're extending the base class.
95113
super(ctx, env)
96114
}
97115

98-
async sayHello():Promise<string> {
116+
async sayHello(): Promise<string> {
99117
let result = this.ctx.storage.sql
100118
.exec("SELECT 'Hello, World!' as greeting")
101119
.one();
@@ -105,6 +123,27 @@ export class MyDurableObject extends DurableObject<Env> {
105123
```
106124
</TypeScriptExample>
107125

126+
<TabItem label="Python" icon="seti:python">
127+
128+
```python
129+
from workers import DurableObject
130+
131+
class MyDurableObject(DurableObject):
132+
def __init__(self, ctx, env):
133+
super().__init__(ctx, env)
134+
135+
async def say_hello(self):
136+
result = self.ctx.storage.sql \
137+
.exec("SELECT 'Hello, World!' as greeting") \
138+
.one()
139+
140+
return result.greeting
141+
```
142+
143+
</TabItem>
144+
145+
</Tabs>
146+
108147
In the code above, you have:
109148

110149
1. Defined a RPC method, `sayHello()`, that can be called by a Worker to communicate with a Durable Object.
@@ -124,7 +163,10 @@ A Worker is used to [access Durable Objects](/durable-objects/best-practices/cre
124163

125164
To communicate with a Durable Object, the Worker's fetch handler should look like the following:
126165

127-
<TypeScriptExample>
166+
167+
<Tabs syncKey="workersExamples">
168+
169+
<TypeScriptExample omitTabs={true}>
128170
```ts
129171
export default {
130172
async fetch(request, env, ctx): Promise<Response> {
@@ -140,6 +182,25 @@ export default {
140182
```
141183
</TypeScriptExample>
142184

185+
<TabItem label="Python" icon="seti:python">
186+
187+
```python
188+
from workers import handler, Response
189+
from urllib.parse import urlparse
190+
191+
@handler
192+
async def on_fetch(request, env, ctx):
193+
url = urlparse(request.url)
194+
id = env.MY_DURABLE_OBJECT.idFromName(url.path)
195+
stub = env.MY_DURABLE_OBJECT.get(id)
196+
greeting = await stub.say_hello()
197+
return Response(greeting)
198+
```
199+
200+
</TabItem>
201+
202+
</Tabs>
203+
143204
In the code above, you have:
144205

145206
1. Exported your Worker's main event handlers, such as the `fetch()` handler for receiving HTTP requests.
@@ -217,7 +278,10 @@ Preview your Durable Object Worker at `<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.de
217278

218279
Your final code should look like this:
219280

220-
<TypeScriptExample>
281+
282+
<Tabs syncKey="workersExamples">
283+
284+
<TypeScriptExample omitTabs={true}>
221285
```ts title="index.ts"
222286
import { DurableObject } from "cloudflare:workers";
223287
export class MyDurableObject extends DurableObject<Env> {
@@ -247,6 +311,36 @@ export default {
247311
```
248312
</TypeScriptExample>
249313

314+
<TabItem label="Python" icon="seti:python">
315+
316+
```python
317+
from workers import DurableObject, handler, Response
318+
from urllib.parse import urlparse
319+
320+
class MyDurableObject(DurableObject):
321+
def __init__(self, ctx, env):
322+
super().__init__(ctx, env)
323+
324+
async def say_hello(self):
325+
result = self.ctx.storage.sql \
326+
.exec("SELECT 'Hello, World!' as greeting") \
327+
.one()
328+
329+
return result.greeting
330+
331+
@handler
332+
async def on_fetch(request, env, ctx):
333+
url = urlparse(request.url)
334+
id = env.MY_DURABLE_OBJECT.idFromName(url.path)
335+
stub = env.MY_DURABLE_OBJECT.get(id)
336+
greeting = await stub.say_hello()
337+
return Response(greeting)
338+
```
339+
340+
</TabItem>
341+
342+
</Tabs>
343+
250344
By finishing this tutorial, you have:
251345

252346
- Successfully created a Durable Object

0 commit comments

Comments
 (0)