Skip to content
Open
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
161 changes: 161 additions & 0 deletions content/user-guide/task-configuration/triggers.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,167 @@ You can attach multiple triggers to a single task by providing a list of trigger

You can mix and match trigger types, combining predefined triggers with those that use `flyte.Cron`, and `flyte.FixedRate` automations (see below for explanations of these concepts).

## Notifications

You can attach notifications to a trigger using the `notifications` parameter of `flyte.Trigger`.
Notifications fire when a triggered run reaches a terminal execution phase.

```python
import flyte
from flyte import notify
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The snippets import notifications as from flyte import notify, but elsewhere in this docs repo the documented pattern is import flyte.notify as notify (e.g., content/api-reference/flyte-sdk/packages/flyte/_index.md:820-822). Using the module import form avoids relying on flyte re-exporting notify and is more consistent for readers.

Suggested change
from flyte import notify
import flyte.notify as notify

Copilot uses AI. Check for mistakes.
from flyte.models import ActionPhase

env = flyte.TaskEnvironment(name="my_task_env")

trigger_with_notifications = flyte.Trigger(
name="daily_report",
automation=flyte.Cron("0 9 * * 1-5"),
notifications=(
notify.Slack(
on_phase=ActionPhase.FAILED,
webhook_url="https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
message="Run {{.Run.Name}} failed with: {{.Error}}",
),
notify.Email(
on_phase=ActionPhase.SUCCEEDED,
recipients=["oncall@example.com"],
subject="Run {{.Run.Name}} succeeded",
body="Run: {{.Run.Name}}",
Comment on lines +301 to +307
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This example message uses {{.Run.Name}} / {{.Error}} placeholders, but the Flyte Notifications API reference in this repo documents {run.name} / {run.error} (and similar) placeholders. Please update the example to match the actual template syntax so it works when copy/pasted.

Suggested change
message="Run {{.Run.Name}} failed with: {{.Error}}",
),
notify.Email(
on_phase=ActionPhase.SUCCEEDED,
recipients=["oncall@example.com"],
subject="Run {{.Run.Name}} succeeded",
body="Run: {{.Run.Name}}",
message="Run {run.name} failed with: {run.error}",
),
notify.Email(
on_phase=ActionPhase.SUCCEEDED,
recipients=["oncall@example.com"],
subject="Run {run.name} succeeded",
body="Run: {run.name}",

Copilot uses AI. Check for mistakes.
),
),
)

@env.task(triggers=trigger_with_notifications)
def process_data(date: str) -> str:
return f"Processed {date}"
```

### Execution phases

The `on_phase` parameter accepts a single phase or a tuple of terminal phases from `flyte.models.ActionPhase`:

| Phase | Description |
|-------|----------------------------|
| `ActionPhase.SUCCEEDED` | Run completed successfully |
| `ActionPhase.FAILED` | Run failed with an error |
| `ActionPhase.TIMED_OUT` | Run exceeded its timeout |
| `ActionPhase.ABORTED` | Run was manually aborted |

To notify on multiple phases with the same notification:

```python
notify.Email(
on_phase=(ActionPhase.FAILED, ActionPhase.ABORTED),
recipients=["oncall@example.com"],
subject="Alert: Run completed with phase {{.Phase}}",
body="Run: {{.Run.Name}}\nError: {{.Error}}",
)
```

### Template variables

All message fields support template variables that are substituted at delivery time:

| Variable | Description |
|--------------------|--------------------------------------------------------|
| `{{.Run.Project}}` | Project name |
| `{{.Run.Domain}}` | Domain name |
| `{{.Run.Name}}` | Run ID |
| `{{.Phase}}` | Execution phase |
| `{{.Error}}` | Error message when failed or abort reason whan aborted |
Comment on lines +339 to +349
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The template variable syntax and names here (e.g., {{.Run.Name}}, {{.Error}}) don’t match the Flyte Notifications API reference in this repo, which documents Python-format placeholders like {run.name}, {run.error}, {run.url}, {project}, {domain} (see content/api-reference/flyte-sdk/packages/flyte.notify/_index.md). As written, users will likely get literal {{...}} text in delivered notifications. Please align the variable table (and the examples in this section) with the documented placeholder format/keys.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

Typo in the template variable description: “whan” → “when”.

Suggested change
| `{{.Error}}` | Error message when failed or abort reason whan aborted |
| `{{.Error}}` | Error message when failed or abort reason when aborted |

Copilot uses AI. Check for mistakes.


### Slack notifications

