Metadata-Version: 2.4
Name: airflow-slack-alerts
Version: 0.1.0
Summary: Zero-dependency Slack failure alerts for Apache Airflow: one import, one Variable, sane message included.
Author: Greg Rosa
License: MIT
Project-URL: Homepage, https://github.com/grosa-svg/airflow-slack-alerts
Project-URL: Documentation, https://github.com/grosa-svg/airflow-slack-alerts/blob/main/docs/configuration.md
Keywords: airflow,slack,alerts,notifications,on_failure_callback,webhook
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Monitoring
Classifier: Framework :: Apache Airflow
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Dynamic: license-file

# airflow-slack-alerts

Zero-dependency Slack failure alerts for Apache Airflow. One import, one Airflow
Variable, and every task failure lands in your Slack channel with a sane,
ready-made message — DAG, task, try number, truncated exception, log link.

```python
from airflow_slack_alerts import slack_failure

default_args = {"on_failure_callback": slack_failure}
```

That's the whole integration.

## Why this instead of the official `SlackWebhookNotifier`?

The official notifier (in `apache-airflow-providers-slack`) is a fine *transport* —
but it ships no message, requires an Airflow Connection, and pulls in `slack_sdk`.

|  | `airflow-slack-alerts` | provider `SlackWebhookNotifier` |
|---|---|---|
| Dependencies | **none** (stdlib urllib) | `apache-airflow-providers-slack` + `slack_sdk` |
| Failure message | **included** (customizable) | bring your own Jinja template |
| Configuration | Airflow Variable or env var | Airflow Connection |
| Unconfigured behavior | **logged warning, no-op** | exception |
| Alerting can crash the task flow | never (never-raise by design) | possible |
| Blocks/attachments/proxy support | no (text only, by design) | yes |

If you need Slack blocks, dynamic channel routing via a bot token, or attachments —
use the provider. If you need *"tell me in Slack when a task dies"* — this.

## Setup (2 minutes)

1. **Create a Slack Incoming Webhook** — Slack app config → Incoming Webhooks →
   Add webhook → pick the channel. The URL is permanently bound to that channel.
2. **Store it** in the Airflow Variable `slack_webhook_url`
   (Admin → Variables), or in the environment variable `SLACK_WEBHOOK_URL`.
3. **Wire the callback** (DAG level via `default_args`, or per task):

```python
from airflow_slack_alerts import slack_failure

with DAG(..., default_args={"on_failure_callback": slack_failure}):
    ...
```

## Multiple channels

A webhook posts to exactly one channel, so channels = webhooks = Variables:

```python
from airflow_slack_alerts import failure_alert

default_args = {"on_failure_callback": failure_alert(var="slack_webhook_url_data_team")}

critical = SomeOperator(
    ...,
    on_failure_callback=failure_alert(var="slack_webhook_url_oncall", mention="<!here>"),
)
```

## Ad-hoc messages

```python
from airflow_slack_alerts import notify

notify(f"Backfill finished: {rows:,} rows across {months} months")
```

## Customizing the message

Prefix, mentions, truncation length, or a fully custom formatter — see
[docs/configuration.md](docs/configuration.md).

## Design principles

- **Never raise.** Alerting must not mask the original task failure; any
  internal error is logged and swallowed.
- **Degrade gracefully.** Missing webhook → one warning in the task log, no crash.
  A half-configured deployment stays a deployment.
- **Zero dependencies.** The package imports Airflow lazily and only for
  `Variable.get`; core logic is testable without Airflow installed.

## License

MIT
