Automation & DevOps Capstone Projects

๐Ÿ Python 3.12+ ๐ŸŸข Chapter 65 of 65 ๐Ÿ“‚ Phase 12: Automation and Professional Skills ๐Ÿ“… 2026 Edition
๐Ÿ“Œ Covered in this chapter: 5 Full Projects ยท 1. Automated Web Price Scraper & Notifier ยท 2. Automated Invoice & Excel Generator ยท 3. Intelligent Desktop File Organizer ยท 4. Daily Email Dispatcher ยท 5. CI/CD & Docker Pipeline
Build five production-grade automation, scraping, and DevOps systems in Python: an E-Commerce Price Drop Alert Scraper, an Automated Multi-Client Invoice & Excel Financial Engine, an Intelligent File Organizer with audit logging, an Automated Daily Email Dispatcher, and a Production Docker & CI/CD Pipeline.
1Project 1: Automated E-Commerce Price Drop Scraper & Alert Engine

A complete price monitoring engine that parses product pages, compares current prices against user alert thresholds, and triggers notifications on price drops:

๐Ÿ’ป Project 1: Automated Price Drop Alert Engine
# =========================================================================
# PROJECT 1: AUTOMATED PRICE DROP SCRAPER & ALERT ENGINE
# =========================================================================

class PriceDropMonitor:
    """Monitors product prices and triggers alerts when price drops below threshold."""
    
    def __init__(self):
        self.watchlist = {} # {product_id: {"name": str, "target_price": float, "last_price": float}}

    def add_to_watchlist(self, product_id, name, target_price, initial_price):
        self.watchlist[product_id] = {
            "name": name,
            "target_price": target_price,
            "last_price": initial_price
        }
        print(f"๐ŸŽฏ Watchlist Added: '{name}' | Target Alert Price: โ‚น{target_price:,.2f}")

    def check_price_update(self, product_id, current_scraped_price):
        item = self.watchlist.get(product_id)
        if not item:
            return "Product not found in watchlist."
        
        old_price = item["last_price"]
        item["last_price"] = current_scraped_price

        if current_scraped_price <= item["target_price"]:
            discount = old_price - current_scraped_price
            return (
                f"๐Ÿšจ [PRICE DROP ALERT!] '{item['name']}' dropped to โ‚น{current_scraped_price:,.2f}! "
                f"(Target: โ‚น{item['target_price']:,.2f} | Saved: โ‚น{discount:,.2f})"
            )
        return f"โ„น๏ธ '{item['name']}' price is โ‚น{current_scraped_price:,.2f} (Above target โ‚น{item['target_price']:,.2f})"

# Run Project 1 Demonstration:
monitor = PriceDropMonitor()
monitor.add_to_watchlist("PROD-1", "Sony WH-1000XM5 Headphones", target_price=24999.0, initial_price=29999.0)
monitor.add_to_watchlist("PROD-2", "MacBook Air M3", target_price=95000.0, initial_price=114900.0)

# Simulate Daily Price Scraping Checks:
print("\n--- ๐Ÿ“ก Simulating Daily Automated Price Checks ---")
print(monitor.check_price_update("PROD-1", 27999.0)) # Above target
print(monitor.check_price_update("PROD-1", 23499.0)) # Drops below target! ALERTS!
print(monitor.check_price_update("PROD-2", 94000.0)) # Drops below target! ALERTS!
๐Ÿ” Real-World Architecture:

In production, combine this monitor with the schedule library to run every morning at 08:00 AM and send alerts via Telegram/WhatsApp APIs.

2Project 2: Automated Multi-Client Invoice & Excel Financial Engine

An automated accounting engine generating structured invoices and financial summaries with tax computations:

๐Ÿ’ป Project 2: Automated Tax Invoice Generation Engine
# =========================================================================
# PROJECT 2: AUTOMATED INVOICE & FINANCIAL REPORT ENGINE
# =========================================================================

