Updated On : Mar-01,2021 Tags smtp, send-mails
smtplib - Simple Guide to Sending Mails using Python

smtplib - Simple Guide to Sending Mails using Python

Simple Mail Transfer Protocol (SMTP) is a standard internet protocol that is used to transfer emails. SMTP was originally standardized in 1982 under RFC 821. It was later updated to Extended SMTP through RFC 5321 which is currently in use by the majority of mail service providers. The SMTP protocol is used only for the transfer of mails. If you want to read mails from the server or modify the mailbox then there is a different protocol named Internet Message Access Protocol (IMAP). Python provides a library named smtplib which can be used to connect to the mail server to send mail. It provides a bunch of methods that can let us send SMTP commands to the mail server and send emails.

As a part of this tutorial, we'll explain with simple examples how we can use smtplib module to communicate with the mail server and transfer emails using simple and easy-to-understand examples. We'll be connecting to Gmail and yahoo mail servers to transfer emails during our examples. Gmail and yahoo mail provides access to SMTP over SSL through port number 465 or 587. We'll be using SMTP over SSL for the majority of our examples because Gmail and yahoo mail does not let us connect to SMTP without SSL. Please find below details about Gmail and yahoo mail server and port details for communicating over SMTP.

Please make a NOTE that Gmail and yahoo mail nowadays does not let us login to the server using a password if we are trying to access their account through some other applications/scripts. It requires us to create an app password that will be used to authenticate that application/script.

Steps to create an app password for Gmail

  • Login to Gmail.
  • Click on Manage your Google Account by clicking on the profile icon on the top right.
  • Click on Security from the left list.
  • Click on App passwords on the security page (Signing into Google Section). It'll ask for a google password to log in again.
  • There will be two dropdowns to select (Select app and Select device). Select Other option for both dropdowns. It'll ask you to give the name of the app. Give the app the name that you like (Ex - SMTP Tutorial). If you had previously created some app then they will be shown in the list along with the last date when you last used it. You can delete old apps from here if you are not using them anymore.
  • Click on Generate and it'll open a window where a temporary password (16 characters) will be displayed.
  • Save this password to use it for the tutorial. It'll display the password only once hence save it in a safe place otherwise you will need to create a new app if the password is lost.

Steps to create an app password for yahoo mail

  • Login to Yahoo Mail.
  • Click on Account Info by clicking on the profile icon from the top right.
  • Click on Account Security from the left list.
  • Click on Manage app passwords at last on that page.
  • On the newly opened window select Other app from the dropdown list. This page will also display a list of already created apps with their last use time. You can delete olds apps from here if you are not using them anymore.
  • It'll show a text box to enter the name of the app. Give the name to the app (Ex - SMTP Tutorial).
  • Click on Generate button to generate an app password. It'll open a new window with a password (16 characters).
  • Save this password to use for the future. It'll display the password only once hence save it in a safe place otherwise you will need to create a new app if the password is lost.

Please DELETE the app if you are no longer using that app for your own safety.

Example 1: Connect to Mail Server

As a part of our first example, we are demonstrating how we can connect to the mail server using SMTP_SSL.


  • SMTP(host='',port=0[,timeout]) - This constructor accepts hostname and port as input and connects to the server. It returns an instance of SMTP which can be then used to communicate with the server. There is an optional timeout parameter that accepts the number as input and time-out the connection after trying for that many seconds to connect to the server.
  • SMTP_SSL(host='',port=0[,timeout]) - This constructor works exactly like SMTP but does communication over SSL. It returns an instance of SMTP_SSL.

Our code for this example has 3 parts. The first two parts try to connect with the SMTP server of Gmail using SMTP class and the third party tries to connect using SMTP_SSL. The first two fails because Gmail does not allow connection over normal SMTP. It only accepts the connection over SSL. The second part has included a timeout of 3 seconds hence it times out and prints an error. We have also printed the time taken by each part.

In [2]:
import smtplib
import time

