How To Send Email In Python

How To Send Email In Python

It provides all the steps required to send or trigger emails in Python.

December 27, 2019

Email is one of the most important factors in having effective business communication. One can also use emails to host marketing campaigns to reach the appropriate audience. Apart from these uses, there are several other benefits of using email as the communication channel including keeping a record of all the messages.

In this tutorial, we will discuss the parameters involved in sending an email and the possible ways to send an email in Python 3 i.e. Python 3.8. The steps should be the same for other versions of Python. We will use Python’s built-in smtplib library to send emails.

Basics of Email

This section explains the basics of sending an email by explaining the parameters involved in an email. We can include the below-listed parameters while sending an email.

From - The mandatory field to specify the sender email address. It must be a valid email address to send an email.

Reply-To - It's an optional parameter to accept email replies. If not specified, the From email address will be used to send replies.

To - It's the most important and mandatory parameter to send an email. We can include either single or multiple receiver email addresses to send an email either to single or multiple receivers.

// To - Format - RFC 2822 - Single Receipient

Receipient Name <Receipient Email>
// OR
Receipient Email

// To - Format - RFC 2822 - Multiple Receipient

Receipient 1 Name <Receipient 1 Email>, Receipient 2 Name <Receipient 2 Email>
, Receipient 3 Name <Receipient 3 Email>
// OR
Receipient 1 Email, Receipient 2 Email
// OR
Receipient 1 Name <Receipient 1 Email>, Receipient 2 Email

Cc - Carbon Copy - Similar to To, we can specify either single or multiple recipients to receive a copy of the email to keep them notified about the communication.

Bcc - Blank Carbon Copy - We can also involve recipients who will receive a copy of the email without mentioning them to the recipients involved in both To and CC list. The recipients involved in both To and CC list will never know that the same email is also sent to the recipients mentioned in the BCC parameter.

Subject - Though it's not a mandatory field, one must include the subject to hint the recipients about the content involved in the email. A short and the descriptive subject can tell the recipient about the communication context.

The subject can be of multiple lines separated with a CRLF (\r\n). Each line must not have more than 70 characters.

Message - The actual message to be sent to the recipients mentioned in To, CC, and BCC parameters. Though we can send an email without a message, it's not a preferred way to send an email.

Standard Services Configuration

You can also use the standard email services including Gmail, Yahoo, and Outlook to send an email. Below listed are the configurations required to send emails using your Gmail, Yahoo, or Outlook as mentioned below.

; Gmail configurations
Host - smtp.gmail.com
; You can also specify port 587
Port - 465
Username - <Gmail username>
Password - <Gmail password>

; Yahoo configurations
Host - smtp.mail.yahoo.com
Port - 465
Username - <Yahoo username>
Password - <Yahoo password>

; Outlook configurations
Host - smtp.live.com
Port - 465
Username - <Outlook username>
Password - <Outlook password>

You must take special care while sending emails using free accounts since there are limitations in sending emails using these services. These services might block your account in case you exceed the specified limit, hence avoid using personal email accounts.

Gmail limits to a maximum of 100 recipients at a time with a limit of 500 messages per day. Similarly, Yahoo also applies a limit of 100 recipients and 500 messages per day.

You might also need to keep the 2-step verification off if you’re using it.

Trigger Email

This section provides the basic code required to trigger or send email in Python. Python provides the built-in smtplib module to send emails using the Simple Mail Transfer Protocol (SMTP) protocol. It also provides a debugging SMTP server for debugging purposes. The local SMTP server does not send any email and simply prints the output on the console. I have used Gmail as the standard email service for demonstration purposes.

Debugging SMTP Server

To start sending emails using the SMTP server provided by smtplib, use the command as shown below to start the SMTP server on the localhost using port 125.

# Start the Local SMTP Server
python -m smtpd -c DebuggingServer -n localhost:1025

Now write the program to send an email using the local SMTP server as shown below.

# Imports SMTP Library
import smtplib

# Sender and Receiver
sender = 'sender@example.com'
receivers = ['receiver@example.com']

# Message
message = 'Welcome Guest!!'

try:
smtpObj = smtplib.SMTP('localhost', 1025)

smtpObj.sendmail(sender, receivers, message)

print("Email sent")

except smtplib.SMTPException:

print("Error sending email")

finally:

smtpObj.quit()

Make sure that the SMTP server is running on the localhost at port 1025. It will show the output of the email as shown below.

---------- MESSAGE FOLLOWS ----------
b'Welcome Guest!!'
------------ END MESSAGE ------------

We can see that the above output only shows the message body. Now update the message to include the other parameters as shown below.

# Imports SMTP Library
import smtplib

# Sender and Receiver
sender = 'sender@example.com'
receivers = ['receiver@example.com']

# Message
message = """
From: Sender <sender@example.com>
To: Receiver <receiver@example.com>
Subject: Welcome

Welcome Guest!!'
"""

try:
smtpObj = smtplib.SMTP('localhost', 1025)

smtpObj.sendmail(sender, receivers, message)

print("Email sent")

except smtplib.SMTPException:

print("Error sending email")

finally:

smtpObj.quit()

The output of the updated message with From, To, and Subject is shown below.

---------- MESSAGE FOLLOWS ----------
b'X-Peer: ::1'
b''
b'From: Sender <sender@example.com>'
b'To: Receiver <receiver@example.com>'
b'Subject: Welcome'
b''
b"Welcome Guest!!'"
------------ END MESSAGE ------------

