How to send an email with Python?
Categories:
Sending Emails with Python: A Comprehensive Guide

Learn how to send emails programmatically using Python's smtplib
and email
modules, covering plain text, HTML, and attachments.
Sending emails from your Python applications is a common requirement for various tasks, such as sending notifications, reports, or automated messages. Python provides powerful built-in modules, primarily smtplib
for sending emails via an SMTP server and email
for constructing email messages, including handling different content types and attachments.
Understanding the Core Modules: smtplib and email
Before diving into code, it's essential to understand the roles of the two main modules involved:
smtplib
: This module defines an SMTP client session object that can be used to send mail to any Internet machine with an SMTP or ESMTP listener daemon. It handles the communication with the mail server.email
: This package is a library for managing email messages. It provides classes for creating, parsing, and modifying email messages, including support for MIME (Multipurpose Internet Mail Extensions) to handle various content types like plain text, HTML, and attachments.
flowchart TD A[Python Application] --> B{smtplib.SMTP()} B --> C{Connect to SMTP Server} C --> D{Login (if required)} D --> E{Construct Email (email module)} E --> F{Send Email (send_message)} F --> G[Recipient's Mailbox]
Basic Email Sending Process Flow in Python
Sending a Simple Plain Text Email
The simplest form of email involves sending plain text. This requires setting up the SMTP connection, logging in (if your server requires authentication), and then sending the message. We'll use smtplib
directly for this basic example.
import smtplib
# Email configuration
SENDER_EMAIL = 'your_email@example.com'
SENDER_PASSWORD = 'your_email_password'
RECEIVER_EMAIL = 'recipient@example.com'
SMTP_SERVER = 'smtp.example.com' # e.g., 'smtp.gmail.com'
SMTP_PORT = 587 # or 465 for SSL
# Message content
subject = 'Hello from Python!'
body = 'This is a test email sent from a Python script.'
message = f'Subject: {subject}\n\n{body}'
try:
# Establish a secure connection (TLS for port 587)
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls() # Upgrade the connection to a secure encrypted SSL/TLS connection
server.login(SENDER_EMAIL, SENDER_PASSWORD)
server.sendmail(SENDER_EMAIL, RECEIVER_EMAIL, message)
print('Email sent successfully!')
except Exception as e:
print(f'Error sending email: {e}')
Python code to send a basic plain text email.
SMTP_SERVER
is smtp.gmail.com
and SMTP_PORT
is 587
(for TLS) or 465
(for SSL). Remember to enable 'Less secure app access' or use an App Password if you're using Gmail with two-factor authentication.Sending HTML Emails and Attachments with the email Module
For more complex emails, such as those with HTML content or attachments, the email
module becomes indispensable. It allows you to construct MIME messages, which can contain multiple parts (e.g., a plain text version, an HTML version, and various attachments).
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
# Email configuration
SENDER_EMAIL = 'your_email@example.com'
SENDER_PASSWORD = 'your_email_password'
RECEIVER_EMAIL = 'recipient@example.com'
SMTP_SERVER = 'smtp.example.com'
SMTP_PORT = 587
# Create a multipart message and set headers
msg = MIMEMultipart()
msg['From'] = SENDER_EMAIL
msg['To'] = RECEIVER_EMAIL
msg['Subject'] = 'HTML Email with Attachment from Python'
# Add body to email
html_body = """
<html>
<body>
<p>Hi there,</p>
<p>This is an <b>HTML email</b> sent from Python!</p>
<p>It includes an attachment.</p>
</body>
</html>
"""
msg.attach(MIMEText(html_body, 'html'))
# Attach a file
filename = 'example.txt' # In the same directory as your script
with open(filename, 'w') as f:
f.write('This is the content of the attached file.')
attachment = open(filename, 'rb') # Open the file in binary mode
# Encode file in base64
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
# Add header as key/value pair to attachment part
part.add_header('Content-Disposition', f'attachment; filename= {filename}')
msg.attach(part)
try:
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls()
server.login(SENDER_EMAIL, SENDER_PASSWORD)
server.send_message(msg)
print('HTML email with attachment sent successfully!')
except Exception as e:
print(f'Error sending email: {e}')
finally:
attachment.close() # Close the file handle
import os
os.remove(filename) # Clean up the temporary file
Sending an HTML email with a file attachment using the email
module.
Best Practices and Security Considerations
When sending emails programmatically, keep the following best practices and security measures in mind:
- Use TLS/SSL: Always use
starttls()
for port 587 or connect directly via SSL for port 465 to encrypt your communication with the SMTP server. This protects your credentials and message content. - Handle Credentials Securely: As mentioned, avoid hardcoding passwords. Use environment variables (e.g.,
os.environ.get('EMAIL_PASSWORD')
), a.env
file withpython-dotenv
, or a dedicated secrets management service. - Error Handling: Implement robust
try-except
blocks to catch potentialsmtplib.SMTPException
errors, such as authentication failures or connection issues. - Rate Limiting: Be mindful of your SMTP server's sending limits to avoid being flagged as spam or temporarily blocked.
- Sender Verification: Ensure your
SENDER_EMAIL
is a legitimate and verified email address to improve deliverability and avoid spam filters. - MIME Types: When attaching files, use the correct MIME types (
application/pdf
,image/jpeg
,text/plain
, etc.) to help email clients render them correctly. Themimetypes
module can assist with this.
1. Set up your email account
Ensure your sending email account allows programmatic access. For Gmail, this might involve generating an App Password if 2-Factor Authentication is enabled, or enabling 'Less secure app access' (though App Passwords are more secure).
2. Install necessary libraries (if any)
For basic email sending, smtplib
and email
are built-in. If you need more advanced features or a higher-level API, consider libraries like yagmail
(pip install yagmail
).
3. Configure SMTP details
Identify your email provider's SMTP server address (e.g., smtp.gmail.com
, smtp.office365.com
) and the correct port (usually 587 for TLS or 465 for SSL).
4. Construct your email message
Decide if you need a plain text, HTML, or multipart message with attachments. Use the email.mime
classes for complex messages.
5. Establish connection and send
Use smtplib.SMTP()
or smtplib.SMTP_SSL()
, call starttls()
if needed, log in with your credentials, and then use sendmail()
or send_message()
.