Of course! Sending email with Python is a common task, and the primary library for it is smtplib. This library allows you to connect to an SMTP (Simple Mail Transfer Protocol) server and send messages.
Here’s a complete guide, starting with the simplest example and building up to more complex scenarios with attachments and HTML.
Prerequisites: An SMTP Server
You need access to an SMTP server to send your email. This is typically provided by your email provider (like Gmail, Outlook, etc.).
Important Note for Gmail Users: Google now requires "Less secure app access" to be turned OFF. Instead, you must use an "App Password".
- Enable 2-Factor Authentication (2FA) on your Google account.
- Go to your Google Account settings -> Security.
- Under "Signing in to Google," click on App Passwords.
- Generate a new password. Select "Mail" for the app and "Other (Custom name)" for the device, and name it something like "Python Script".
- Google will give you a 16-character password (e.g.,
abcd efgh ijkl mnop). Copy this password. You will use it in your Python script instead of your regular Google password.
The Basic Example: Sending a Plain Text Email
This is the simplest way to send an email. We'll use smtplib to connect to the server and email.mime.text to create the email message.
import smtplib
from email.mime.text import MIMEText
# --- Configuration ---
# Replace with your email provider's SMTP server details
SMTP_SERVER = "smtp.gmail.com" # For Gmail
SMTP_PORT = 587 # For TLS (common for Gmail)
SMTP_USE_TLS = True # Use TLS encryption
# Your email credentials (use an App Password for Gmail)
# It's best practice to use environment variables for these
sender_email = "your_email@gmail.com"
sender_password = "your_16_character_app_password" # Or your regular password if not using Gmail
# The recipient's email
receiver_email = "recipient_email@example.com"
# --- Email Content ---
subject = "Hello from Python!"
body = """
This is a test email sent from a Python script using smtplib.
It's a plain text email.
"""
# --- Create the Email Message ---
# The MIMEText object creates the email body
msg = MIMEText(body, 'plain') # 'plain' for plain text, 'html' for HTML
msg['Subject'] = subject
msg['From'] = sender_email
msg['To'] = receiver_email
# --- Send the Email ---
try:
# Create a secure session with the server
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
if SMTP_USE_TLS:
server.starttls() # Upgrade the connection to a secure one
# Login to your email account
server.login(sender_email, sender_password)
# Send the email
server.sendmail(sender_email, receiver_email, msg.as_string())
print("Email sent successfully!")
except Exception as e:
print(f"Failed to send email. Error: {e}")
Breakdown of the Code:
import smtplib: The core library for sending emails.from email.mime.text import MIMEText: Used to create the email body.MIME(Multipurpose Internet Mail Extensions) is the standard for formatting non-ASCII text in email.- Configuration: You must fill in your SMTP server details, port, and credentials.
MIMEText(body, 'plain'): Creates the email content. The first argument is the text, and the second specifies the content type ('plain'or'html').msg['Subject'],msg['From'],msg['To']: These are the email headers. They are crucial for routing and displaying the email correctly.with smtplib.SMTP(...) as server:: This is a context manager. It automatically handles connecting to the server and closing the connection, even if errors occur.server.starttls(): Encrypts the connection for security. This is required for most modern servers.server.login(): Authenticates you with the server.server.sendmail(): The actual function that sends the email. It takes the sender, a list of recipients, and the full message as a string.
Sending an HTML Email
Sending HTML emails is just as easy. You simply change the content type to 'html'.
import smtplib
from email.mime.text import MIMEText
# --- Configuration (same as before) ---
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
SMTP_USE_TLS = True
sender_email = "your_email@gmail.com"
sender_password = "your_16_character_app_password"
receiver_email = "recipient_email@example.com"
# --- HTML Email Content ---
subject = "A More Stylish Email from Python"
html_body = """
<html>
<body>
<h1>This is an HTML Email!</h1>
<p>You can make text <b>bold</b>, <i>italic</i>, and even add links:</p>
<a href="https://www.python.org">Visit Python's website</a>
<p>Best regards,<br>The Python Script</p>
</body>
</html>
"""
# --- Create the Email Message ---
# The only change is 'html' instead of 'plain'
msg = MIMEText(html_body, 'html')
msg['Subject'] = subject
msg['From'] = sender_email
msg['To'] = receiver_email
# --- Send the Email (same as before) ---
try:
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls()
server.login(sender_email, sender_password)
server.sendmail(sender_email, receiver_email, msg.as_string())
print("HTML Email sent successfully!")
except Exception as e:
print(f"Failed to send email. Error: {e}")
Sending an Email with an Attachment
To send attachments, you need to use email.mime.multipart.MIMEMultipart. This allows you to combine different parts (the body text and the file attachment) into a single email.
import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
# --- Configuration (same as before) ---
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
SMTP_USE_TLS = True
sender_email = "your_email@gmail.com"
sender_password = "your_16_character_app_password"
receiver_email = "recipient_email@example.com"
# --- Create the Multipart Message ---
msg = MIMEMultipart()
msg['Subject'] = "Email with an Attachment from Python"
msg['From'] = sender_email
msg['To'] = receiver_email
# --- Add Body to Email ---
body = "Please find the attached document."
msg.attach(MIMEText(body, 'plain'))
# --- Add Attachment ---
# Path to the file you want to attach
filename = "my_document.pdf" # Make sure this file exists in the same directory
try:
# Open the file in binary mode
with open(filename, "rb") as attachment:
# Create a MIMEBase object and set the maintype and subtype
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
# Encode the file in Base64 to make it email-safe
encoders.encode_base64(part)
# Add header to the attachment
part.add_header(
"Content-Disposition",
f"attachment; filename= {filename}",
)
# Attach the file to the message
msg.attach(part)
except FileNotFoundError:
print(f"Error: The file '{filename}' was not found.")
exit()
# --- Send the Email ---
try:
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
server.starttls()
server.login(sender_email, sender_password)
server.sendmail(sender_email, receiver_email, msg.as_string())
print("Email with attachment sent successfully!")
except Exception as e:
print(f"Failed to send email. Error: {e}")
Security Best Practice: Using Environment Variables
Hardcoding passwords in your scripts is a security risk. A much better approach is to use environment variables.
-
Install the
python-dotenvlibrary:pip install python-dotenv
-
Create a
.envfile in the same directory as your script:# .env file EMAIL_ADDRESS="your_email@gmail.com" EMAIL_PASSWORD="your_16_character_app_password" -
Modify your Python script to load these variables:
import os from dotenv import load_dotenv # Load environment variables from .env file load_dotenv() # Now you can access the variables securely sender_email = os.getenv("EMAIL_ADDRESS") sender_password = os.getenv("EMAIL_PASSWORD") # ... rest of your script ...This way, your sensitive credentials are kept separate from your code.
