Skip to main content

Sending Email reports in Python

Here’s how you can automate sending daily email reports in Python using smtplib for sending emails and scheduling the job with the schedule or APScheduler library. I’ll walk you through the process step by step.

Step 1: Set Up Your Email Server Credentials

To send emails using Python, you’ll need access to an email SMTP server. For this example, let’s use Gmail’s SMTP server. First, create a .env file or store your credentials securely for security reasons, especially if you’re sharing the code. Make sure to enable “Less secure apps” for your Gmail account or use OAuth for more security (Gmail is used here, but any email provider’s SMTP server can be used).

Step 2: Install Required Libraries

First, you need to install the required packages using pip:

pip install schedule
pip install python-dotenv

Or, if you plan to use APScheduler for advanced scheduling:

pip install apscheduler

Step 3: Script to Send Email Reports

import smtplib
import schedule
import time
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from dotenv import load_dotenv
import os

# Load environment variables from a .env file
load_dotenv()

# Set up email credentials (or load them securely from environment variables)
EMAIL_ADDRESS = os.getenv('EMAIL_ADDRESS')  # Your email address
EMAIL_PASSWORD = os.getenv('EMAIL_PASSWORD')  # Your email password
TO_EMAIL = os.getenv('TO_EMAIL')  # Recipient email address

# Email content generation function
def generate_email_report():
    subject = "Daily Report"
    body = """
    Hello,

    This is your daily report. 

    Best Regards,
    Your Automation Script
    """

    return subject, body

# Function to send email
def send_email(subject, body):
    # Create the message
    msg = MIMEMultipart()
    msg['From'] = EMAIL_ADDRESS
    msg['To'] = TO_EMAIL
    msg['Subject'] = subject

    # Attach the body of the email
    msg.attach(MIMEText(body, 'plain'))

    try:
        # Set up the server and login
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.starttls()  # Secure the connection
        server.login(EMAIL_ADDRESS, EMAIL_PASSWORD)

        # Send the email
        server.sendmail(EMAIL_ADDRESS, TO_EMAIL, msg.as_string())
        print(f"Email sent successfully to {TO_EMAIL}")

        # Close the connection
        server.quit()
    except Exception as e:
        print(f"Failed to send email. Error: {e}")

# Function to schedule and send the daily report
def daily_report_job():
    subject, body = generate_email_report()
    send_email(subject, body)

# Schedule the report to run daily at a specific time
schedule.every().day.at("09:00").do(daily_report_job)  # Set to 9:00 AM

# Keep the script running
if __name__ == "__main__":
    while True:
        schedule.run_pending()
        time.sleep(60)  # Check every minute

Step 4: Environment Variables

Create a .env file in the same directory with the following content:

[email protected]
EMAIL_PASSWORD=your_password
[email protected]

This .env file will store sensitive data like your email credentials securely.

Step 5: How It Works

  1. Libraries:
    • smtplib: Used to send the email via the SMTP protocol.
    • schedule: Used to run the function daily at a specified time.
    • dotenv: Loads email credentials from environment variables.
    • email.mime.multipart and email.mime.text: Helps structure the email and its content.
  2. Email Sending:
    • The function send_email sets up an SMTP connection to Gmail, logs in, and sends an email to the recipient.
  3. Scheduling:
    • The schedule.every().day.at("09:00").do(daily_report_job) ensures that the report is sent daily at 9:00 AM.
  4. Environment Variables:
    • Store sensitive data in a .env file to avoid hardcoding them into the script.

Step 6: Running the Script

  1. Run the Python script from the terminal or deploy it to a server.
    python daily_email_report.py
  2. The script will run in the background and send an email every day at the specified time.

Advanced Option: Use APScheduler (Optional)

If you want a more flexible or robust scheduling solution, you can use APScheduler instead of schedule.

Here’s a basic example of how to modify the script:

from apscheduler.schedulers.blocking import BlockingScheduler

# Function to schedule and send the daily report
def daily_report_job():
    subject, body = generate_email_report()
    send_email(subject, body)

# Schedule with APScheduler
scheduler = BlockingScheduler()
scheduler.add_job(daily_report_job, 'cron', hour=9, minute=0)  # Run at 9:00 AM every day

if __name__ == "__main__":
    scheduler.start()

Step 7: Deploying the Script

To deploy this script for continuous running, you can:

  1. Run it on a server like a VPS or cloud service.
  2. Use Cron jobs (Linux/macOS) or Task Scheduler (Windows) to keep it running daily without user interaction.

Daniel Dye

Daniel Dye is the President of NativeRank Inc., a premier digital marketing agency that has grown into a powerhouse of innovation under his leadership. With a career spanning decades in the digital marketing industry, Daniel has been instrumental in shaping the success of NativeRank and its impressive lineup of sub-brands, including MarineListings.com, LocalSEO.com, MarineManager.com, PowerSportsManager.com, NikoAI.com, and SearchEngineGuidelines.com. Before becoming President of NativeRank, Daniel served as the Executive Vice President at both NativeRank and LocalSEO for over 12 years. In these roles, he was responsible for maximizing operational performance and achieving the financial goals that set the foundation for the company’s sustained growth. His leadership has been pivotal in establishing NativeRank as a leader in the competitive digital marketing landscape. Daniel’s extensive experience includes his tenure as Vice President at GetAds, LLC, where he led digital marketing initiatives that delivered unprecedented performance. Earlier in his career, he co-founded Media Breakaway, LLC, demonstrating his entrepreneurial spirit and deep understanding of the digital marketing world. In addition to his executive experience, Daniel has a strong technical background. He began his career as a TAC 2 Noc Engineer at Qwest (now CenturyLink) and as a Human Interface Designer at 9MSN, where he honed his skills in user interface design and network operations. Daniel’s educational credentials are equally impressive. He holds an Executive MBA from the Quantic School of Business and Technology and has completed advanced studies in Architecture and Systems Engineering from MIT. His commitment to continuous learning is evident in his numerous certifications in Data Science, Machine Learning, and Digital Marketing from prestigious institutions like Columbia University, edX, and Microsoft. With a blend of executive leadership, technical expertise, and a relentless drive for innovation, Daniel Dye continues to propel NativeRank Inc. and its sub-brands to new heights, making a lasting impact in the digital marketing industry.

More Articles By Daniel Dye

Olya Ianovskaia at Search Engine Land wrote a great article on Structured Data and SEO, which we wanted to expand on. As we move into 2025, structured data remains crucial for SEO, helping search engines understand and display content in a way that improves visibility and drives engagement. This article delves into the importance of […]
In today’s digital landscape, understanding how your competitors’ brands are performing in the market is critical for staying competitive. One tool that offers invaluable insights into brand engagement and popularity is Google Trends. This free service from Google provides real-time data on search trends, which you can use to monitor how frequently people are searching […]
Google recently updated its spam policies document, introducing additional details on site reputation abuse and revising several key sections. These updates aim to provide clearer guidelines on how site owners can maintain their site’s reputation and avoid being penalized by Google for spammy practices. Let’s take a deep dive into the new changes, including examples […]

Was this helpful?