Loading

CyberOak Automation Hub

Production-grade scripts, orchestration walkthroughs, and developer updates.

⭐ Featured Blueprint • Data Automation

Turn Any Python Script into an Automated PDF Report — Emailed on Schedule (with WeasyPrint)

Skip the "can you send me the report" Slack messages. Learn how to generate a styled PDF from your data with WeasyPrint and email it automatically using smtplib — then schedule it to run and land in inboxes on its own with CyberOak.

preview.py
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
from weasyprint import HTML

# Email and report parameters are supplied by CyberOak's
# Key-Value Parameters section.
SMTP_HOST = SMTP_HOST
SMTP_PORT = SMTP_PORT
SMTP_USER = SMTP_USER
SMTP_PASSWORD = SMTP_PASSWORD
REPORT_RECIPIENT = REPORT_RECIPIENT


def build_html_report(rows: list[dict], title: str) -> str:
    table_rows = "".join(
        f"<tr><td>{r['name']}</td><td>{r['value']}</td></tr>"
        for r in rows
    )

    return f"""
    <html>
    <head>
        <style>
            @page {{
                size: A4;
                margin: 2cm;
                @bottom-center {{
                    content: "Generated automatically by CyberOak";
                    font-size: 9px;
                    color: #999;
                }}
            }}
            body {{ font-family: Helvetica, sans-serif; }}
            h1 {{ color: #212832; }}
            table {{ width: 100%; border-collapse: collapse; }}
            th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
            th {{ background-color: #00ba94; color: white; }}
        </style>
    </head>
    <body>
        <h1>{title}</h1>
        <table>
            <tr><th>Metric</th><th>Value</th></tr>
            {table_rows}
        </table>
    </body>
    </html>
    """


def html_to_pdf(html_content: str, output_path: str):
    HTML(string=html_content).write_pdf(output_path)


def send_email_with_attachment(
    subject: str,
    body: str,
    attachment_path: str,
    recipient: str,
):
    message = MIMEMultipart()
    message["From"] = SMTP_USER
    message["To"] = recipient
    message["Subject"] = subject
    message.attach(MIMEText(body, "plain"))

    with open(attachment_path, "rb") as f:
        part = MIMEBase("application", "octet-stream")
        part.set_payload(f.read())
        encoders.encode_base64(part)
        part.add_header(
            "Content-Disposition",
            f"attachment; filename={attachment_path}",
        )
        message.attach(part)

    print("Connecting to SMTP server...")
    with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
        server.starttls()
        server.login(SMTP_USER, SMTP_PASSWORD)
        server.sendmail(SMTP_USER, recipient, message.as_string())

    print(f"Report emailed to {recipient}")


# Example usage
if __name__ == "__main__":
    report_data = [
        {"name": "New Signups", "value": 128},
        {"name": "Active Trials", "value": 342},
        {"name": "Churned Accounts", "value": 7},
    ]

    html = build_html_report(report_data, "Weekly Growth Report")
    pdf_path = "weekly_growth_report.pdf"

    print("Generating PDF report...")
    html_to_pdf(html, pdf_path)

    send_email_with_attachment(
        subject="Weekly Growth Report",
        body="Attached is this week's automated growth report.",
        attachment_path=pdf_path,
        recipient=REPORT_RECIPIENT,
    )
Ken Muriithi
Sep 23, 2026 • 5 min read
Read Full Article →

Latest Articles

Search Engine Optimization • 4 min read

Build Your Own Python SEO Site Crawler: Audit Broken Links & Title Tags with Zero Setup

Want to crawl your website without paying for expensive SEO software? This Python automation script uses requests and Beautiful Soup to crawl your website, discover internal links, detect broken pages, and audit page titles. Run it instantly on CyberOak—no package installation or environment setup

Aug 03, 2026 Read Full Article →
Artificial Intelligence • 2 min read

Zero-Setup AI Automation: Summarizing Customer Feedback with OpenAI and Pandas on Cyberoak

Streamline your customer intelligence workflows without managing infrastructure. In this guide, learn how to tap into Cyberoak's pre-installed libraries to fetch raw text data, perform zero-shot sentiment analysis using OpenAI's gpt-4o, and export structural pipeline metrics directly to Excel.

Jul 14, 2026 Read Full Article →
Workflow Automation • 2 min read

Automating Document Workflows: Extracting PDF Line Items to JSON with Python

Manually extracting structured tables and text from enterprise PDFs is a operational bottleneck. In this guide, we break down how to automate a robust data pipeline on Cyberoak using pdfplumber and advanced Regular Expressions (Regex) to cleanly parse unstructured PDF line items into a scalable JSON

Jul 13, 2026 Read Full Article →
Data Engineering • 3 min read

Mastering the Data Pipeline: From PostgreSQL to Excel with Python

Learn how to build a clean, automated data pipeline using Python. This step-by-step tutorial covers connecting to a PostgreSQL database with psycopg2, loading queries directly into a Pandas DataFrame, and exporting the data into a polished Excel (.xlsx) file using openpyxl

Jul 12, 2026 Read Full Article →