From b92a4794726cefe9e7dc736a8da5bcb10e0afb41 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 21 May 2025 17:30:53 +0100 Subject: [PATCH 1/2] Add Python code to Durable Object get-started.mdx. --- src/components/TypeScriptExample.astro | 69 +++++++++--- .../docs/durable-objects/get-started.mdx | 104 +++++++++++++++++- 2 files changed, 152 insertions(+), 21 deletions(-) diff --git a/src/components/TypeScriptExample.astro b/src/components/TypeScriptExample.astro index 43b05c50479e96..8a4b43a3478a0e 100644 --- a/src/components/TypeScriptExample.astro +++ b/src/components/TypeScriptExample.astro @@ -13,10 +13,11 @@ const props = z filename: z.string().optional(), playground: z.boolean().default(false), code: z.custom>().optional(), + omitTabs: z.boolean().optional(), }) .strict(); -const { filename, playground, code } = props.parse(Astro.props); +const { filename, playground, code, omitTabs } = props.parse(Astro.props); const slot = await Astro.slots.render("default"); @@ -41,19 +42,55 @@ if (!raw) { raw = raw.replace(/\u007f/g, "\n"); const js = await format(tsBlankSpace(raw), { parser: "babel", useTabs: true }); ---- - - - - - - - - +const includeTabsDefinition = !omitTabs; + +// Define tab config array +const tabs = [ + { + label: "JavaScript", + icon: "seti:javascript", + lang: "js", + code: js, + title: filename?.replace(".ts", ".js"), + meta: playground ? "playground" : undefined, + }, + { + label: "TypeScript", + icon: "seti:typescript", + lang: "ts", + code: raw, + title: filename, + meta: undefined + }, +] as const; +--- +{includeTabsDefinition ? ( + + {tabs.map(tab => ( + + + + ))} + +) : ( + <> + {tabs.map(tab => ( + + + + ))} + +)} \ No newline at end of file diff --git a/src/content/docs/durable-objects/get-started.mdx b/src/content/docs/durable-objects/get-started.mdx index 2ae87f45748900..4b9aaa510890dc 100644 --- a/src/content/docs/durable-objects/get-started.mdx +++ b/src/content/docs/durable-objects/get-started.mdx @@ -72,7 +72,9 @@ If you do not use JavaScript or TypeScript, you will need a [shim](https://devel 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. - + + + ```ts export class MyDurableObject extends DurableObject { constructor(ctx: DurableObjectState, env: Env) { @@ -83,11 +85,27 @@ export class MyDurableObject extends DurableObject { ``` + + +```python +from workers import DurableObject + +class MyDurableObject(DurableObject): + def __init__(self, ctx, env): + super().__init__(ctx, env) +``` + + + + + 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. Your file should now look like: - + + + ```ts export class MyDurableObject extends DurableObject { constructor(ctx: DurableObjectState, env: Env) { @@ -95,7 +113,7 @@ export class MyDurableObject extends DurableObject { super(ctx, env) } - async sayHello():Promise { + async sayHello(): Promise { let result = this.ctx.storage.sql .exec("SELECT 'Hello, World!' as greeting") .one(); @@ -105,6 +123,27 @@ export class MyDurableObject extends DurableObject { ``` + + +```python +from workers import DurableObject + +class MyDurableObject(DurableObject): + def __init__(self, ctx, env): + super().__init__(ctx, env) + + async def say_hello(self): + result = self.ctx.storage.sql \ + .exec("SELECT 'Hello, World!' as greeting") \ + .one() + + return result.greeting +``` + + + + + In the code above, you have: 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 To communicate with a Durable Object, the Worker's fetch handler should look like the following: - + + + + ```ts export default { async fetch(request, env, ctx): Promise { @@ -140,6 +182,25 @@ export default { ``` + + +```python +from workers import handler, Response +from urllib.parse import urlparse + +@handler +async def on_fetch(request, env, ctx): + url = urlparse(request.url) + id = env.MY_DURABLE_OBJECT.idFromName(url.path) + stub = env.MY_DURABLE_OBJECT.get(id) + greeting = await stub.say_hello() + return Response(greeting) +``` + + + + + In the code above, you have: 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 `..workers.de Your final code should look like this: - + + + + ```ts title="index.ts" import { DurableObject } from "cloudflare:workers"; export class MyDurableObject extends DurableObject { @@ -247,6 +311,36 @@ export default { ``` + + +```python +from workers import DurableObject, handler, Response +from urllib.parse import urlparse + +class MyDurableObject(DurableObject): + def __init__(self, ctx, env): + super().__init__(ctx, env) + + async def say_hello(self): + result = self.ctx.storage.sql \ + .exec("SELECT 'Hello, World!' as greeting") \ + .one() + + return result.greeting + +@handler +async def on_fetch(request, env, ctx): + url = urlparse(request.url) + id = env.MY_DURABLE_OBJECT.idFromName(url.path) + stub = env.MY_DURABLE_OBJECT.get(id) + greeting = await stub.say_hello() + return Response(greeting) +``` + + + + + By finishing this tutorial, you have: - Successfully created a Durable Object From ef54f267d66ddaf2a73d4a86064d42540c36c090 Mon Sep 17 00:00:00 2001 From: Kian Newman-Hazel Date: Wed, 18 Jun 2025 15:44:15 +0100 Subject: [PATCH 2/2] refactor TypeScriptExample change --- src/components/TypeScriptExample.astro | 68 +++++++------------------- 1 file changed, 17 insertions(+), 51 deletions(-) diff --git a/src/components/TypeScriptExample.astro b/src/components/TypeScriptExample.astro index 8a4b43a3478a0e..997a8cb08ffdb4 100644 --- a/src/components/TypeScriptExample.astro +++ b/src/components/TypeScriptExample.astro @@ -13,7 +13,7 @@ const props = z filename: z.string().optional(), playground: z.boolean().default(false), code: z.custom>().optional(), - omitTabs: z.boolean().optional(), + omitTabs: z.boolean().default(false), }) .strict(); @@ -43,54 +43,20 @@ raw = raw.replace(/\u007f/g, "\n"); const js = await format(tsBlankSpace(raw), { parser: "babel", useTabs: true }); -const includeTabsDefinition = !omitTabs; - -// Define tab config array -const tabs = [ - { - label: "JavaScript", - icon: "seti:javascript", - lang: "js", - code: js, - title: filename?.replace(".ts", ".js"), - meta: playground ? "playground" : undefined, - }, - { - label: "TypeScript", - icon: "seti:typescript", - lang: "ts", - code: raw, - title: filename, - meta: undefined - }, -] as const; +const Wrapper = omitTabs ? Fragment : Tabs; --- -{includeTabsDefinition ? ( - - {tabs.map(tab => ( - - - - ))} - -) : ( - <> - {tabs.map(tab => ( - - - - ))} - -)} \ No newline at end of file + + + + + + + + +