Hey there!
Sending emails through code is an incredibly useful skill for any Python programmer. Whether you‘re building an application, automating workflows, or just want to level up your scripting abilities – being able to programmatically send emails can take your projects to the next level.
In this comprehensive guide, I‘ll walk you step-by-step through how to send emails through Gmail using Python.
By the end, you‘ll have the knowledge and code to start sending automated emails from your own Gmail account. Let‘s get started!
Why Send Emails through Python?
Here are some of the top reasons you may want to send emails from Python:
-
Automate notifications and alerts – Send automatic emails when certain events occur, like application errors or server issues.
-
Build email newsletters – Design and send customized bulk email campaigns.
-
Password reset emails – Many web apps use email for password recovery.
-
Email reports and summaries – Schedule scripts to email data insights or system statuses.
-
Lead generation and contact forms – Capture leads via email by automating contact form submissions.
-
Transactional emails – Send receipts, invoices, order confirmations automatically after purchases.
-
Marketing campaigns – Send timed promotional emails and special offers.
-
Personalized messaging – Tailor custom email content for each recipient.
The applications are endless! No matter your specific needs, Python makes it simple to leverage the power of email.
Overview of the Process
At a high level, here are the main steps we‘ll cover to send emails with Python:
-
Set up a Gmail account – This will be used for sending your emails.
-
Import smtplib – This built-in module lets us manage SMTP connections.
-
Create an SMTP connection – Connect to Google‘s servers with SMTP_SSL.
-
Log in to the SMTP server – Authenticate with your Gmail username and password.
-
Construct the email content – Set up the recipients, subject, and body.
-
Send the email – Pass the message to smtplib to send it.
-
Handle errors – Catch exceptions in case of issues sending.
-
Add attachments – Optional ability to include files.
-
Customize email templates – Format your emails with HTML/custom code.
-
Send bulk emails – Learn how to easily send mass emails.
We have a lot to cover, so let‘s dive in!
Prerequisites
Before we start coding, you‘ll need:
-
A Gmail account set up to allow less secure apps. Don‘t worry – I‘ll show you how to do this in the next section.
-
Python installed on your machine. Any version 3.x should work.
-
Basic knowledge of Python. Familiarity with variables, functions, if statements, etc.
As long as you have those basics covered, you‘ll be able to follow along. Let‘s get your Gmail account ready to go!
Set Up Your Gmail Account
We‘ll be using Gmail‘s SMTP servers to send our emails behind the scenes.
By default, Google blocks app access to your Gmail account for security reasons. So we need to configure your account settings to allow our Python script to log in and send emails.
Here are the steps:
-
Go to your Gmail account settings page.
-
Scroll down to the "Less secure app access" section.
-
Turn ON the setting that says "Allow less secure apps".

