Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: Cron triggers are now supported in Python Workers
description: You can now set up scheduled handlers in your Python Workers
products:
- workers
date: 2025-04-24T12:00:00Z
---

import { WranglerConfig } from "~/components";

You can now create Python Workers which are executed via a cron trigger.

This is similar to how it's done in JavaScript Workers, simply define a scheduled event
listener in your Worker:

```python
from workers import handler

@handler
async def on_scheduled(event, env, ctx):
print("cron processed")
```

Define a cron trigger configuration in your Wrangler configuration file:

<WranglerConfig>

```toml
[triggers]
# Schedule cron triggers:
# - At every 3rd minute
# - At 15:00 (UTC) on first day of the month
# - At 23:59 (UTC) on the last weekday of the month
crons = [ "*/3 * * * *", "0 15 1 * *", "59 23 LW * *" ]
```

</WranglerConfig>

Then test your new handler by using Wrangler with the `--test-scheduled` flag and
making a request to `/cdn-cgi/handler/scheduled?cron=*+*+*+*+*`:

```sh
npx wrangler dev --test-scheduled

curl "http://localhost:8787/cdn-cgi/handler/scheduled?cron=*+*+*+*+*"
```

Consult the [Workers Cron Triggers page](/workers/configuration/cron-triggers/) for full details on cron triggers in Workers.
43 changes: 40 additions & 3 deletions src/content/docs/workers/configuration/cron-triggers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ head: []
description: Enable your Worker to be executed on a schedule.
---

import { Render, WranglerConfig } from "~/components";
import { Render, WranglerConfig, TabItem, Tabs } from "~/components";

## Background

Expand All @@ -27,7 +27,42 @@ Cron Triggers execute on UTC time.

To respond to a Cron Trigger, you must add a [`"scheduled"` handler](/workers/runtime-apis/handlers/scheduled/) to your Worker.

<Render file="cron-trigger-example" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the repercussions of this change are but I seem to recall that we intentionally wanted to move away from inlined examples in the docs to allow testing them properly in case they suddenly break.
Maybe someone with more docs experience can chime in.

<Tabs> <TabItem label="JavaScript" icon="seti:javascript">

```js
export default {
async scheduled(controller, env, ctx) {
console.log("cron processed");
},
};
```

</TabItem> <TabItem label="TypeScript" icon="seti:typescript">

```ts
interface Env {}
export default {
async scheduled(
controller: ScheduledController,
env: Env,
ctx: ExecutionContext,
) {
console.log("cron processed");
},
};
```

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

```python
from workers import handler

@handler
async def on_scheduled(controller, env, ctx):
print("cron processed")
```

</TabItem></Tabs>

Refer to the following additional examples to write your code:

Expand Down Expand Up @@ -140,12 +175,14 @@ Changes such as adding a new Cron Trigger, updating an old Cron Trigger, or dele

:::

Test Cron Triggers using `Wrangler` by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` route which can be used to test using a HTTP request. To simulate different cron patterns, a `cron` query parameter can be passed in.
Test Cron Triggers using `Wrangler` by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` (or `/cdn-cgi/handler/scheduled` for Python Workers) route which can be used to test using a HTTP request. To simulate different cron patterns, a `cron` query parameter can be passed in.

```sh
npx wrangler dev --test-scheduled

curl "http://localhost:8787/__scheduled?cron=*+*+*+*+*"

curl "http://localhost:8787/cdn-cgi/handler/scheduled?cron=*+*+*+*+*" # Python Workers
```

## View past events
Expand Down
26 changes: 23 additions & 3 deletions src/content/docs/workers/examples/cron-trigger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ description: Set a Cron Trigger for your Worker.

import { Render, TabItem, Tabs, WranglerConfig } from "~/components";

<Render file="cron-trigger-example" />
<Tabs syncKey="workersExamples"> <TabItem label="JavaScript" icon="seti:javascript">

<Tabs syncKey="workersExamples"> <TabItem label="TypeScript (Standard)" icon="seti:typescript">
```js
export default {
async scheduled(controller, env, ctx) {
console.log("cron processed");
},
};
```

</TabItem> <TabItem label="TypeScript" icon="seti:typescript">

```ts
interface Env {}
Expand All @@ -32,6 +40,16 @@ export default {
};
```

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

```python
from workers import handler

@handler
async def on_scheduled(controller, env, ctx):
print("cron processed")
```

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

```ts
Expand Down Expand Up @@ -103,10 +121,12 @@ crons = ["0 * * * *"]

The recommended way of testing Cron Triggers is using Wrangler.

Cron Triggers can be tested using Wrangler by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` route which can be used to test using a HTTP request. To simulate different cron patterns, a `cron` query parameter can be passed in.
Cron Triggers can be tested using Wrangler by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` (or `/cdn-cgi/handler/scheduled` for Python Workers) route which can be used to test using a HTTP request. To simulate different cron patterns, a `cron` query parameter can be passed in.

```sh
npx wrangler dev --test-scheduled

curl "http://localhost:8787/__scheduled?cron=0+*+*+*+*"

curl "http://localhost:8787/cdn-cgi/handler/scheduled?cron=*+*+*+*+*" # Python Workers
```
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ export default {

The recommended way of testing Cron Triggers is using Wrangler.

Cron Triggers can be tested using Wrangler by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` route which can be used to test using a HTTP request. To simulate different cron patterns, a `cron` query parameter can be passed in.
Cron Triggers can be tested using Wrangler by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` (or `/cdn-cgi/handler/scheduled` for Python Workers) route which can be used to test using a HTTP request. To simulate different cron patterns, a `cron` query parameter can be passed in.

```sh
npx wrangler dev --test-scheduled