`notify.Slack` sends a message to a Slack channel via an [incoming webhook](https://api.slack.com/messaging/webhooks).

**Simple message:**

```python
notify.Slack(
on_phase=ActionPhase.FAILED,
webhook_url="https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
message="Run {{.Run.Name}} failed in {{.Run.Project}}/{{.Run.Domain}}: {{.Error}}",
)
```

**Rich formatting with [Block Kit](https://api.slack.com/block-kit):**

Use `blocks` instead of `message` for structured layouts. When `blocks` is provided, `message` is ignored.

```python
notify.Slack(
on_phase=ActionPhase.SUCCEEDED,
webhook_url="https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
blocks=[
{
"type": "header",
"text": {"type": "plain_text", "text": "Task Succeeded"},
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Run:*\n{{.Run.Name}}"},
{"type": "mrkdwn", "text": "*Phase:*\n{{.Phase}}"},
],
},
{"type": "divider"},
{
"type": "context",
"elements": [
{"type": "mrkdwn", "text": "{{.Run.Project}}/{{.Run.Domain}}"},
],
},
],
)
```

### Email notifications

`notify.Email` sends an email notification. You can provide a plain-text `body`, an `html_body`, or both (the email is sent as multipart when both are present).

```python
notify.Email(
on_phase=ActionPhase.FAILED,
recipients=["oncall@example.com"],
cc=["team-lead@example.com"],
subject="ALERT: Run {{.Run.Name}} failed",
body="Run: {{.Run.Name}}\nError: {{.Error}}",
html_body="<b>Error:</b> {{.Error}}<br>",
)
```

### Microsoft Teams notifications

`notify.Teams` sends a message to a Teams channel via an incoming webhook. Use `card` for [Adaptive Card](https://adaptivecards.io/designer/) formatting; when `card` is set, `title` and `message` are ignored.

```python
notify.Teams(
on_phase=ActionPhase.FAILED,
webhook_url="https://outlook.office.com/webhook/YOUR_WEBHOOK_URL",
title="Task Failed",
message="Run {{.Run.Name}} failed: {{.Error}}\n",
)
```

### Custom webhook notifications

`notify.Webhook` sends an HTTP request to any endpoint. All string values in `headers` and `body` support template variables.

```python
notify.Webhook(
on_phase=ActionPhase.SUCCEEDED,
url="https://api.example.com/events",
method="POST",
headers={"Authorization": "Bearer my-token"},
body={
"event": "task_succeeded",
"run": "{{.Run.Name}}",
},
)
```


## Deploying a task with triggers

We recommend that you define your triggers in code together with your tasks and deploy them together.
Expand Down
144 changes: 144 additions & 0 deletions content/user-guide/task-deployment/run-with-notifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
title: Run with notifications
weight: 11
variants: +flyte +union
---

# Run with notifications

You can attach notifications to a single run by passing them to `flyte.with_runcontext()`.
Notifications fire when the run reaches the terminal execution phase — no trigger or persistent deployment is required.

```python
import os
import flyte
from flyte import notify
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The snippets import notifications as from flyte import notify, but the API reference examples use import flyte.notify as notify (e.g., content/api-reference/flyte-sdk/packages/flyte/_index.md:820-822). Consider switching to the module import form to avoid relying on a re-export and to match the documented style.

Suggested change
from flyte import notify
import flyte.notify as notify

Copilot uses AI. Check for mistakes.
from flyte.models import ActionPhase

env = flyte.TaskEnvironment(name="notify_example")

SLACK_WEBHOOK_URL = os.environ["SLACK_WEBHOOK_URL"]
NOTIFICATION_EMAIL = os.environ["NOTIFICATION_EMAIL"]


@env.task
def compute(x: int, y: int) -> int:
return x + y


if __name__ == "__main__":
result = flyte.with_runcontext(
notifications=(
notify.Slack(
on_phase=ActionPhase.SUCCEEDED,
webhook_url=SLACK_WEBHOOK_URL,
message="Run {{.Run.Name}} succeeded.",
),
notify.Email(
on_phase=ActionPhase.FAILED,
recipients=[NOTIFICATION_EMAIL],
subject="ALERT: Run {{.Run.Name}} failed",
body="Run: {{.Run.Name}}\nError: {{.Error}}",
Comment on lines +35 to +41
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This example uses {{.Run.Name}} / {{.Error}} placeholders, but the Flyte Notifications API reference in this repo shows {run.name} / {run.error} placeholders for notification message templating. Please update the example strings so they match the real template syntax.

Suggested change
message="Run {{.Run.Name}} succeeded.",
),
notify.Email(
on_phase=ActionPhase.FAILED,
recipients=[NOTIFICATION_EMAIL],
subject="ALERT: Run {{.Run.Name}} failed",
body="Run: {{.Run.Name}}\nError: {{.Error}}",
message="Run {run.name} succeeded.",
),
notify.Email(
on_phase=ActionPhase.FAILED,
recipients=[NOTIFICATION_EMAIL],
subject="ALERT: Run {run.name} failed",
body="Run: {run.name}\nError: {run.error}",

Copilot uses AI. Check for mistakes.
),
),
).run(compute, x=3, y=7)
print(f"Result: {result}")
```

Pass a single notification or a tuple of notifications. All notification types from `flyte.notify` are supported: `Slack`, `Email`, `Teams`, `Webhook`, and `NamedDelivery`.
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This line says “All notification types from flyte.notify are supported” but the flyte.notify module also documents types like NamedRule in the API reference. Either include all supported types (including whether NamedRule is supported here) or reword this to avoid an exhaustive claim (e.g., “Common notification types include ...”).

Suggested change
Pass a single notification or a tuple of notifications. All notification types from `flyte.notify` are supported: `Slack`, `Email`, `Teams`, `Webhook`, and `NamedDelivery`.
Pass a single notification or a tuple of notifications. Common notification types from `flyte.notify` include: `Slack`, `Email`, `Teams`, `Webhook`, and `NamedDelivery`.

Copilot uses AI. Check for mistakes.

> [!NOTE]
> To attach notifications to every run created by a scheduled trigger, set `notifications` on the `flyte.Trigger` object instead. See [Notifications](../task-configuration/triggers#notifications).

## Execution phases

The `on_phase` parameter accepts a single phase or a tuple of phases from `flyte.models.ActionPhase`:

| Phase | Description |
|-------|-------------|
| `ActionPhase.SUCCEEDED` | Run completed successfully |
| `ActionPhase.FAILED` | Run failed with an error |
| `ActionPhase.TIMED_OUT` | Run exceeded its timeout |
| `ActionPhase.ABORTED` | Run was manually aborted |

## Template variables

All message fields support template variables substituted at delivery time:

| Variable | Description |
|----------|-------------|
| `{{.Run.Project}}` | Project name |
| `{{.Run.Domain}}` | Domain name |
| `{{.Run.Name}}` | Run ID |
| `{{.Phase}}` | Execution phase |
| `{{.Error}}` | Error message (failed) or abort reason (aborted) |
Comment on lines +64 to +74
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The template variable syntax and keys in this page (e.g., {{.Run.Name}}, {{.Phase}}, {{.Error}}) don’t match the Flyte Notifications API reference in this repo, which documents placeholders like {run.name}, {run.phase}, {run.error}, {run.url}, {project}, {domain} (see content/api-reference/flyte-sdk/packages/flyte.notify/_index.md). As written, notification messages will likely not render as intended when users copy/paste them. Please update the examples and the variable table to the documented placeholder format.

Copilot uses AI. Check for mistakes.

## Slack notifications

`notify.Slack` sends a message to a Slack channel via an [incoming webhook](https://api.slack.com/messaging/webhooks).

**Simple message:**

```python
notify.Slack(
on_phase=ActionPhase.FAILED,
webhook_url=SLACK_WEBHOOK_URL,
message="Run {{.Run.Name}} failed in {{.Run.Project}}/{{.Run.Domain}}: {{.Error}}",
)
```

**Rich formatting with [Block Kit](https://api.slack.com/block-kit):**

Use `blocks` instead of `message` for structured layouts. When `blocks` is provided, `message` is ignored.

```python
notify.Slack(
on_phase=ActionPhase.SUCCEEDED,
webhook_url=SLACK_WEBHOOK_URL,
blocks=[
{
"type": "header",
"text": {"type": "plain_text", "text": "Task Succeeded"},
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Run:*\n{{.Run.Name}}"},
{"type": "mrkdwn", "text": "*Phase:*\n{{.Phase}}"},
],
},
{"type": "divider"},
{
"type": "context",
"elements": [
{"type": "mrkdwn", "text": "{{.Run.Project}}/{{.Run.Domain}}"},
],
},
],
)
```

## Email notifications

`notify.Email` sends an email notification. Provide `body` for plain text, `html_body` for HTML, or both (sent as multipart).

```python
notify.Email(
on_phase=ActionPhase.FAILED,
recipients=[NOTIFICATION_EMAIL],
cc=["team-lead@example.com"],
subject="ALERT: Run {{.Run.Name}} failed",
body="Run: {{.Run.Name}}\nError: {{.Error}}",
html_body="<b>Error:</b> {{.Error}}<br>",
)
```

To receive emails locally while developing, start a debug SMTP server before running your script:

```bash
# Python >= 3.12
pip install aiosmtpd
sudo python -m aiosmtpd -n -l localhost:25
```
Comment on lines +139 to +142
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

For local SMTP testing, recommending sudo python ... localhost:25 encourages running Python as root. Since the text already mentions 1025 as an alternative, consider making the non-root option the default command (and mention 25 only as an optional privileged-port variant).

Copilot uses AI. Check for mistakes.

The server prints received emails to stdout. Port 25 requires root; use port 1025 as an alternative (update the SMTP port in your configuration accordingly).
Loading