################### SMTP ########################
start = time.time()
try:
    smtp = smtplib.SMTP(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp = None

print("Connection Object : {}".format(smtp))
print("Total Time Taken  : {:,.2f} Seconds\n".format(time.time() - start))

############### SMTP with Timeout ######################
start = time.time()
try:
    smtp = smtplib.SMTP(host="smtp.gmail.com", port=465, timeout=3)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp = None

print("Connection Object : {}".format(smtp))
print("Total Time Taken  : {:,.2f} Seconds\n".format(time.time() - start))

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))
ErrorType : SMTPServerDisconnected, Error : Connection unexpectedly closed
Connection Object : None
Total Time Taken  : 10.28 Seconds

ErrorType : SMTPServerDisconnected, Error : Connection unexpectedly closed: timed out
Connection Object : None
Total Time Taken  : 3.13 Seconds

Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f42c8070>
Total Time Taken  : 0.75 Seconds

Example 2: Login and Logout

As a part of our second example, we are explaining how we can log in and logout of the server using user name and password once the connection is established.


Important Methods of SMTP/SMTP_SSL Instance

  • login(user, password) - This method accepts user name and password as input and logs in to the server using authentication. It returns two values as output. The response code and response message.
  • quit() - This method logs the user out of the session and terminates the connection with the server.

2.1: Gmail

Our code for this example connects to the Gmail server by creating an instance of SMTP_SSL. It then tries to log in to the server using the user name and app password. After successful login, it logs out of the session. We are printing response code and response messages for each call of the methods.

In [3]:
import smtplib
import time

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f42dee20>
Total Time Taken  : 0.57 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection v5sm16370789pfc.100 - gsmtp

2.2: Yahoo Mail

Our code for this example is exactly the same as our code for the previous part with the only difference that we are connecting to the Yahoo mail server in this part.

In [4]:
import smtplib
import time

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.mail.yahoo.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="sunny.2309@yahoo.in", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f4297970>
Total Time Taken  : 0.64 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Authentication successful

Logging Out....
Response Code : 221
Response      : Service Closing transmission

Example 3: Verify Email Address with Debugging Messages

As a part of our third example, we are explaining how we can verify user name by connecting to the SMTP server using verify() method.


Important Methods of SMTP/SMTP_SSL Instance

  • verify(address) - It accepts email addresses as input and sends them for verification purposes to the server.
  • ehlo_or_helo_if_needed() - It sends HELO or EHLO command to the server to identify the client connecting to it.
  • set_debuglevel(level) - It accepts integer value specifying to print debugging messages at that level. It prints debugging messages for communication with the server if the level is set to 1. It prints debugging messages with a timestamp for communication with the server if the level is set to 2.

3.1: Debugging Level 1

Our code for this example first connects to the Gmail mail server by creating an instance of SMTP_SSL providing its hostname and port number. It then sets the debug level to 1 to prints all communication messages. We then login to the mail server by providing user credentials. We are then verifying an email address using verify() method. We are then logging out of the server and terminating the connection with the server.

In [5]:
import smtplib
import time

################# IMAP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

smtp_ssl.set_debuglevel(1)

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In........")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

######### Verify mail adress ############################
print("\nVerifying Email Address.......")
resp_code, response = smtp_ssl.verify("coderzcolumn07@gmail.com")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

######### Log out to mail account ############################
print("\nLogging Out.......")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f4293b80>
Total Time Taken  : 0.86 Seconds

Logging In........
send: 'ehlo [127.0.1.1]\r\n'
reply: b'250-smtp.gmail.com at your service, [49.34.236.95]\r\n'
reply: b'250-SIZE 35882577\r\n'
reply: b'250-8BITMIME\r\n'
reply: b'250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\r\n'
reply: b'250-ENHANCEDSTATUSCODES\r\n'
reply: b'250-PIPELINING\r\n'
reply: b'250-CHUNKING\r\n'
reply: b'250 SMTPUTF8\r\n'
reply: retcode (250); Msg: b'smtp.gmail.com at your service, [49.34.236.95]\nSIZE 35882577\n8BITMIME\nAUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\nENHANCEDSTATUSCODES\nPIPELINING\nCHUNKING\nSMTPUTF8'
send: 'AUTH PLAIN AG1haWwyc3VubnkuMjMwOUBnbWFpbC5jb20Aa3VnZXVhYW5jcnVya3dkbQ==\r\n'
reply: b'235 2.7.0 Accepted\r\n'
reply: retcode (235); Msg: b'2.7.0 Accepted'
send: 'vrfy coderzcolumn07@gmail.com\r\n'
Response Code : 235
Response      : 2.7.0 Accepted