That‘s it! This white-lists our Python script to connect as an authorized app.
Pro Tip: For added security, I recommend creating a new dedicated Gmail account solely for sending emails programmatically. That way your personal inbox stays separated.
Okay, with access enabled we can jump into the code!
Import the smtplib Module
Python makes sending emails easy with the built-in smtplib module. This contains classes for managing connections to SMTP servers as well as handling the sending and formatting of email messages.
To get started, we first need to import smtplib:
import smtplib
This gives us access to the tools and objects we need like SMTP, SMTP_SSL, etc.
Create an SMTP Connection
The next step is to create an SMTP connection object to interact with Google‘s servers.
For Gmail, we want to use SMTP_SSL which will establish an encrypted SSL/TLS connection:
smtp_server = smtplib.SMTP_SSL(‘smtp.gmail.com‘, 465)
We pass the SMTP domain name and port number for Gmail:
- Domain: smtp.gmail.com
- Port: 465
There are also options for non-encrypted connections or using alternative ports. But this SSL approach is recommended as it provides transport security for our emails.
Log in to the SMTP Server
Now that our connection is established, we need to log in with our Gmail credentials so we can send emails through our account:
smtp_server.login(‘[email protected]‘, ‘your_password‘)
Make sure to use your actual Gmail address and account password here.
Upon a successful login, we will have access to send emails as our Gmail user.
Construct the Email Message
At this point, our SMTP connection is in place and authenticated. Now we can put together the content of the email we want to send.
This involves crafting the email headers like sender, recipients, subject line as well as the body content.
Let‘s look at a template for a basic email message:
message = """
From: Automated Email <[email protected]>
To: Recipient <[email protected]>
Subject: Test Email from Python
This is the body of the email.
"""
Breaking this down:
From– Your logged in Gmail address. You can optionally add a name too.To– The recipient‘s email address.Subject– The subject line for the email.Body– The content of the email as a plain text string.
Later we‘ll see how to customize this further with HTML formatting and templates.
Send the Email
Now comes the fun part – sending the actual email!
To send our message, we simply pass it to smtplib‘s send_message method:
smtp_server.send_message(message)
And the email will instantly be queued up and sent through Gmail‘s SMTP servers to the recipient!
It happens incredibly fast so don‘t blink 😉
Handle Errors and Exceptions
Of course, there are always potential errors and exceptions that may arise when sending emails over the network:
SMTPAuthenticationError– Incorrect login credentials provided.SMTPRecipientsRefused– The recipient address is invalid.SMTPSenderRefused– Your sender address is not allowed.SMTPDataError– Issue with formatting or encoding of the message.
To handle these gracefully in our code, we can wrap the send_message() call in a try/except block:
try:
smtp_server.send_message(message)
except SMTPAuthenticationError:
print(‘Invalid username/password‘)
except SMTPRecipientsRefused:
print(‘Invalid recipient email‘)
except SMTPSenderRefused:
print(‘Invalid sender email‘)
except SMTPDataError:
print(‘Email data was invalid‘)
This will catch any exceptions and print a friendly error message instead of our program crashing.
Proper error handling is essential for robust, production-ready applications.
Send Emails with Attachments
What about sending emails with file attachments like documents, images, PDFs, etc?
Python‘s email module provides some really handy tools to make attaching files a breeze.
Here‘s an example:
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg[‘Subject‘] = ‘Email with attachment‘
msg[‘From‘] = ‘[email protected]‘
msg.set_content(‘This is the body text‘)
with open(‘file.pdf‘, ‘rb‘) as f:
file_attachment = f.read()
msg.add_attachment(file_attachment, maintype=‘application‘, subtype=‘octet-stream‘, filename=‘file.pdf‘)
smtp_server.send_message(msg)
The key steps are:
-
Construct an
EmailMessageobject for our email. -
Read the binary contents of the file attachment using
rb. -
Add the file contents using
msg.add_attachment(). -
Send the message with the attachment.
The attachment will be properly encoded and included as a multipart message. Easy!
You can attach any file type like PDFs, JPGs, DOCs – anything!
Send Bulk Emails to Multiple Recipients
What about sending one email to multiple recipients at once?
We can easily modify our script to support bulk sending:
recipient_list = [‘[email protected]‘, ‘[email protected]‘]
msg[‘To‘] = ‘, ‘.join(recipient_list)
smtp_server.send_message(msg)
Here we define a list of recipient emails, then join them into a comma separated string. This sets all those emails to receive the message.
One thing to note is that each recipient will see who else was sent the email. For hidden/blind copies, check out the Bcc option.
According to recent stats, Gmail allows you to send emails to up to 2000 recipients per day from a single account.
Customize the Email Content
Up until now, we‘ve only sent simple plain text email content. But you can format the body in many more robust ways.
Send emails with HTML
To add HTML formatting, you first need to import MIMEText from the email.mime module:
from email.mime.text import MIMEText
We can then create an HTML MIMEText object:
html_body = """
<p>This is HTML content</p>
"""
html_msg = MIMEText(html_body, ‘html‘)
msg.attach(html_msg)
By specifying the subtype as ‘html‘, it will render any HTML tags and styling.
Use email templates
Hard-coding HTML in your Python script can get messy. A better approach is to use templates.
For example, we can create an external email_template.html file:
<html>
<body>
<p>This is the email body</p>
</body>
</html>
And then render it with Python‘s Jinja template engine:
import jinja2
template_loader = jinja2.FileSystemLoader(searchpath="./")
template_env = jinja2.Environment(loader=template_loader)
email_template = template_env.get_template("email_template.html")
html_content = email_template.render(name=‘John‘)
This allows much cleaner separation of HTML design and Python code.
Insert images
To embed images directly into your HTML emails, you can leverage MIMEImage:
from email.mime.image import MIMEImage
img_bytes = open(‘image.png‘, ‘rb‘).read()
img = MIMEImage(img_bytes)
img.add_header(‘Content-ID‘, ‘<myimage>‘)
img.add_header(‘Content-Disposition‘, ‘inline‘, filename=‘image.png‘)
msg.attach(img)
We read the raw image bytes, create a MIMEImage, and attach it to the main message. The Content-ID allows referencing and embedding it from HTML via <img src="cid:myimage">.
As you can see, the possibilities are endless when it comes to formatting rich email content!
Putting It All Together
Let‘s see all this in action in a full email example:
import smtplib
import jinja2
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
template_loader = jinja2.FileSystemLoader(searchpath="./")
template_env = jinja2.Environment(loader=template_loader)
email_template = template_env.get_template("email_template.html")
msg = MIMEMultipart()
msg[‘Subject‘] = ‘Custom Email‘
msg[‘From‘] = ‘[email protected]‘
msg[‘To‘] = ‘[email protected]‘
html_content = email_template.render(name=‘John‘)
msg.attach(MIMEText(html_content, ‘html‘))
img_bytes = open(‘image.png‘, ‘rb‘).read()
img = MIMEImage(img_bytes)
img.add_header(‘Content-ID‘, ‘<myimage>‘)
msg.attach(img)
smtp_server = smtplib.SMTP_SSL(‘smtp.gmail.com‘, 465)
smtp_server.login(‘[email protected]‘, ‘your_password‘)
smtp_server.send_message(msg)
smtp_server.quit()
This combines everything we‘ve covered like MIME types, HTML, images, and templates into a customized email message. Flex those coding skills!
Summary of Key Points
We‘ve covered a ton of material here! Let‘s recap some of the key points:
-
Use Python‘s
smtplibmodule to manage SMTP connections and send emails. -
Create an
SMTP_SSLconnection on port 465 for encrypted Gmail access. -
Enable "less secure app access" on your Gmail account.
-
Log in to Google‘s servers with your Gmail username and password.
-
Construct the email message with headers like recipient, subject, body.
-
Send the message with
smtp_server.send_message(). -
Handle exceptions and errors that may occur.
-
Use
MIMEtypes to attach files and embed images. -
Leverage templates like Jinja for cleaner HTML formatting.
-
Specify
msg[‘To‘]as a list to send bulk emails. -
Customize and tweak emails via headers, attachments, and HTML.
I know that was a lot to digest, but learning by example is always the best approach in my experience. The key is being able to reference code that actually works!
Example Use Cases and Next Steps
Now that you have the foundation, let‘s chat through some real-world use cases where sending emails with Python comes in handy:
-
Transactional receipts – Send order confirmations, tracking info, digital receipts when purchases occur.
-
Password reset – Implement forgotten password flow by emailing magic links or temp codes.
-
Email alerts – Get notified for certain app events like new registrations or server issues.
-
Newsletters – Schedule and send email digests, promotions, announcements to subscribers.
-
Lead generation – Automate contacting potential leads from sources like contact forms.
-
Scheduled reports – Email regular data exports, metrics, dashboards on a cadence.
The possibilities are truly endless!
Some next steps I recommend:
-
Try connecting the email script to a real world app like order tracking or password reset in a web project.
-
Research using an email service provider like MailGun versus your own Gmail.
-
Look into email deliverability factors like SPF, DKIM, and best practices.
-
Experiment with email templates using a CSS framework like Tailwind.
-
Learn how to capture and store sent email logs and metrics.
Let me know if you have any other questions! I‘m always happy to help fellow coders along their Python journey.
I appreciate you taking the time to read this guide. Now go send some awesome automated emails!
Happy programming,
[Your name here]