Skip to content

Commit 4106ec1

Browse files
authored
Python documentation additions and cleanup (#26267)
* Python documentation additions and cleanup * Update minor typo in Python Workflows docs * Updates per feedback * Adding pywrangler link
1 parent 4c310f4 commit 4106ec1

File tree

17 files changed

+441
-271
lines changed

17 files changed

+441
-271
lines changed

src/content/docs/workers/configuration/cron-triggers.mdx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ head: []
55
description: Enable your Worker to be executed on a schedule.
66
---
77

8-
import { Render, WranglerConfig, TabItem, Tabs, DashButton } from "~/components";
8+
import {
9+
Render,
10+
WranglerConfig,
11+
TabItem,
12+
Tabs,
13+
DashButton,
14+
} from "~/components";
915

1016
## Background
1117

@@ -55,11 +61,11 @@ export default {
5561
</TabItem> <TabItem label="Python" icon="seti:python">
5662

5763
```python
58-
from workers import handler
64+
from workers import WorkerEntrypoint, Response
5965

60-
@handler
61-
async def on_scheduled(controller, env, ctx):
62-
print("cron processed")
66+
class Default(WorkerEntrypoint):
67+
async def scheduled(self, controller, env, ctx):
68+
print("cron processed")
6369
```
6470

6571
</TabItem></Tabs>
@@ -143,31 +149,24 @@ To avoid ambiguity you may prefer to use the three-letter abbreviations (e.g. `S
143149
Some common time intervals that may be useful for setting up your Cron Trigger:
144150

145151
- `* * * * *`
146-
147152
- At every minute
148153

149154
- `*/30 * * * *`
150-
151155
- At every 30th minute
152156

153157
- `45 * * * *`
154-
155158
- On the 45th minute of every hour
156159

157160
- `0 17 * * sun` or `0 17 * * 1`
158-
159161
- 17:00 (UTC) on Sunday
160162

161163
- `10 7 * * mon-fri` or `10 7 * * 2-6`
162-
163164
- 07:10 (UTC) on weekdays
164165

165166
- `0 15 1 * *`
166-
167167
- 15:00 (UTC) on first day of the month
168168

169169
- `0 18 * * 6L` or `0 18 * * friL`
170-
171170
- 18:00 (UTC) on the last Friday of the month
172171

173172
- `59 23 LW * *`

src/content/docs/workers/examples/cron-trigger.mdx

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
---
2-
32
summary: Set a Cron Trigger for your Worker.
43
tags:
54
- Middleware
@@ -35,58 +34,58 @@ export default {
3534
```ts
3635
interface Env {}
3736
export default {
38-
async scheduled(
39-
controller: ScheduledController,
40-
env: Env,
41-
ctx: ExecutionContext,
42-
) {
43-
console.log("cron processed");
44-
},
37+
async scheduled(
38+
controller: ScheduledController,
39+
env: Env,
40+
ctx: ExecutionContext,
41+
) {
42+
console.log("cron processed");
43+
},
4544
};
4645
```
4746

4847
</TabItem> <TabItem label="Python" icon="seti:python">
4948

5049
```python
51-
from workers import handler
50+
from workers import WorkerEntrypoint, Response
5251

53-
@handler
54-
async def on_scheduled(controller, env, ctx):
55-
print("cron processed")
52+
class Default(WorkerEntrypoint):
53+
async def scheduled(self, controller, env, ctx):
54+
print("cron processed")
5655
```
5756

5857
</TabItem> <TabItem label="Hono" icon="seti:typescript">
5958

6059
```ts
61-
import { Hono } from 'hono';
60+
import { Hono } from "hono";
6261

6362
interface Env {}
6463

6564
// Create Hono app
6665
const app = new Hono<{ Bindings: Env }>();
6766

6867
// Regular routes for normal HTTP requests
69-
app.get('/', (c) => c.text('Hello World!'));
68+
app.get("/", (c) => c.text("Hello World!"));
7069

7170
// Export both the app and a scheduled function
7271
export default {
73-
// The Hono app handles regular HTTP requests
74-
fetch: app.fetch,
75-
76-
// The scheduled function handles Cron triggers
77-
async scheduled(
78-
controller: ScheduledController,
79-
env: Env,
80-
ctx: ExecutionContext,
81-
) {
82-
console.log("cron processed");
83-
84-
// You could also perform actions like:
85-
// - Fetching data from external APIs
86-
// - Updating KV or Durable Object storage
87-
// - Running maintenance tasks
88-
// - Sending notifications
89-
},
72+
// The Hono app handles regular HTTP requests
73+
fetch: app.fetch,
74+
75+
// The scheduled function handles Cron triggers
76+
async scheduled(
77+
controller: ScheduledController,
78+
env: Env,
79+
ctx: ExecutionContext,
80+
) {
81+
console.log("cron processed");
82+
83+
// You could also perform actions like:
84+
// - Fetching data from external APIs
85+
// - Updating KV or Durable Object storage
86+
// - Running maintenance tasks
87+
// - Sending notifications
88+
},
9089
};
9190
```
9291

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
pcx_content_type: concept
3+
title: The Basics
4+
sidebar:
5+
order: 4
6+
head:
7+
- tag: title
8+
content: Learn the basics of Python Workers
9+
description: Learn the basics of Python Workers
10+
---
11+
12+
import { WranglerConfig } from "~/components";
13+
14+
## Fetch Handler
15+
16+
As mentioned in the [introduction to Python Workers](/workers/languages/python/), a Python Worker can be as simple as four lines of code:
17+
18+
```python
19+
from workers import WorkerEntrypoint, Response
20+
21+
class Default(WorkerEntrypoint):
22+
async def fetch(self, request):
23+
return Response("Hello World!")
24+
```
25+
26+
Similar to other Workers, the main entry point for a Python worker is the [`fetch` handler](/workers/runtime-apis/handlers/fetch) which handles incoming requests
27+
sent to the Worker.
28+
29+
In a Python Worker, this handler is placed in a `Default` class that extends the `WorkerEntrypoint` class (which you can import from the `workers` SDK module).
30+
31+
## The `Request` Interface
32+
33+
The `request` parameter passed to your `fetch` handler is a JavaScript Request object, exposed via the [foreign function interface (FFI)](/workers/languages/python/ffi),
34+
allowing you to access it directly from your Python code.
35+
36+
Let's try editing the worker to accept a POST request. We know from the
37+
[documentation for `Request`](/workers/runtime-apis/request) that we can call
38+
`await request.json()` within an `async` function to parse the request body as
39+
JSON.
40+
41+
In a Python Worker, you would write:
42+
43+
```python
44+
from workers import WorkerEntrypoint, Response
45+
from hello import hello
46+
47+
class Default(WorkerEntrypoint):
48+
async def fetch(self, request):
49+
name = (await request.json()).name
50+
return Response(hello(name))
51+
```
52+
53+
Many other JavaScript APIs are available in Python Workers via the FFI, so you can
54+
call other methods in a similar way.
55+
56+
Once you edit the `src/entry.py`, Wrangler will automatically restart the local
57+
development server.
58+
59+
Now, if you send a POST request with the appropriate body,
60+
your Worker will respond with a personalized message.
61+
62+
```bash
63+
curl --header "Content-Type: application/json" \
64+
--request POST \
65+
--data '{"name": "Python"}' http://localhost:8787
66+
```
67+
68+
```bash output
69+
Hello, Python!
70+
```
71+
72+
## The `env` Attribute
73+
74+
The `env` attribute on the `WorkerEntrypoint` can be used to access
75+
[environment variables](/workers/configuration/environment-variables/),
76+
[secrets](/workers/configuration/secrets/),and
77+
[bindings](/workers/runtime-apis/bindings/).
78+
79+
For example, let us try setting and using an environment variable in a Python Worker. First, add the environment variable to your Worker's [Wrangler configuration file](/workers/wrangler/configuration/):
80+
81+
<WranglerConfig>
82+
83+
```toml
84+
name = "hello-python-worker"
85+
main = "src/entry.py"
86+
compatibility_flags = ["python_workers"]
87+
compatibility_date = "2025-11-02"
88+
89+
[vars]
90+
API_HOST = "example.com"
91+
```
92+
93+
</WranglerConfig>
94+
95+
Then, you can access the `API_HOST` environment variable via the `env` parameter:
96+
97+
```python
98+
from workers import WorkerEntrypoint, Response
99+
100+
class Default(WorkerEntrypoint):
101+
async def fetch(self, request):
102+
return Response(self.env.API_HOST)
103+
```
104+
105+
## Modules
106+
107+
Python workers can be split across multiple files.
108+
109+
Let's create a new Python file, called `src/hello.py`:
110+
111+
```python
112+
def hello(name):
113+
return "Hello, " + name + "!"
114+
```
115+
116+
Now, we can modify `src/entry.py` to make use of the new module.
117+
118+
```python
119+
from hello import hello
120+
from workers import WorkerEntrypoint, Response
121+
122+
class Default(WorkerEntrypoint):
123+
async def fetch(self, request):
124+
return Response(hello("World"))
125+
```
126+
127+
Once you edit `src/entry.py`, [`pywrangler`](/workers/languages/python/#the-pywrangler-cli-tool) will automatically detect the change and
128+
reload your Worker.
129+
130+
## Types and Autocompletion
131+
132+
When developing Python Workers, you can take advantage of type hints and autocompletion
133+
in your IDE.
134+
135+
To enable them, install the `workers-runtime-sdk` package in your `pyproject.toml` file.
136+
137+
```toml
138+
[dependency-groups]
139+
dev = [
140+
"workers-py",
141+
"workers-runtime-sdk"
142+
]
143+
```
144+
145+
Additionally, you can generate types based on your Worker configuration using `uv run pywrangler types`
146+
147+
This includes Env types based on your bindings, module rules, and runtime types based on the compatibility_date
148+
and compatibility_flags in your config file.
149+
150+
## Upgrading `pywrangler`
151+
152+
To upgrade to the latest version of [`pywrangler`](/workers/languages/python/#the-pywrangler-cli-tool) globally, run the following command:
153+
154+
```bash
155+
uv tool upgrade workers-py
156+
```
157+
158+
To upgrade to the latest version of `pywrangler` in a specific project, run the following command:
159+
160+
```bash
161+
uv lock --upgrade-package workers-py
162+
```
163+
164+
## Next Up
165+
166+
- Learn details about local development, deployment, and [how Python Workers work](/workers/languages/python/how-python-workers-work).
167+
- Explore the [package](/workers/languages/python/packages) docs for instructions on how to use packages with Python Workers.
168+
- Understand which parts of the [Python Standard Library](/workers/languages/python/stdlib) are supported in Python Workers.
169+
- Learn about Python Workers' [foreign function interface (FFI)](/workers/languages/python/ffi), and how to use it to work with [bindings](/workers/runtime-apis/bindings) and [Runtime APIs](/workers/runtime-apis/).

0 commit comments

Comments
 (0)