Verifying Email Address.......
reply: b"252 2.1.5 Send some mail, I'll try my best ob6sm15406459pjb.30 - gsmtp\r\n"
reply: retcode (252); Msg: b"2.1.5 Send some mail, I'll try my best ob6sm15406459pjb.30 - gsmtp"
send: 'quit\r\n'
Response Code : 252
Response      : 2.1.5 Send some mail, I'll try my best ob6sm15406459pjb.30 - gsmtp

Logging Out.......
Response Code : 221
Response      : 2.0.0 closing connection ob6sm15406459pjb.30 - gsmtp
reply: b'221 2.0.0 closing connection ob6sm15406459pjb.30 - gsmtp\r\n'
reply: retcode (221); Msg: b'2.0.0 closing connection ob6sm15406459pjb.30 - gsmtp'

3.2: Debugging Level 2 (Times Stamp Display)

Our code for this example is almost the same as our code for the previous example with minor changes. The first change is that we have set debug level to 2 in this example. The second change is that before logging in, we have called ehlo_or_helo_if_needed() method. This method will make sure that login() method does not need to send HELO/EHLO message to the server which it does if the user had not identified itself with the server.

In [6]:
import smtplib
import time

################# IMAP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

smtp_ssl.set_debuglevel(2)

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

################# Saying Hello ################################
print("\nSaying Hello to server........")
smtp_ssl.ehlo_or_helo_if_needed()

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

######### Verify mail adress ############################
print("\nVerifying Email Address.......")
resp_code, response = smtp_ssl.verify("coderzcolumn07@gmail.com")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

######### Log out to mail account ############################
print("\nLogging Out........")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f42ec220>
Total Time Taken  : 0.59 Seconds

Saying Hello to server........
13:21:16.586262 send: 'ehlo [127.0.1.1]\r\n'
13:21:16.886116 reply: b'250-smtp.gmail.com at your service, [49.34.236.95]\r\n'
13:21:16.886457 reply: b'250-SIZE 35882577\r\n'
13:21:16.886604 reply: b'250-8BITMIME\r\n'
13:21:16.887404 reply: b'250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\r\n'
13:21:16.887596 reply: b'250-ENHANCEDSTATUSCODES\r\n'
13:21:16.887746 reply: b'250-PIPELINING\r\n'
13:21:16.887892 reply: b'250-CHUNKING\r\n'
13:21:16.888032 reply: b'250 SMTPUTF8\r\n'
13:21:16.888186 reply: retcode (250); Msg: b'smtp.gmail.com at your service, [49.34.236.95]\nSIZE 35882577\n8BITMIME\nAUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH\nENHANCEDSTATUSCODES\nPIPELINING\nCHUNKING\nSMTPUTF8'
13:21:16.889269 send: 'AUTH PLAIN AG1haWwyc3VubnkuMjMwOUBnbWFpbC5jb20Aa3VnZXVhYW5jcnVya3dkbQ==\r\n'
Logging In.....
13:21:17.249095 reply: b'235 2.7.0 Accepted\r\n'
13:21:17.250201 reply: retcode (235); Msg: b'2.7.0 Accepted'
13:21:17.251279 send: 'vrfy coderzcolumn07@gmail.com\r\n'
Response Code : 235
Response      : 2.7.0 Accepted

Verifying Email Address.......
13:21:17.525995 reply: b"252 2.1.5 Send some mail, I'll try my best x9sm16210044pjp.29 - gsmtp\r\n"
13:21:17.527121 reply: retcode (252); Msg: b"2.1.5 Send some mail, I'll try my best x9sm16210044pjp.29 - gsmtp"
13:21:17.528046 send: 'quit\r\n'
Response Code : 252
Response      : 2.1.5 Send some mail, I'll try my best x9sm16210044pjp.29 - gsmtp

Logging Out........
Response Code : 221
Response      : 2.0.0 closing connection x9sm16210044pjp.29 - gsmtp
13:21:17.872181 reply: b'221 2.0.0 closing connection x9sm16210044pjp.29 - gsmtp\r\n'
13:21:17.872382 reply: retcode (221); Msg: b'2.0.0 closing connection x9sm16210044pjp.29 - gsmtp'

