How To Send Email In Python

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

). 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.

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.