curl "http://localhost:8787/__scheduled?cron=*%2F3+*+*+*+*"

curl "http://localhost:8787/cdn-cgi/handler/scheduled?cron=*+*+*+*+*" # Python Workers
```
14 changes: 12 additions & 2 deletions src/content/docs/workers/runtime-apis/fetch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Worker-to-Worker `fetch` requests are possible with [Service bindings](/workers/

```js null {3-7}
export default {
async scheduled(event, env, ctx) {
async scheduled(controller, env, ctx) {
return await fetch("https://example.com", {
headers: {
"X-Source": "Cloudflare-Workers",
Expand All @@ -58,7 +58,17 @@ async function eventHandler(event) {
}
```

</TabItem> </Tabs>
</TabItem> <TabItem label="Python Worker" icon="seti:python">

```python
from workers import fetch, handler

@handler
async def on_scheduled(controller, env, ctx):
return await fetch("https://example.com", headers={"X-Source": "Cloudflare-Workers"})
```

</TabItem></Tabs>



Expand Down
43 changes: 38 additions & 5 deletions src/content/docs/workers/runtime-apis/handlers/scheduled.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ pcx_content_type: configuration
title: Scheduled Handler
---

import { TabItem, Tabs } from "~/components";

## Background

When a Worker is invoked via a [Cron Trigger](/workers/configuration/cron-triggers/), the `scheduled()` handler handles the invocation.
Expand All @@ -11,12 +13,14 @@ When a Worker is invoked via a [Cron Trigger](/workers/configuration/cron-trigge

You can test the behavior of your `scheduled()` handler in local development using Wrangler.

Cron Triggers can be tested using `Wrangler` by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` route which can be used to test using a http request. To simulate different cron patterns, a `cron` query parameter can be passed in.
Cron Triggers can be tested using `Wrangler` by passing in the `--test-scheduled` flag to [`wrangler dev`](/workers/wrangler/commands/#dev). This will expose a `/__scheduled` (or `/cdn-cgi/handler/scheduled` for Python Workers) route which can be used to test using a http request. To simulate different cron patterns, a `cron` query parameter can be passed in.

```sh
npx wrangler dev --test-scheduled

curl "http://localhost:8787/__scheduled?cron=*+*+*+*+*"

curl "http://localhost:8787/cdn-cgi/handler/scheduled?cron=*+*+*+*+*" # Python Workers
```

:::
Expand All @@ -25,25 +29,54 @@ curl "http://localhost:8787/__scheduled?cron=*+*+*+*+*"

## Syntax

<Tabs> <TabItem label="JavaScript" icon="seti:javascript">

```js
export default {
async scheduled(event, env, ctx) {
async scheduled(controller, env, ctx) {
ctx.waitUntil(doSomeTaskOnASchedule());
},
};
```

</TabItem> <TabItem label="TypeScript" icon="seti:typescript">

```ts
interface Env {}
export default {
async scheduled(
controller: ScheduledController,
env: Env,
ctx: ExecutionContext,
) {
ctx.waitUntil(doSomeTaskOnASchedule());
},
};
```

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

```python
from workers import handler

@handler
async def on_scheduled(controller, env, ctx):
ctx.waitUntil(doSomeTaskOnASchedule())
```

</TabItem></Tabs>

### Properties

- `event.cron` string
- `controller.cron` string

- The value of the [Cron Trigger](/workers/configuration/cron-triggers/) that started the `ScheduledEvent`.

- `event.type` string
- `controller.type` string

- The type of event. This will always return `"scheduled"`.

- `event.scheduledTime` number
- `controller.scheduledTime` number

- The time the `ScheduledEvent` was scheduled to be executed in milliseconds since January 1, 1970, UTC. It can be parsed as <code>new Date(event.scheduledTime)</code>.

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/workers/wrangler/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ As of Wrangler v3.2.0, `wrangler dev` is supported by any Linux distributions pr
- `--remote` <Type text="boolean" /> <MetaInfo text="(default: false) optional" />
- Develop against remote resources and data stored on Cloudflare's network.
- `--test-scheduled` <Type text="boolean" /> <MetaInfo text="(default: false) optional" />
- Exposes a `/__scheduled` fetch route which will trigger a scheduled event (Cron Trigger) for testing during development. To simulate different cron patterns, a `cron` query parameter can be passed in: `/__scheduled?cron=*+*+*+*+*`.
- Exposes a `/__scheduled` fetch route which will trigger a scheduled event (Cron Trigger) for testing during development. To simulate different cron patterns, a `cron` query parameter can be passed in: `/__scheduled?cron=*+*+*+*+*` or `/cdn-cgi/handler/scheduled?cron=*+*+*+*+*`.
- `--log-level` <Type text="'debug'|'info'|'log'|'warn'|'error|'none'" /> <MetaInfo text="(default: log) optional" />
- Specify Wrangler's logging level.
- `--show-interactive-dev-session` <Type text="boolean" /> <MetaInfo text="(default: true if the terminal supports interactivity) optional" />
Expand Down
20 changes: 0 additions & 20 deletions src/content/partials/workers/cron-trigger-example.mdx

This file was deleted.