Example 4: Send Mail using sendmail() Method

As a part of our fourth example, we'll demonstrate how we can send mail using sendmail() method once the connection has been established with the mail server and the user has logged in.


Important Methods of SMTP/SMTP_SSL Instance

  • sendmail(from_addr,to_addrs,msg) - This method lets us send mail to list of addresses. The from_addr parameter accepts a string representing the email address. The to_addrs parameter accepts a list of email addresses to which send mail. It also accepts a single string where a list of addresses is separated by a comma. The msg accepts a string or byte string representing the contents of the mail. This function returns a dictionary with a list of email addresses to which sending of mail failed. If mail sending fails to all addresses then it raises an error.

4.1: Represent Mail using Simple String

Our code for this example builds on the code from our previous examples. It creates a connection with the Gmail server and then logs in. It then sends simple mail using sendmail() method.

In [7]:
import smtplib
import time
import imaplib
import email

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

################ Send Mail ########################
print("\nSending Mail..........")
frm = "mail2sunny.2309@gmail.com"
to_list = ["mail2sunny.2309@gmail.com", "sunny.2309@yahoo.in", "coderzcolumn07@gmail.com"]
message = 'Subject: {}\n\n{}'.format("Test Email", "Hello All,\n\nHow are you doing?\n\nRegards,\nCoderzColumn")

response = smtp_ssl.sendmail(from_addr=frm,
                             to_addrs=to_list,
                             msg=message
                            )

print("List of Failed Recipients : {}".format(response))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f42d5fd0>
Total Time Taken  : 0.52 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection s27sm14870015pgk.77 - gsmtp

4.2: Use EmailMessage from email Module to Represent mail

Our code for this example is almost the same as our previous example with the only minor change that we have created an instance of EmailMessage available from email module which can be used to represent email messages. We can treat an instance of EmailMessage as a dictionary and set fields of mail like from, to, subject, etc. We have set the body of the email using set_content() method of the EmailMessage. When calling sendmail() method we have passed string by calling as_string() method on EmailMessage instance. The as_string() method returns string representation of email.

If you are interested in learning about how emails are represented in Python then please feel free to check our tutorial on module email which is used for it.

In [8]:
import smtplib
import time
import email

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

################ Send Mail ########################
print("\nSending Mail..........")

message = email.message.EmailMessage()
message.set_default_type("text/plain")

frm = "mail2sunny.2309@gmail.com"
to_list = ["mail2sunny.2309@gmail.com", "sunny.2309@yahoo.in", "coderzcolumn07@gmail.com"]
message["From"] = frm
message["To"] = to_list
message["Subject"] =  "Test Email"

body = '''
Hello All,

How are you doing?

Regards,
CoderzColumn
'''
message.set_content(body)

response = smtp_ssl.sendmail(from_addr=frm,
                             to_addrs=to_list,
                             msg=message.as_string())

print("List of Failed Recipients : {}".format(response))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f4293d60>
Total Time Taken  : 0.55 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection q64sm3380408pfb.6 - gsmtp

Example 5: Send Mail using send_message() Method

As a part of our fifth example, we are demonstrating how we can send mail using send_message() method.


  • send_message(msg,from_addr=None,to_addrs=None) - This method lets us send mail to list of addresses using EmailMessage instance. The msg parameter accepts an instance of EmailMessage which has information about mail. The from_addr parameter accepts a string representing the address from which we are sending mail. If EmailMessage instance has information about from address then this parameter can be ignored. The to_addrs parameter accepts a list of addresses to which mail needs to be sent. We don't need to provide this parameter if EmailMessage instance has information about addresses to which we are sending emails.

Our code for this example is almost the same as our previous example with the only major change that we are using send_message() method to send mail.

In [9]:
import smtplib
import time
import email

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

################ Send Mail ########################
print("\nSending Mail..........")

message = email.message.EmailMessage()
message.set_default_type("text/plain")
message["From"] = "mail2sunny.2309@gmail.com"
message["To"] = ["mail2sunny.2309@gmail.com", "sunny.2309@yahoo.in", "coderzcolumn07@gmail.com"]
message["Subject"] =  "Test Email"

