Sending emails programmatically is a common task in many applications, such as sending notifications, alerts, or newsletters. Python provides the smtplib
module to facilitate sending emails using the Simple Mail Transfer Protocol (SMTP). In this guide, we’ll walk you through the steps to send an email using Python’s smtplib
and the email
module.
1. Prerequisites
- Python installed on your system.
- An SMTP server to send emails. Common options include Gmail’s SMTP server, Outlook’s SMTP server, or any other email provider’s SMTP server.
- Credentials for the SMTP server (email address and password).
2. Importing Necessary Modules
You’ll need to import the following modules:
smtplib
: To handle the SMTP protocol.email.mime
modules: To construct the email content.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
3. Setting Up the SMTP Server
Different email providers have different SMTP server addresses and port numbers. Below are the SMTP settings for some popular email providers:
Email Provider | SMTP Server | Port | Security |
---|---|---|---|
Gmail | smtp.gmail.com | 587 (STARTTLS) or 465 (SSL) | STARTTLS or SSL |
Outlook | smtp.office365.com | 587 | STARTTLS |
Yahoo | smtp.mail.yahoo.com | 587 | STARTTLS |
SMTP.com | smtp.smtp.com | 587 or 465 | STARTTLS or SSL |
4. Creating the Email Message
Use the MIMEMultipart
class to create the email message. This allows you to add multiple parts to your email, such as plain text and HTML content.
# Email credentials
sender_email = "your_email@example.com"
receiver_email = "recipient@example.com"
password = "your_password"
# Create a multipart message
message = MIMEMultipart("alternative")
message["Subject"] = "Subject of the Email"
message["From"] = sender_email
message["To"] = receiver_email
# Create the plain-text and HTML version of your message
text = """\
Hi there,
This is a test email sent from Python.
Best regards,
Your Name
"""
html = """\
Hi there,
This is a test email sent from Python.
Best regards,
Your Name
"""
# Attach parts into message container
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)
5. Sending the Email
Use the smtplib
module to connect to the SMTP server and send the email. It’s important to handle the connection securely using SSL or STARTTLS.
5.1 Using STARTTLS
STARTTLS upgrades the connection to a secure encrypted SSL/TLS connection.
try:
# Connect to the SMTP server
smtp_server = "smtp.gmail.com"
port = 587 # For STARTTLS
server = smtplib.SMTP(smtp_server, port)
server.ehlo() # Can be omitted
server.starttls() # Secure the connection
server.ehlo() # Can be omitted
# Login to the server
server.login(sender_email, password)
# Send the email
server.sendmail(sender_email, receiver_email, message.as_string())
print("Email sent successfully!")
except Exception as e:
print("Error sending email:", e)
finally:
server.quit()
5.2 Using SSL
SSL creates a secure connection from the start.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
# Email credentials
sender_email = "your_email@example.com"
receiver_email = "recipient@example.com"
password = "your_password"
# Create a multipart message
message = MIMEMultipart("alternative")
message["Subject"] = "Subject of the Email"
message["From"] = sender_email
message["To"] = receiver_email
# Create the plain-text and HTML version of your message
text = """\
Hi there,
This is a test email sent from Python.
Best regards,
Your Name
"""
html = """\
Hi there,
This is a test email sent from Python.
Best regards,
Your Name
"""
# Attach parts into message container
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)
try:
# Connect to the SMTP server using SSL
smtp_server = "smtp.gmail.com"
port = 465 # For SSL
with smtplib.SMTP_SSL(smtp_server, port) as server:
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message.as_string())
print("Email sent successfully!")
except Exception as e:
print("Error sending email:", e)
6. Full Example Code
Below is a complete example that sends an email using SMTP with STARTTLS. Replace the placeholder values with your actual email credentials and recipient’s email address.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def send_email(sender_email, receiver_email, password, subject, body_text, body_html=None):
# Create a multipart message
message = MIMEMultipart("alternative")
message["Subject"] = subject
message["From"] = sender_email
message["To"] = receiver_email
# Attach the plain text part
part1 = MIMEText(body_text, "plain")
message.attach(part1)
# Attach the HTML part if provided
if body_html:
part2 = MIMEText(body_html, "html")
message.attach(part2)
try:
# Connect to the SMTP server
smtp_server = "smtp.gmail.com"
port = 587 # For STARTTLS
server = smtplib.SMTP(smtp_server, port)
server.ehlo()
server.starttls()
server.ehlo()
# Login to the server
server.login(sender_email, password)
# Send the email
server.sendmail(sender_email, receiver_email, message.as_string())
print("Email sent successfully!")
except Exception as e:
print("Error sending email:", e)
finally:
server.quit()
# Usage
sender = "your_email@gmail.com"
recipient = "recipient@example.com"
password = "your_password" # Consider using environment variables or secure storage
subject = "Test Email from Python"
text = "Hi there,\nThis is a test email sent from Python."
html = """\
Hi there,
This is a test email sent from Python.
Best regards,
Your Name
"""
send_email(sender, recipient, password, subject, text, html)
7. Sending Emails with Attachments
To send emails with attachments, you can use the email.mime
modules such as MIMEBase
and encoders
.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
def send_email_with_attachment(sender_email, receiver_email, password, subject, body, filename):
# Create a multipart message
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject
# Attach the body with the msg instance
message.attach(MIMEText(body, "plain"))
# Open the file to be sent
with open(filename, "rb") as attachment:
# Instance of MIMEBase and named as part
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
# Encode file in ASCII characters to send by email
encoders.encode_base64(part)
# Add header as key/value pair to attachment part
part.add_header(
"Content-Disposition",
f"attachment; filename= {filename}",
)
# Attach the attachment to the MIMEMultipart object
message.attach(part)
try:
# Connect to the SMTP server
smtp_server = "smtp.gmail.com"
port = 587 # For STARTTLS
server = smtplib.SMTP(smtp_server, port)
server.ehlo()
server.starttls()
server.ehlo()
# Login to the server
server.login(sender_email, password)
# Convert the message to a string and send it
server.sendmail(sender_email, receiver_email, message.as_string())
print("Email with attachment sent successfully!")
except Exception as e:
print("Error sending email:", e)
finally:
server.quit()
# Usage
sender = "your_email@gmail.com"
recipient = "recipient@example.com"
password = "your_password"
subject = "Test Email with Attachment"
body = "Hi there,\nThis email contains an attachment."
filename = "example.pdf" # Replace with your file path
send_email_with_attachment(sender, recipient, password, subject, body, filename)
8. Best Practices and Security
- Do Not Hardcode Credentials: Avoid hardcoding your email password in the script. Instead, use environment variables or a configuration file that’s not checked into version control.
- Use App Passwords: If your email provider supports it (like Gmail), use app-specific passwords instead of your main account password.
- Handle Exceptions: Always handle potential exceptions to prevent your application from crashing and to provide meaningful error messages.
- Limit Access: Ensure that your SMTP credentials have the least privilege necessary. For example, create a separate account for sending automated emails.
- Secure Connections: Always use secure connections (SSL/TLS) when connecting to the SMTP server to protect your credentials and email content.
9. Using Environment Variables for Credentials
Storing sensitive information like email passwords in environment variables enhances security.
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def send_secure_email():
# Retrieve credentials from environment variables
sender_email = os.getenv("SENDER_EMAIL")
receiver_email = os.getenv("RECEIVER_EMAIL")
password = os.getenv("EMAIL_PASSWORD")
subject = "Secure Email from Python"
body = "This email is sent securely using environment variables."
# Create the email message
message = MIMEMultipart("alternative")
message["Subject"] = subject
message["From"] = sender_email
message["To"] = receiver_email
# Attach the plain text
part1 = MIMEText(body, "plain")
message.attach(part1)
try:
smtp_server = "smtp.gmail.com"
port = 587
server = smtplib.SMTP(smtp_server, port)
server.ehlo()
server.starttls()
server.ehlo()
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message.as_string())
print("Secure email sent successfully!")
except Exception as e:
print("Error sending secure email:", e)
finally:
server.quit()
# Ensure to set the environment variables before running the script
# Example (Unix):
# export SENDER_EMAIL="your_email@gmail.com"
# export RECEIVER_EMAIL="recipient@example.com"
# export EMAIL_PASSWORD="your_password"
send_secure_email()
10. Conclusion
Sending emails using Python’s smtplib
and email
modules is a straightforward process that can be integrated into various applications for automated communication. By following best practices and ensuring the security of your credentials, you can efficiently manage email sending tasks within your Python projects.