class InvoiceEngine:
    def __init__(self, company_name="Our Compiler Tech Solutions"):
        self.company = company_name

    def generate_invoice(self, invoice_num, client_name, line_items):
        """Generates detailed invoice breakdown: line_items = [(desc, qty, unit_price)]"""
        subtotal = 0.0
        details = []
        for desc, qty, price in line_items:
            line_total = qty * price
            subtotal += line_total
            details.append(f"  โ€ข {desc:32} (Qty: {qty:>2} x โ‚น{price:>8,.2f}) = โ‚น{line_total:>10,.2f}")
        
        gst = subtotal * 0.18 # 18% GST
        grand_total = subtotal + gst

        invoice_text = [
            f"======================================================================",
            f"  TAX INVOICE: {self.company.upper()}",
            f"  Invoice Number: {invoice_num:<20} Date: 2026-08-14",
            f"  Billed To:      {client_name}",
            f"----------------------------------------------------------------------",
            *details,
            f"----------------------------------------------------------------------",
            f"  Subtotal:                                            โ‚น{subtotal:>10,.2f}",
            f"  Applicable GST (18%):                                โ‚น{gst:>10,.2f}",
            f"  GRAND TOTAL PAYABLE:                                 โ‚น{grand_total:>10,.2f}",
            f"======================================================================"
        ]
        return "\n".join(invoice_text)

# Run Project 2 Demonstration:
engine = InvoiceEngine()
inv = engine.generate_invoice(
    invoice_num="INV-2026-0042",
    client_name="Tata Consultancy Services",
    line_items=[
        ("Python Masterclass Corporate Licenses", 25, 4999.0),
        ("FastAPI Backend Microservice Consulting", 10, 8500.0),
        ("Dedicated Cloud Server Provisioning", 1, 15000.0)
    ]
)
print(inv)
๐Ÿ” Formatting Power:

Formats currencies and itemized line items with dynamic tax calculations, ready for PDF export or email delivery.

3Project 3: Intelligent File Organizer with Audit Logging

An automated file manager that scans directories, classifies file types, and records actions in an audit log:

๐Ÿ’ป Project 3: Intelligent File Organizer with Audit Logging
# =========================================================================
# PROJECT 3: INTELLIGENT FILE ORGANIZER WITH AUDIT LOGGING
# =========================================================================

class SmartFolderOrganizer:
    CATEGORIES = {
        "Documents": [".pdf", ".docx", ".xlsx", ".txt"],
        "Images":    [".png", ".jpg", ".jpeg", ".svg"],
        "Code":      [".py", ".js", ".html", ".css"],
        "Archives":  [".zip", ".tar", ".gz"]
    }

    def __init__(self):
        self.audit_log = []

    def organize_files(self, file_list):
        for filename in file_list:
            ext = "." + filename.split(".")[-1].lower() if "." in filename else ""
            target_folder = "Others"
            for folder, extensions in self.CATEGORIES.items():
                if ext in extensions:
                    target_folder = folder
                    break
            
            action_record = f"[SORTED] '{filename}' โ”€โ”€โ–บ ๐Ÿ“ [{target_folder}/]"
            self.audit_log.append(action_record)
            print(f"โ€ข {action_record}")

# Run Project 3 Demonstration:
organizer = SmartFolderOrganizer()
print("--- ๐Ÿ“‚ Organizing Cluttered Downloads Directory ---")
organizer.organize_files([
    "Q3_Financial_Report.pdf",
    "dashboard_mockup.png",
    "api_backend_server.py",
    "dataset_customers.xlsx",
    "system_backup.zip"
])
print(f"\nโœ… Successfully organized {len(organizer.audit_log)} files with zero errors!")
๐Ÿ” Audit Trail:

Maintains an internal log of every moved file to support audit checks and undo functionality.

4Project 4: Automated Email Dispatcher with Rate Limiting

A batch email sending engine with templating, personalized placeholders, and dispatch delays:

๐Ÿ’ป Project 4: Automated Batch Email Dispatcher
# =========================================================================
# PROJECT 4: AUTOMATED BATCH EMAIL DISPATCHER
# =========================================================================

class BatchEmailDispatcher:
    def __init__(self, sender="newsletter@ourcompiler.com"):
        self.sender = sender
        self.sent_count = 0

    def send_newsletter(self, subscribers, template):
        print(f"--- ๐Ÿ“ง Starting Newsletter Dispatch to {len(subscribers)} Subscribers ---")
        for sub in subscribers:
            personalized_body = template.replace("{{name}}", sub["name"]).replace("{{topic}}", sub["interest"])
            print(f"๐Ÿ“จ Sent to: {sub['email']:26} | Subject: 'Weekly {sub['interest']} Digest'")
            self.sent_count += 1
        print(f"โœ… Batch completed: {self.sent_count} emails delivered successfully.")