body = '''
Hello All,

How are you doing?

Regards,
CoderzColumn
'''
message.set_content(body)

response = smtp_ssl.send_message(msg=message)

print("List of Failed Recipients : {}".format(response))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f4293370>
Total Time Taken  : 0.53 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection w18sm3035802pjh.19 - gsmtp

Example 6: Add Recipients in CC and BCC

As a part of our sixth example, we are demonstrating how we can set CC and BCC fields of the mail.

Our code for this example is exactly the same as our previous example with minor changes. We have moved one of our addresses to Cc field and one address to Bcc field of the EmailMessage instance representing mail.

In [10]:
import smtplib
import time
import email

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

################ Send Mail ########################
print("\nSending Mail..........")

message = email.message.EmailMessage()
message.set_default_type("text/plain")
message["From"] = "mail2sunny.2309@gmail.com"
message["To"] = ["coderzcolumn07@gmail.com", ]
message["cc"] = ["mail2sunny.2309@gmail.com",]
message["Bcc"] = ["sunny.2309@yahoo.in", ]

message["Subject"] =  "Test Email"

body = '''
Hello All,

How are you doing?

Regards,
CoderzColumn
'''
message.set_content(body)

response = smtp_ssl.send_message(msg=message)

print("List of Failed Recipients : {}".format(response))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f4047e50>
Total Time Taken  : 0.52 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection u1sm12615206pfn.209 - gsmtp

Example 7: Send Attachments with Mail

As a part of our seventh example, we'll explain how we can attach files to our mail using add_attachment() method of EmailMessage instance.

7.1: Attach JPEG Image

Our code for this example is almost the same as our previous example with the minor addition of code for attaching a jpeg image file. We have kept a JPEG image file in the same directory. We are first reading the file's content as bytes. Then we are calling add_attachment() method on an instance of EmailMessage giving it bytes data as input. We are also setting other parameters of add_attachment() as mentioned below.

  • maintype - It accepts a string representing the main type of the attachment.
  • subtype - It accepts a string representing the subtype of the attachment.
  • filename - It accepts a string representing the file name of the attachment.

If you are interested in learning about which main and subtype to use for different file types then please check the below link.

In [11]:
import smtplib
import time
import email

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

################ Send Mail ########################
print("\nSending Mail..........")

message = email.message.EmailMessage()

message["From"] = "mail2sunny.2309@gmail.com"
message["To"] = ["coderzcolumn07@gmail.com", ]
message["cc"] = ["mail2sunny.2309@gmail.com",]
message["Bcc"] = ["sunny.2309@yahoo.in", ]

message["Subject"] =  "Mail with attachments"

body = '''
Hello All,

Please find attached file.

Regards,
CoderzColumn
'''
message.set_content(body)

### Attach JPEG Image.
with open("dr_apj_kalam.jpeg", mode="rb") as fp:
    img_content = fp.read()
    message.add_attachment(img_content, maintype="image", subtype="jpeg", filename="kalam.jpeg")

### Send Message
response = smtp_ssl.send_message(msg=message)

print("List of Failed Recipients : {}".format(response))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2e59d5040>
Total Time Taken  : 0.53 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection z137sm17611896pfc.172 - gsmtp

7.2: Attach PDF FIle

Our code for this example is almost the same as our previous example with the only change that we are using a PDF file in this example instead of a JPEG file.

In [15]:
import smtplib
import time
import email

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

################ Send Mail ########################
print("\nSending Mail..........")

message = email.message.EmailMessage()

message["From"] = "mail2sunny.2309@gmail.com"
message["To"] = ["coderzcolumn07@gmail.com", ]
message["cc"] = ["mail2sunny.2309@gmail.com",]
message["Bcc"] = ["sunny.2309@yahoo.in", ]

message["Subject"] =  "Mail with attachments"

body = '''
Hello All,

Please find attached file.

Regards,
CoderzColumn
'''
message.set_content(body)

### Attach PDF Image.
with open("Deploying a Django Application to Google App Engine.pdf", mode="rb") as fp:
    pdf_content = fp.read()
    message.add_attachment(pdf_content, maintype="application", subtype="pdf", filename="doc.pdf")