We can format our message to send HTML email by specifying the MIME version and content type as shown below.

message = """
From: Sender <sender@example.com>
To: Receiver <receiver@example.com>
MIME-Version: 1.0
Content-type: text/html
Subject: Welcome

Welcome Guest!!

<b>This is HTML message in bold.</b>
"""

We can also use the email modules to generate the message as shown below.

# Import SMTP Library
import smtplib

# Import email modules
from email.message import EmailMessage

# Sender and Receiver
sender = 'sender@example.com'
receivers = ['receiver@example.com']

# Message
message = EmailMessage()

message['Subject'] = 'Welcome'
message['From'] = sender
message['To'] = receivers

message.set_content('Welcome Guest !!')

# Send email
try:

smtpObj = smtplib.SMTP('localhost', 1025)

smtpObj.send_message(message)

print("Email sent")

except smtplib.SMTPException:

print("Error sending email")

finally:

smtpObj.quit()

If the SMTP server is listening on port 1025, the above-mentioned code will trigger an email locally on executing it. The SMTP server will print the output as shown below.

---------- MESSAGE FOLLOWS ----------
b'Subject: Welcome'
b'From: sender@example.com'
b'To: receiver@example.com'
b'Content-Type: text/plain; charset="utf-8"'
b'Content-Transfer-Encoding: 7bit'
b'MIME-Version: 1.0'
b'X-Peer: ::1'
b''
b'Welcome Guest !!'
------------ END MESSAGE ------------

I have executed it using the PyCharm IDE, though it can be done using a simple text editor and console. The output is as shown in Fig 1.

Python Email Output

Fig 1

This is how we can send an email using the local SMTP server without any authentication.

We can also generate the email message using the file as shown below.

# Message
message = EmailMessage()

message['Subject'] = 'Welcome'
message['From'] = sender
message['To'] = receivers

# Message from File
with open('hello.txt') as fp:
message.set_content(fp.read())

Gmail

In the previous step, I have triggered emails using the local SMTP server listening on port 1025. The standard email ports of an email server include 25, 465, and 587. In this section, we will use the Gmail service listening on port 587 to send emails securely.

The code used to send emails using Gmail is shown below.

# Import SMTP Library
import smtplib
import ssl

# Import email modules
from email.message import EmailMessage

# SMTP Server
server = 'tls://smtp.gmail.com'
port = 587
user = 'yourname@gmail.com'
password = 'password'

# Sender and Receiver
sender = 'yourname@gmail.com'
receivers = ['receiver@gmail.com']

# Message
message = EmailMessage()

message['From'] = sender
message['To'] = receivers
message['MIME-Version'] = '1.0'
message['Content-type']: 'text/html'
message['Subject'] = 'Welcome'

message.set_content('Welcome Guest !!')

# Create SSL context
context = ssl.create_default_context()

# Send email
try:

smtpObj = smtplib.SMTP(server, port)

smtpObj.ehlo()
smtpObj.starttls(context=context)
smtpObj.ehlo()
smtpObj.login(user, password)

smtpObj.send_message(message)

print("Email sent")

except smtplib.SMTPException as exc:

print("Error sending email")
print(exc)

finally:
smtpObj.quit()

Similarly, we can send emails using other email services.

Send Attachment

We can also attache files with the email message to send images, documents as attachment. The sample code to send an email with attachment is shown below.

# Import SMTP Library
import smtplib
import ssl
import base64

# Import email modules
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# SMTP Server
server = 'tls://smtp.gmail.com'
port = 587
user = 'yourname@gmail.com'
password = 'password'

# Sender and Receiver
sender = 'yourname@gmail.com'
receivers = ['receiver@gmail.com']

# Attachment
filename = 'hello.txt'

# Read and encode into base64 format
with open(filename, 'rb') as attachment:
encodedPart = MIMEBase('application', 'octet-stream')
encodedPart.set_payload(attachment.read())

encoders.encode_base64(encodedPart)

encodedPart.add_header(
"Content-Disposition",
f"attachment; filename= {filename}",
)

# Message
message = MIMEMultipart()

message['From'] = sender
message['To'] = receiver
message['MIME-Version'] = '1.0'
message['Content-type']: 'text/html'
message['Subject'] = 'Welcome'

message.attach(MIMEText('Welcome Guest !!', "plain"))
message.attach(encodedPart)

# Create SSL context
context = ssl.create_default_context()

# Send email
try:

smtpObj = smtplib.SMTP(server, port)

smtpObj.ehlo()
smtpObj.starttls(context=context)
smtpObj.ehlo()
smtpObj.login(user, password)

smtpObj.send_message(message)

print("Email sent")

except smtplib.SMTPException as exc:

print("Error sending email")
print(exc)

finally:
smtpObj.quit()

Summary

This tutorial provided the basics of the parameters involved in emails and the code to send an email with and without attachment in Python to the local SMTP server and standard service providers.

Write your comment to join the discussion. You can also follow the other tutorials on Python including How To Install VSCode For Python On Windows, How To Install Eclipse for Python On Windows, How To Install VSCode For Python On Ubuntu, and How To Install PyCharm For Python On Windows.

All the examples discussed in this tutorial are also available on GitHub.

Write a Comment
Click the captcha image to get new code.
Discussion Forum by DISQUS