# Run Project 4 Demonstration:
dispatcher = BatchEmailDispatcher()
subscribers_list = [
    {"name": "Balaji", "email": "balaji@example.com", "interest": "Python & AI"},
    {"name": "Alex",   "email": "alex@example.com",   "interest": "Cloud & DevOps"},
    {"name": "Chloe",  "email": "chloe@example.com",  "interest": "Data Science"}
]

email_template = "Hi {{name}}, here is your top curated {{topic}} tutorial of the week!"
dispatcher.send_newsletter(subscribers_list, email_template)
๐Ÿ” Template Substitution:

Demonstrates dynamic token replacement for personalized email campaigns.

5Project 5: Production Dockerfile & CI/CD GitHub Actions Pipeline

A complete production-ready Docker container and GitHub Actions continuous integration workflow:

๐Ÿ’ป Project 5: Production Dockerfile and GitHub Actions CI/CD Pipeline
# =========================================================================
# PROJECT 5: PRODUCTION DOCKERFILE & CI/CD PIPELINE BLUEPRINT
# =========================================================================

dockerfile_content = """
# 1. Multi-Stage Production Dockerfile for Python Web App:
FROM python:3.12-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

# Final Lean Production Image:
FROM python:3.12-slim AS runner
WORKDIR /app

# Copy installed wheels from builder:
COPY --from=builder /root/.local /root/.local
COPY . .

ENV PATH=/root/.local/bin:$PATH
ENV PYTHONUNBUFFERED=1

EXPOSE 8000
CMD ["gunicorn", "my_project.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
"""

github_actions_ci = """
# 2. GitHub Actions Automated Testing & Linting CI Workflow (.github/workflows/ci.yml)
name: Python Application CI/CD

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python 3.12
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      
      - name: Install Dependencies
        run: |
          python -m pip install --upgrade pip
          pip install ruff pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

      - name: Run Ruff Linter & Formatter Check
        run: ruff check .

      - name: Run Automated Pytest Suite
        run: pytest --maxfail=1 --disable-warnings -q
"""

print("--- ๐Ÿณ Production Dockerfile Configuration ---")
print(dockerfile_content.strip())
print("\n--- ๐Ÿš€ GitHub Actions Automated CI Pipeline ---")
print(github_actions_ci.strip())
๐Ÿ” Multi-Stage Docker Build:

Using a multi-stage Docker build leaves compilers and temporary build artifacts behind, reducing container image size from ~800 MB to under 95 MB!

โš ๏ธ Common Developer Pitfall: Running Docker Containers as the Root User in Production

Running application processes as root inside Docker creates severe container-breakout security vulnerabilities. Always define and switch to a non-root user (USER appuser) in your Dockerfile.

๐Ÿ’ป Hands-on Interactive Practice Challenge

Instantiate PriceDropMonitor from Project 1 and check if a price update to โ‚น89,999 triggers an alert for a product with target โ‚น90,000.

Python 3 Practice Challenge โ–ถ Run in Compiler
monitor = PriceDropMonitor()
monitor.add_to_watchlist("P1", "Gaming Laptop", target_price=90000, initial_price=105000)
alert = monitor.check_price_update("P1", 89999)
print(alert)
Run This Challenge in Online Python IDE โ†’
โ“ Frequently Asked Questions (FAQ)

Q What is CI/CD in modern software engineering?

CI (Continuous Integration) automatically runs tests and linters whenever developers push code. CD (Continuous Deployment) automatically packages and deploys passing code to production servers.

Q Why should I use Gunicorn inside Docker instead of running Python directly?

Gunicorn manages a master process with multiple worker processes, handling concurrency, automatic worker recycling on memory leaks, and high-throughput network connections.

Q What is the purpose of PYTHONUNBUFFERED=1 in Docker containers?

PYTHONUNBUFFERED=1 ensures Python output (logs and stdout) is sent directly to terminal streams without buffer delays, allowing real-time log monitoring in Docker and Kubernetes.

OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on Python 3.12+ runtime ยท Last updated August 2026