Skip to content

Commit 3f8f1a1

Browse files
authored
Use Python SDK in templates and add DO templates for Python. (#9035)
1 parent 0b4d22a commit 3f8f1a1

File tree

27 files changed

+561
-11
lines changed

27 files changed

+561
-11
lines changed

.changeset/bitter-walls-cough.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"create-cloudflare": minor
3+
---
4+
5+
Add DO templates for Python Workers and update to use SDK

packages/create-cloudflare/templates/hello-world-durable-object-with-assets/c3.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ const config: TemplateConfig = {
1616
ts: {
1717
path: "./ts",
1818
},
19+
python: {
20+
path: "./py",
21+
},
1922
},
2023
},
2124
};
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Logs
2+
3+
logs
4+
_.log
5+
npm-debug.log_
6+
yarn-debug.log*
7+
yarn-error.log*
8+
lerna-debug.log*
9+
.pnpm-debug.log*
10+
11+
# Diagnostic reports (https://nodejs.org/api/report.html)
12+
13+
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
14+
15+
# Runtime data
16+
17+
pids
18+
_.pid
19+
_.seed
20+
\*.pid.lock
21+
22+
# Dependency directories
23+
24+
node_modules/
25+
jspm_packages/
26+
27+
# TypeScript cache
28+
29+
\*.tsbuildinfo
30+
31+
# Optional npm cache directory
32+
33+
.npm
34+
35+
# Optional eslint cache
36+
37+
.eslintcache
38+
39+
# Optional stylelint cache
40+
41+
.stylelintcache
42+
43+
# Optional REPL history
44+
45+
.node_repl_history
46+
47+
# Output of 'npm pack'
48+
49+
\*.tgz
50+
51+
# dotenv environment variable files
52+
53+
.env
54+
.env.development.local
55+
.env.test.local
56+
.env.production.local
57+
.env.local
58+
59+
# public
60+
61+
# Stores VSCode versions used for testing VSCode extensions
62+
63+
.vscode-test
64+
65+
# wrangler project
66+
67+
.dev.vars
68+
.wrangler/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## Usage
2+
3+
You can run the Worker defined by your new project by executing `wrangler dev` in this
4+
directory. This will start up an HTTP server and will allow you to iterate on your
5+
Worker without having to restart `wrangler`.
6+
7+
### Types and autocomplete
8+
9+
This project also includes a pyproject.toml and uv.lock file with some requirements which
10+
set up autocomplete and type hints for this Python Workers project.
11+
12+
To get these installed you'll need `uv`, which you can install by following
13+
https://docs.astral.sh/uv/getting-started/installation/.
14+
15+
Once `uv` is installed, you can run the following:
16+
17+
```
18+
uv venv
19+
uv sync
20+
```
21+
22+
Then point your editor's Python plugin at the `.venv` directory. You should then have working
23+
autocomplete and type information in your editor.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "<TBD>",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"deploy": "wrangler deploy",
7+
"dev": "wrangler dev",
8+
"start": "wrangler dev"
9+
},
10+
"devDependencies": {
11+
"wrangler": "^3.101.0"
12+
}
13+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Hello, World!</title>
7+
</head>
8+
<body>
9+
<h1 id="heading"></h1>
10+
<script>
11+
fetch('/message')
12+
.then((resp) => resp.text())
13+
.then((text) => {
14+
const h1 = document.getElementById('heading');
15+
h1.textContent = text;
16+
});
17+
</script>
18+
</body>
19+
</html>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[project]
2+
name = "<TBD>"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.12"
7+
dependencies = [
8+
"webtypy>=0.1.7",
9+
]
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from workers import DurableObject, Response
2+
3+
"""
4+
* Welcome to Cloudflare Workers! This is your first Durable Objects application.
5+
*
6+
* - Run `npm run dev` in your terminal to start a development server
7+
* - Open a browser tab at http://localhost:8787/ to see your Durable Object in action
8+
* - Run `npm run deploy` to publish your application
9+
*
10+
* Learn more at https://developers.cloudflare.com/durable-objects
11+
"""
12+
13+
"""
14+
* Env provides a mechanism to reference bindings declared in wrangler.jsonc within Python
15+
*
16+
* @typedef {Object} Env
17+
* @property {DurableObjectNamespace} MY_DURABLE_OBJECT - The Durable Object namespace binding
18+
"""
19+
20+
# A Durable Object's behavior is defined in an exported Python class
21+
class MyDurableObject(DurableObject):
22+
"""
23+
* The constructor is invoked once upon creation of the Durable Object, i.e. the first call to
24+
* `DurableObjectStub::get` for a given identifier (no-op constructors can be omitted)
25+
*
26+
* @param {DurableObjectState} ctx - The interface for interacting with Durable Object state
27+
* @param {Env} env - The interface to reference bindings declared in wrangler.jsonc
28+
"""
29+
def __init__(self, ctx, env):
30+
super().__init__(ctx, env)
31+
32+
"""
33+
* The Durable Object exposes an RPC method `say_hello` which will be invoked when when a Durable
34+
* Object instance receives a request from a Worker via the same method invocation on the stub
35+
*
36+
* @param {string} name - The name provided to a Durable Object instance from a Worker
37+
* @returns {Promise<string>} The greeting to be sent back to the Worker
38+
"""
39+
async def say_hello(self, name):
40+
return f"Hello, {name}!"
41+
42+
43+
"""
44+
* This is the standard fetch handler for a Cloudflare Worker
45+
*
46+
* @param {Request} request - The request submitted to the Worker from the client
47+
* @param {Env} env - The interface to reference bindings declared in wrangler.jsonc
48+
* @param {ExecutionContext} ctx - The execution context of the Worker
49+
* @returns {Promise<Response>} The response to be sent back to the client
50+
"""
51+
async def on_fetch(request, env, ctx):
52+
# Create a `DurableObjectId` for an instance of the `MyDurableObject`
53+
# class named "foo". Requests from all Workers to the instance named
54+
# "foo" will go to a single globally unique Durable Object instance.
55+
id = env.MY_DURABLE_OBJECT.idFromName("foo")
56+
57+
# Create a stub to open a communication channel with the Durable
58+
# Object instance.
59+
stub = env.MY_DURABLE_OBJECT.get(id)
60+
61+
# Call the `say_hello()` RPC method on the stub to invoke the method on
62+
# the remote Durable Object instance
63+
greeting = await stub.say_hello("world")
64+
65+
return Response(greeting)
66+

packages/create-cloudflare/templates/hello-world-durable-object-with-assets/py/uv.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)