Python Snippets

Send Email with HTML Content and Attachments using Python

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import os
from typing import List, Optional

def send_html_email(
    sender_email: str,
    sender_password: str,
    recipient_emails: List[str],
    subject: str,
    html_content: str,
    attachments: Optional[List[str]] = None,
    smtp_server: str = "smtp.gmail.com",
    smtp_port: int = 587
) -> bool:
    """
    Send an HTML email with optional attachments.
    
    Args:
        sender_email (str): Sender's email address
        sender_password (str): Sender's email password or app password
        recipient_emails (List[str]): List of recipient email addresses
        subject (str): Email subject line
        html_content (str): HTML content for the email body
        attachments (Optional[List[str]]): List of file paths to attach
        smtp_server (str): SMTP server address (default: Gmail)
        smtp_port (int): SMTP server port (default: 587 for TLS)
    
    Returns:
        bool: True if email was sent successfully, False otherwise
    """
    
    try:
        # Create message container
        msg = MIMEMultipart()
        msg['From'] = sender_email
        msg['To'] = ", ".join(recipient_emails)
        msg['Subject'] = subject
        
        # Add HTML content
        msg.attach(MIMEText(html_content, 'html'))
        
        # Add attachments if provided
        if attachments:
            for file_path in attachments:
                if os.path.isfile(file_path):
                    with open(file_path, "rb") as attachment:
                        part = MIMEBase('application', 'octet-stream')
                        part.set_payload(attachment.read())
                    
                    encoders.encode_base64(part)
                    part.add_header(
                        'Content-Disposition',
                        f'attachment; filename= {os.path.basename(file_path)}'
                    )
                    msg.attach(part)
        
        # Create SMTP session
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.starttls()  # Enable TLS encryption
        server.login(sender_email, sender_password)
        
        # Send email
        text = msg.as_string()
        server.sendmail(sender_email, recipient_emails, text)
        server.quit()
        
        print("Email sent successfully!")
        return True
        
    except Exception as e:
        print(f"Error occurred while sending email: {str(e)}")
        return False

# Example usage
if __name__ == "__main__":
    # Email configuration
    SENDER_EMAIL = "your_email@gmail.com"
    SENDER_PASSWORD = "your_app_password"  # Use app password for Gmail
    RECIPIENTS = ["recipient1@example.com", "recipient2@example.com"]
    
    # HTML content
    html_body = """
    <html>
      <body>
        <h2>Welcome to Our Service!</h2>
        <p>Hello there,</p>
        <p>We're excited to have you on board. Here are some key features:</p>
        <ul>
          <li>✔ Real-time notifications</li>
          <li>✔ Advanced analytics dashboard</li>
          <li>✔ 24/7 customer support</li>
        </ul>
        <p>Feel free to explore our <a href="https://example.com">documentation</a> to get started.</p>
        <br>
        <p>Best regards,<br>The Team</p>
      </body>
    </html>
    """
    
    # Optional attachments
    files_to_attach = ["document.pdf", "image.png"]  # Update with actual file paths
    
    # Send the email
    success = send_html_email(
        sender_email=SENDER_EMAIL,
        sender_password=SENDER_PASSWORD,
        recipient_emails=RECIPIENTS,
        subject="Welcome to Our Platform!",
        html_content=html_body,
        attachments=files_to_attach  # Remove this parameter if no attachments needed
    )
    
    if not success:
        print("Failed to send email.")

This code snippet provides a robust solution for sending HTML emails with attachments in Python. It uses the built-in smtplib and email modules to create and send emails with rich HTML content and file attachments.

Features:

  1. HTML Email Support: Sends professionally formatted emails with HTML content
  2. Attachment Support: Can attach multiple files to emails
  3. Error Handling: Comprehensive exception handling with informative error messages
  4. Flexible Configuration: Works with different SMTP servers (defaults to Gmail)
  5. Type Hints: Full type annotations for better code clarity and IDE support

Why This is Useful:

How to Use:

  1. Gmail Setup:
    • Enable 2-factor authentication on your Gmail account
    • Generate an App Password (don’t use your regular password)
    • Update SENDER_EMAIL and SENDER_PASSWORD with your credentials
  2. Other Providers:
    • Update smtp_server and smtp_port for your email provider
    • Common values:
      • Outlook: smtp-mail.outlook.com, port 587
      • Yahoo: smtp.mail.yahoo.com, port 587
  3. Customize Content:
    • Modify the html_body variable with your desired HTML content
    • Update recipient emails in the RECIPIENTS list
    • Add file paths to files_to_attach if sending attachments
  4. Run the Script:
    • Execute the script to send your email
    • Check the console output for success or error messages

The function returns True on successful delivery and False if an error occurs, making it easy to integrate into larger applications that need to verify email delivery status.