Email notifications for pipen pipelines on status changes.
Uses Python stdlib `smtplib` + `email.message` — zero additional dependencies beyond `pipen`.
Installation
pip install pipen-email
Quickstart
from pipen import Pipen, Proc
class SayHello(Proc):
input = "name:var"
output = "outfile:file:greeting.txt"
script = 'echo "Hello, {{in.name}}!" > {{out.outfile}}'
pipeline = Pipen(
name="my-pipeline",
loglevel="debug",
plugin_opts={
# SMTP — email_host is required for any notifications to fire
"email_host": "smtp.example.com",
"email_port": 587,
"email_use_tls": True,
"email_username": "user",
"email_password": "pass",
# Envelope
"email_to": "you@example.com",
# Job digest (opt-in)
"email_on_job": True,
"email_batch_interval": 60,
},
)
pipeline.set_start(SayHello).set_data(["Alice", "Bob"]).run()
Note:
email_hostmust be set to a truthy value. Without it, no emails will be sent — all notification keys are silently ignored. This acts as a master switch so you can disable the plugin entirely by omittingemail_host.
SMTP Examples
Local debug server
# Terminal 1 — start a debug SMTP server
python -m aiosmtpd -n -l localhost:1025
# Terminal 2 — run the pipeline
python my_pipeline.py
plugin_opts = {
"email_host": "localhost",
"email_port": 1025,
"email_to": "dev@localhost",
}
Gmail (with App Password)
Generate an app password at myaccount.google.com/apppasswords.
plugin_opts = {
"email_host": "smtp.gmail.com",
"email_port": 587,
"email_use_tls": True,
"email_username": "you@gmail.com",
"email_password": "your-16-char-app-password",
"email_to": "you@gmail.com",
}
No-auth relay
plugin_opts = {
"email_host": "smtp-relay.internal",
"email_port": 25,
"email_to": "team@example.com",
}
AWS SES
plugin_opts = {
"email_host": "email-smtp.us-east-1.amazonaws.com",
"email_port": 587,
"email_use_tls": True,
"email_username": "AKIA...",
"email_password": "your-ses-smtp-password",
"email_to": "team@example.com",
}
Configuration Reference
All options live in pipen.config.plugin_opts. Set them via Pipen(plugin_opts={...}), .pipen.toml, or per-process Proc.plugin_opts.
SMTP connection
| Key | Default | Description |
|---|---|---|
email_host |
None |
SMTP server hostname. Must be set for any emails to send. |
email_port |
25 |
SMTP server port |
email_use_tls |
False |
Use STARTTLS on connect |
email_use_ssl |
False |
Use SMTPS (SSL on port 465) |
email_username |
None |
SMTP auth username |
email_password |
None |
SMTP auth password |
email_timeout |
30 |
SMTP connection timeout in seconds |
Email envelope
| Key | Default | Description |
|---|---|---|
email_from |
"pipen@localhost" |
From address |
email_to |
None |
To address(es) — comma-separated string or list |
email_cc |
None |
CC address(es) — comma-separated string or list |
email_bcc |
None |
BCC address(es) — comma-separated string or list |
email_subject_prefix |
"[pipen]" |
Prefix prepended to every subject line |
Pipeline lifecycle
| Key | Default | Description |
|---|---|---|
email_on_start |
True |
Send email when pipeline starts |
email_on_complete |
True |
Send email when pipeline finishes (success or failure) |
Process lifecycle
| Key | Default | Description |
|---|---|---|
email_on_proc_start |
True |
Send email when a process starts |
email_on_proc_done |
True |
Send email when a process completes, fails, or returns cached |
email_on_proc_shutdown |
True |
Send email when a process receives a signal (SIGTERM, SIGKILL, etc.) |
Note:
email_on_proc_donecovers all terminal statuses — completed, failed, and cached. There is no separateemail_on_proc_failedtoggle. When a process fails, the email body includes the failed job's script path, stdout/stderr file paths, and full stderr content.
Job lifecycle
| Key | Default | Description |
|---|---|---|
email_on_job |
False |
Enable batched job status digest emails |
email_batch_interval |
60 |
Minimum seconds between job digest emails |
Logging
| Key | Default | Description |
|---|---|---|
email_loglevel |
"info" |
Log level for email send events. One of "debug", "info", "warning", "error", or "critical". Case-insensitive. |
How It Works
Email guard
All hooks check email_host first via the internal _should_send method. If email_host is not set (or falsy), every notification silently skips. This means you can conditionally enable the plugin:
# Disable in dev, enable in CI
plugin_opts = {
"email_host": "smtp.example.com" if os.environ.get("CI") else None,
"email_to": "team@example.com",
}
Pipeline emails
Sent on on_start and on_complete. Body format:
Pipeline: my-pipeline
Status: COMPLETED
Workdir: .pipen/my-pipeline
Outdir: /output/path
Processes: 3
Process names: ProcA, ProcB, ProcC
Process emails
Sent on on_proc_start, on_proc_done, and on_proc_shutdown. Body format:
Pipeline: my-pipeline
Process: ProcA
Status: COMPLETED
Jobs: 10
Workdir: .pipen/my-pipeline/ProcA
Job status summary:
INIT: 0-9
SUCCEEDED: 0-9
On process failure, the body also includes details about the first failed job:
Information for job #3:
- script: .pipen/my-pipeline/ProcA/3/job.script
- stdout: .pipen/my-pipeline/ProcA/3/job.stdout
- stderr: .pipen/my-pipeline/ProcA/3/job.stderr
Full STDERR:
----------------
Traceback (most recent call last):
...
Job digest emails
When email_on_job is True, each job lifecycle event records its index. A digest email is sent when email_batch_interval seconds have elapsed since the last digest. Digest body format:
Job status digest:
---------------------
INIT: 0-9
RUNNING: 0-9
SUCCEEDED: 0-2
FAILED: 3-5
Job digest emails are also flushed automatically in on_proc_done (via the interval gate).
Shutdown email
Only sent when the process receives an actual signal (sig is truthy). For normal process completion, on_proc_shutdown is called with sig=None and no email is sent — the on_proc_done email covers that case.
Error Handling
SMTP errors are caught and logged at ERROR level. The pipeline never fails due to an email error — _send_email returns False on failure, and the caller continues.
See Also
- pipen — pipeline framework
- example.py — runnable smoke test
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pipen_email-0.0.2.tar.gz.
File metadata
- Download URL: pipen_email-0.0.2.tar.gz
- Upload date:
- Size: 260.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82a76a882fd6672ee2497fb3a00ff5e9620e11287588534b26d7e293c4cb1659
|
|
| MD5 |
f6c7c1285387fd9363014ea2075d4a9f
|
|
| BLAKE2b-256 |
f59f4b4d278154737994595d4e8895e6a06d48282e77274a505fb0578f1328c3
|
File details
Details for the file pipen_email-0.0.2-py3-none-any.whl.
File metadata
- Download URL: pipen_email-0.0.2-py3-none-any.whl
- Upload date:
- Size: 7.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2950f951ba19c0f0c2a55c6bbf8999786162d0a1aded43aa5d6fd112e4fcc022
|
|
| MD5 |
d1725c3bb8c76d51db98d4a58435d782
|
|
| BLAKE2b-256 |
e2046918847d9032c99a93aaec8683e2a55e77525ded8897a6c6453e6b3f00df
|