Tiny library for emailing yourself from unattended tools — cron jobs, scheduled tasks, long-running pipelines. Plain text, Gmail-compatible SMTP, hot-reload of credentials and recipients, zero runtime dependencies.
pip install git+https://github.com/wuwenrui555/pingme.git(Pin to a tag with @v0.1.2 for reproducibility; omit for the latest release on main.)
Requires Python 3.12+.
# ~/.config/pingme/smtp.env (or equivalent env vars)
PINGME_SMTP_USER=you@gmail.com
PINGME_SMTP_APP_PASSWORD=xxxxxxxxxxxxxxxxRecipients per event live at <config-dir>/recipients/<event>.txt, with default.txt as fallback (one email per line, # for comments).
For Gmail (the most common case), the full setup walkthrough — 2-Step Verification, app passwords, and network troubleshooting — is at docs/setup-gmail.md.
from pathlib import Path
from pingme import (
SmtpCredentialsMissing,
load_smtp_credentials,
resolve_recipients,
send_email,
)
creds = load_smtp_credentials()
if isinstance(creds, SmtpCredentialsMissing):
raise RuntimeError("missing PINGME_SMTP_USER / PINGME_SMTP_APP_PASSWORD")
res = resolve_recipients("alerts", Path("~/.config/myapp/recipients").expanduser())
send_email(
creds=creds,
recipients=res.emails,
subject="[myapp] disk almost full",
body="myhost /var at 96% used",
)- Best-effort delivery. SMTP errors are logged, never raised — no
try/exceptneeded aroundsend_email. - Hot-reload. Every
load_smtp_credentialsandresolve_recipientscall re-reads its source. Edit the dotenv or recipients files and the next call sees the change. - Caller-owned concerns. No dedup, no
logging.Handlerintegration, no event registry, no payload formatting, no recipient validation, no HTML or non-SMTP channels. pingme is the transport layer; callers wire those above it.
Apache 2.0, see LICENSE.