### Send Message
response = smtp_ssl.send_message(msg=message)

print("List of Failed Recipients : {}".format(response))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2f40479a0>
Total Time Taken  : 0.82 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection 14sm16748218pfy.55 - gsmtp

7.3: Attach Zip File

Our code for this example is almost the same as our previous example with the only change that we are attaching a zip file in this example instead. The zip file has PDF and a JPEG image from previous examples in it.

In [16]:
import smtplib
import time
import email

################# SMTP SSL ################################
start = time.time()
try:
    smtp_ssl = smtplib.SMTP_SSL(host="smtp.gmail.com", port=465)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
    smtp_ssl = None

print("Connection Object : {}".format(smtp_ssl))
print("Total Time Taken  : {:,.2f} Seconds".format(time.time() - start))

######### Log In to mail account ############################
print("\nLogging In.....")
resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))

################ Send Mail ########################
print("\nSending Mail..........")

message = email.message.EmailMessage()

message["From"] = "mail2sunny.2309@gmail.com"
message["To"] = ["coderzcolumn07@gmail.com", ]
message["cc"] = ["mail2sunny.2309@gmail.com",]
message["Bcc"] = ["sunny.2309@yahoo.in", ]

message["Subject"] =  "Mail with attachments"

body = '''
Hello All,

Please find attached file.

Regards,
CoderzColumn
'''
message.set_content(body)

### Attach Zip Image.
with open("docs.zip", mode="rb") as fp:
    zip_content = fp.read()
    message.add_attachment(zip_content, maintype="application", subtype="zip", filename="docs.zip")

### Send Message
response = smtp_ssl.send_message(msg=message)

print("List of Failed Recipients : {}".format(response))

######### Log out to mail account ############################
print("\nLogging Out....")
resp_code, response = smtp_ssl.quit()

print("Response Code : {}".format(resp_code))
print("Response      : {}".format(response.decode()))
Connection Object : <smtplib.SMTP_SSL object at 0x7ff2e59d5340>
Total Time Taken  : 0.66 Seconds

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

Logging Out....
Response Code : 221
Response      : 2.0.0 closing connection b14sm16171889pfi.74 - gsmtp

Example 8: SMTP_SSL as a Context Manager

As a part of our eighth example, we are demonstrating that we can use SMTP_SSL instance as context manager as well. If we use SMTP_SSL as context manager then we don't need to call quit() method to close the connection. It'll be called automatically once the context manager ends.

Our code for this example is almost the same as our 4th example with the only change that we are using SMTP_SSL as a context manager and not calling quit() method to end connection.

In [1]:
import smtplib
import time
import imaplib
import email

################# SMTP SSL ################################
with smtplib.SMTP_SSL(host="smtp.gmail.com", port=465) as smtp_ssl:
    print("Connection Object : {}".format(smtp_ssl))

    ######### Log In to mail account ############################
    print("\nLogging In.....")
    resp_code, response = smtp_ssl.login(user="mail2sunny.2309@gmail.com", password="app_password")

    print("Response Code : {}".format(resp_code))
    print("Response      : {}".format(response.decode()))

    ################ Send Mail ########################
    print("\nSending Mail..........")
    frm = "mail2sunny.2309@gmail.com"
    to_list = ["mail2sunny.2309@gmail.com", "sunny.2309@yahoo.in", "coderzcolumn07@gmail.com"]
    message = 'Subject: {}\n\n{}'.format("Test Email", "Hello All,\n\nHow are you doing?\n\nRegards,\nCoderzColumn")

    response = smtp_ssl.sendmail(from_addr=frm,
                                 to_addrs=to_list,
                                 msg=message
                                )

    print("List of Failed Recipients : {}".format(response))demonstrating
Connection Object : <smtplib.SMTP_SSL object at 0x7fcd7bdc2748>

Logging In.....
Response Code : 235
Response      : 2.7.0 Accepted

Sending Mail..........
List of Failed Recipients : {}

This ends our small tutorial explaining how we can use smtplib to send mails using Python. Please feel free to let us know your views in the comments section.

References



Sunny Solanki  Sunny Solanki