Skip to main content

Building a simple automation script

This capstone stitches earlier Series 18 ideas—filesystem hygiene, HTTP calls, guarded email—into a single maintainable CLI module you can cron later. Patterns mirror professional “small batch job” repos even if toy data powers the demonstration.

Review context from Scheduling tasks when choosing triggers.


📚 Prerequisites

  • Series 18 articles 137–143 (skim OK, but familiarity helps).

🎯 What you'll master

  • Structure configuration + orchestration cleanly (main(), typed helpers).
  • Exit non-zero meaningfully without leaking secrets in tracebacks logged to email.

Script outline

automation_news_digest/
├── digest.py # orchestration logic
├── config.example.env # checklist of required env vars (no secrets!)
└── requirements.txt

digest.py skeleton:

import logging
import os
import sys
from pathlib import Path

import requests
from dotenv import load_dotenv

LOG = logging.getLogger("digest")


def fetch_headline(url: str, timeout: int = 10) -> str:
resp = requests.get(url, timeout=timeout)
resp.raise_for_status()
snippet = resp.text.splitlines()[0][:120]
return snippet


def main() -> int:
load_dotenv()
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s")
inbox = Path(os.environ["DIGEST_ARCHIVE_DIR"]).expanduser()
inbox.mkdir(parents=True, exist_ok=True)

try:
line = fetch_headline(os.environ["SOURCE_URL"])
except requests.RequestException as exc:
LOG.error("download failed", exc_info=exc)
return 2

target = inbox / "latest.txt"
target.write_text(line + "\n", encoding="utf-8")
LOG.info("Wrote digest to %s", target)
return 0


if __name__ == "__main__":
raise SystemExit(main())

Layer email notification by adapting **smtplib patterns**—keep transport separate so unit tests monkeypatch adapters.


Testing hint

Pure functions (fetch_headline) shine in pytest with recorded HTTP fixtures—the Chapter 6 track begins with why automated tests matter.


💡 Key takeaways

  • Keep side effects (write_text, SMTP) narrow so mocks stay simple.
  • main() returning exit codes meshes cleanly with schedulers observing process results.

➡️ Next steps

Open Chapter 6: Testing, Deployment, and Best Practices starting with article 145 — testing fundamentals.