Internet Message Access Protocol is an Internet protocol that lets us access email messages from mailboxes. It even let us move mails between mailboxes, create directories within mailboxes, mark emails as read/unread, marks emails as important, etc. It's the protocol used by all the email clients to access the mailbox of the user. The current version of IMAP is IMAP4rev1 generally referred to as IMAP4. Python provides us with the library named imaplib which lets us access our mailbox and read emails over IMAP.
As a part of this tutorial, we'll explain with simple examples how we can use imaplib to access mailboxes, read emails, copy mails between directories, create directories, etc. We'll be logging in to our Gmail and Yahoo mail servers for this. Gmail and Yahoo mail provides access to IMAP4 over port number 993. Gmail and Yahoo mail let us access the mailbox over SSL only. The below link has information about hostname and port details about Gmail and Yahoo mail that we'll be using for our examples.
Please make a NOTE that Gmail and yahoo mail nowadays does not let us login to the server using a password nowadays 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.
Below we have given steps to create an app whose password we'll use to access Gmail and Yahoo mail mailboxes.
Steps to create an app password for Gmail
Steps to create an app password for yahoo mail
Please DELETE the app if you are no longer using that app for your own safety.
As a part of our first example, we are explaining how we can make connections to the mail server over IMAP4. The imaplib provides us with a class named IMPA4 and IMAP4_SSL which can be used to make a connection to the server.
Our code for this example has three-part. The first part tries connection with the Gmail mail server over port 993 using IMAP4 class. The second part tries the same but with the timeout set to 3 seconds using IMAP4 class. The third part tries to connect with the Gmail server using IMAP4_SSL class. Our first two parts of the code fail to connect to the server because Gmail and Yahoo mail allows connection over SSL only. The third part of our code is successfully able to connect to the mail server.
import imaplib
import time
################### IMAP ########################
start = time.time()
try:
imap = imaplib.IMAP4(host="imap.gmail.com", port=993)
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
imap = None
print("Connection Object : {}".format(imap))
print("Total Time Taken : {:,.2f} Seconds\n".format(time.time() - start))
############### IMAP with Timeout ######################
start = time.time()
try:
imap = imaplib.IMAP4(host="imap.gmail.com", port=993, timeout=3)
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
imap = None
print("Connection Object : {}".format(imap))
print("Total Time Taken : {:,.2f} Seconds\n".format(time.time() - start))
################# IMAP SSL ################################
start = time.time()
try:
imap_ssl = imaplib.IMAP4_SSL(host="imap.gmail.com", port=993)
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
imap_ssl = None
print("Connection Object : {}".format(imap_ssl))
print("Total Time Taken : {:,.2f} Seconds".format(time.time() - start))
As a part of our second example, we are demonstrating how we can log in to the server using credentials and log out once the connection is established using IMAP4 instance.
Please make a NOTE that majority of methods of IMAP4/IMAP4_SSL returns a tuple of two values of the form (reponse_code, [reponse_message,...]). The response code is either OK or NONE. The response message is a list with a single binary string or a list of binary strings based on the method call. If the method is a simple command like login/logout then the second value of the tuple is a list with one value (binary message) specifying the response of the server after the execution of that method.
Our code for this example first creates an instance of IMAP4_SSL and establishes a connection with the server. It then calls the login() method with user name and password to log in a user to the server. At last, it calls logout() to log the user out. All our method calls are wrapped inside of the try-except block to catch any errors that can happen. We are also printing response codes and messages.
Please make a NOTE that we are calling decode() methods on response messages to convert them from bytes to string format.
import imaplib
import time
################ IMAP SSL ##############################
start = time.time()
try:
imap_ssl = imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT)
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
imap_ssl = None
print("Connection Object : {}".format(imap_ssl))
print("Total Time Taken : {:,.2f} Seconds\n".format(time.time() - start))
############### Login to Mailbox ######################
print("Logging into mailbox...")
try:
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, response = None, None
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############### Logout of Mailbox ######################
print("\nLogging Out....")
try:
resp_code, response = imap_ssl.logout()
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, response = None, None
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
As a part of our third example, we'll explain how we can list down directories present within the mailbox using list() method of IMAP4/IMAP4_SSL instance.
Our code for this example tarts like our previous examples by establishing a connection with the server and logging in to it. It then calls list() method without any parameters to list down all mailboxes present. We are then looping through all directories and printing them. We have then called list() method with parameter directory set to [Gmail] so that it returns directory which are subdirectories of it. Our code then logs out of the server.
import imaplib
import time
################ IMAP SSL ##############################
start = time.time()
try:
imap_ssl = imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT)
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
imap_ssl = None
print("Connection Object : {}".format(imap_ssl))
print("Total Time Taken : {:,.2f} Seconds\n".format(time.time() - start))
############### Login to Mailbox ######################
print("Logging into mailbox...")
try:
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, response = None, None
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
#################### List Directores #####################
try:
resp_code, directories = imap_ssl.list()
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, directories = None, None
print("Response Code : {}".format(resp_code))
print("========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
#################### List Directores #####################
try:
resp_code, directories = imap_ssl.list(directory="[Gmail]")
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, directories = None, None
print("Response Code : {}".format(resp_code))
print("\n========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
############### Logout of Mailbox ######################
print("\nLogging Out....")
try:
resp_code, response = imap_ssl.logout()
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, response = None, None
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
As a part of our fourth example, we are again explaining the usage of list() method to list down mailboxes present in the directory but this time we are explaining pattern parameter. The pattern parameter accepts a pattern to match the list of directories that matches that pattern.
Our code for this example starts by establishing a connection with the server and logs in to it like our previous examples. It then calls list() method with a pattern that will match all directories which has Coursera word in them. We print all subdirectories which match this pattern. We have then called list() method again with a pattern that matches for word Coursera/Algo at the beginning of the directory name. We again print a list of directories that matches this pattern. At last, we log out of the server.
import imaplib
import time
################ IMAP SSL ##############################
start = time.time()
try:
imap_ssl = imaplib.IMAP4_SSL(host="imap.mail.yahoo.com", port=imaplib.IMAP4_SSL_PORT)
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
imap_ssl = None
print("Connection Object : {}".format(imap_ssl))
print("Total Time Taken : {:,.2f} Seconds\n".format(time.time() - start))
############### Login to Mailbox ######################
print("Logging into mailbox...")
try:
resp_code, response = imap_ssl.login("sunny.2309@yahoo.in", "app_password")
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, response = None, None
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
#################### List Directores #####################
try:
resp_code, directories = imap_ssl.list(pattern="*Coursera*")
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, directories = None, None
print("Response Code : {}".format(resp_code))
print("========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
#################### List Directores #####################
try:
resp_code, directories = imap_ssl.list(pattern="Coursera/Algo*")
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, directories = None, None
print("Response Code : {}".format(resp_code))
print("\n========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
############### Logout of Mailbox ######################
print("\nLogging Out....")
try:
resp_code, response = imap_ssl.logout()
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))
resp_code, response = None, None
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
Our code for this example is almost the same as our code for the third example with the only change that we are using IMAP4_SSL instance as a context manager. As we are using IMAP4_SSL instance as a context manager, we don't need to call logout() method to log out of the server. When we are exiting of context, the logout() method will be called by the context manager.
import imaplib
import time
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
#################### List Directores #####################
resp_code, directories = imap_ssl.list()
print("Response Code : {}".format(resp_code))
print("========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
#################### List Directores #####################
resp_code, directories = imap_ssl.list(directory="[Gmail]")
print("Response Code : {}".format(resp_code))
print("\n========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
As a part of our sixth example, we are demonstrating how we can display the count of mail messages present per-directory using select() method of IMAP4_SSL instance.
select(mailbox='INBOX',readonly=False) - This method select as mailbox given by parameter mailbox so that all the operations that we'll perform after this method will be performed on this selected mailbox. It's set to INBOX by default. It returns the tuple of two values where the second value has a count of the mails for a given mailbox.
close() - It closes currently selected mailbox. The deleted messages are permanently removed from the mailbox. We should call this command before logging out of the mailbox.
Our code for this example starts by creating an instance of IMAP4_SSL and logging in to the mail server. It then lists down a list of directories present in the mailbox using list() method. We are then looping through the list of directories and retrieving mail count per-directory using select() method. We are accessing the mailbox in read-only mode.
import imaplib
import time
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
#################### List Directores #####################
resp_code, directories = imap_ssl.list()
print("Response Code : {}".format(resp_code))
print("========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
############### Number of Messages per Directory ############
print("\n=========== Mail Count Per Directory ===============\n")
for directory in directories:
directory_name = directory.decode().split('"')[-2]
directory_name = '"' + directory_name + '"'
try:
resp_code, mail_count = imap_ssl.select(mailbox=directory_name, readonly=True)
except Exception as e:
print("{} - ErrorType : {}, Error : {}".format(directory_name, type(e).__name__, e))
resp_code, mail_count = None, None
############# Close Selected Mailbox #######################
imap_ssl.close()
As a part of our seventh example, we are demonstrating how we can retrieve mails from mailboxes using search() method.
search(charset, criterion) - This method searches mailbox based on criteria provided using criterion parameter. The criterion parameter accepts string specifying which mails to retrieve. This method will return a tuple of two values where the second value will have a byte string having a list of mail ids separated by space.
fetch(message_set,message_parts) - This method accepts string specifying list of message ids and string specifying message parts to retrieve for all messages.
Below link has detailed information about strings which can be used as criterion parameter of search() method and message_parts parameter of fetch() method.
Our code for this example starts by connecting to the server by creating an instance of IMAP4_SSL. It then logs in to the server and then selects ELITMUS as a mailbox. It then retrieves mail ids for all mails inside of ELITMUS mailbox using select() method. The mail ids are an integer from 1 to a number of mails in the box. The number 1 represents the oldest mail and the maximum number represents the latest mail id. We then take the last two mail ids and retrieve mail contents using fetch() method. We are creating an instance of EmailMessage which is a wrapper class provided by email module which is used to represent mails. We can generate an instance of EmailMessage by calling message_from_bytes() method of email module. The method accepts a message represented as byte string as input and returns EmailMessage instance.
We are then printing various parts of the mail like from, to, bcc, data, subject, and body. We are calling walk() method instance of EmailMessage to retrieve all parts of the message and printing only part which is text.
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.
import imaplib
import email
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############### Set Mailbox #############
resp_code, mail_count = imap_ssl.select(mailbox="ELITMUS", readonly=True)
############### Retrieve Mail IDs for given Directory #############
resp_code, mails = imap_ssl.search(None, "ALL")
print("Mail IDs : {}\n".format(mails[0].decode().split()))
############### Display Few Messages for given Directory #############
for mail_id in mails[0].decode().split()[-2:]:
print("================== Start of Mail [{}] ====================".format(mail_id))
resp_code, mail_data = imap_ssl.fetch(mail_id, '(RFC822)') ## Fetch mail data.
message = email.message_from_bytes(mail_data[0][1]) ## Construct Message from mail data
print("From : {}".format(message.get("From")))
print("To : {}".format(message.get("To")))
print("Bcc : {}".format(message.get("Bcc")))
print("Date : {}".format(message.get("Date")))
print("Subject : {}".format(message.get("Subject")))
print("Body : ")
for part in message.walk():
if part.get_content_type() == "text/plain":
body_lines = part.as_string().split("\n")
print("\n".join(body_lines[:12])) ### Print first 12 lines of message
print("================== End of Mail [{}] ====================\n".format(mail_id))
############# Close Selected Mailbox #######################
print("\nClosing selected mailbox....")
imap_ssl.close()
As a part of our eighth example, we are demonstrating how we can create, delete and rename mailboxes using create(), delete() and rename() methods of IMAP4_SSL instance.
Our code for this example starts by establishing a connection to the server by creating an instance of IAP4_SSL. We are then logging in to the mail server. We are then selecting mailbox as INBOX using select() method. We are then creating a mailbox named ELITMUS_2 using create() method. Once the mailbox is created, we are listing down directories using list() method to check whether the mailbox was created or not. We are then deleting mailbox using delete() method. Once the mailbox is deleted, we are again listing down mailboxes to check whether the mailbox was deleted or not. The last part of our code rename mailbox ELITMUS_2 to ELITMUS_3 using rename() method. We are then again listing down directories to check whether the mailbox was renamed or not.
Once all operations are performed, we are calling expunge() method to make the change permanent and close the mailbox using close() method.
import imaplib
import email
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############### Set Mailbox #############
resp_code, mail_count = imap_ssl.select(mailbox="INBOX", readonly=False)
############### Create Mailbox #############
print("Creating Mailbox : ELITMUS_2")
resp_code, mail_count = imap_ssl.create(mailbox="ELITMUS_2")
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
#################### List Directores #####################
resp_code, directories = imap_ssl.list()
print("\nResponse Code : {}".format(resp_code))
print("========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
############### Delete Mailbox #############
print("\nDeleting Mailbox : Myntra")
resp_code, mail_count = imap_ssl.delete(mailbox="Myntra")
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
#################### List Directores #####################
resp_code, directories = imap_ssl.list()
print("\nResponse Code : {}".format(resp_code))
print("========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
############### Rename Mailbox #############
print("\nRenaming Mailbox : ELITMUS_2")
resp_code, mail_count = imap_ssl.rename(oldmailbox="ELITMUS_2", newmailbox="ELITMUS_3")
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
#################### List Directores #####################
resp_code, directories = imap_ssl.list()
print("\nResponse Code : {}".format(resp_code))
print("========= List of Directories =================\n")
for directory in directories:
print(directory.decode())
################### Expunge ########################
print("\nFinalizing changes...")
resp_code, directories = imap_ssl.expunge()
print("\nResponse Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
############# Close Selected Mailbox #######################
print("\nClosing selected mailbox....")
imap_ssl.close()
As a part of the ninth example, we'll explain how we can copy mails from one directory to another using copy() method of IMAP4_SSL instance.
Our code for this example starts by creating an instance of IMPA4_SSL to establish a connection to the server. It then logs in to the server and selects the mailbox as ELITMUS. It then searches the mailbox using search() method to retrieve all mail ids. It then takes the last two mail ids and copies them using copy() method to Personal mailbox. It passes both mail ids together to be copied. It then copies the first two emails from the ELITMUS mailbox to Personal mailbox. This time it loops through ids and copies individual mail by calling copy() method more than once. Once all operations are done, it closes mailbox using close() method.
import imaplib
import email
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############### Set Mailbox #############
resp_code, mail_count = imap_ssl.select(mailbox="ELITMUS", readonly=False)
############### Retrieve Mail IDs for given Directory #############
resp_code, mails = imap_ssl.search(None, "ALL")
print("Mail IDs : {}\n".format(mails[0].decode().split()))
################## Copy Messages to new mailbox ###################
print("\nCopying few mails of ELITMUS to different directory....")
mail_ids = mails[0].decode().split()[-2:]
mail_ids = ":".join(mail_ids)
print(mail_ids)
resp_code, response = imap_ssl.copy(mail_ids, "Personal")
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
################## Copy Messages to new mailbox ###################
print("\nCopying few mails of ELITMUS to different directory....")
mail_ids = mails[0].decode().split()[:2]
for mail_id in mail_ids:
resp_code, response = imap_ssl.copy(mail_id, "Personal")
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
############# Close Selected Mailbox #######################
print("\nClosing selected mailbox....")
imap_ssl.close()
As a part of our tenth example, we are demonstrating how we can search mailbox using different patterns passed to criterion parameter of the search() method.
Our code for this example like our previous example starts by establishing a connection with the server and logging in to the server. It then selects a mailbox named INBOX. It then gives a pattern that searches for mails from a particular sender. It retrieves all mail ids matching that pattern using search() method. It then prints the contents of the last two emails from that sender. The second search call searches for a mail from a particular sender and subject line containing a particular string. It retrieves all mail ids matching that pattern and then uses that mail ids to print contents of the latest two emails matching that pattern.
import imaplib
import email
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############### Set Mailbox #############
resp_code, mail_count = imap_ssl.select(mailbox="INBOX", readonly=True)
############### Search mails in a given Directory #############
resp_code, mails = imap_ssl.search(None, '(FROM "Neil Patel")')
mail_ids = mails[0].decode().split()
print("Total Mail IDs : {}\n".format(len(mail_ids)))
for mail_id in mail_ids[-2:]:
print("================== Start of Mail [{}] ====================".format(mail_id))
resp_code, mail_data = imap_ssl.fetch(mail_id, '(RFC822)') ## Fetch mail data.
message = email.message_from_bytes(mail_data[0][1]) ## Construct Message from mail data
print("From : {}".format(message.get("From")))
print("To : {}".format(message.get("To")))
print("Bcc : {}".format(message.get("Bcc")))
print("Date : {}".format(message.get("Date")))
print("Subject : {}".format(message.get("Subject")))
print("Body : ")
for part in message.walk():
if part.get_content_type() == "text/plain":
body_lines = part.as_string().split("\n")
print("\n".join(body_lines[:6])) ### Print first few lines of message
print("================== End of Mail [{}] ====================\n".format(mail_id))
############### Search mails in a given Directory #############
resp_code, mails = imap_ssl.search(None, 'FROM "Medium Daily Digest" Subject "Jupyter"')
mail_ids = mails[0].decode().split()
print("Total Mail IDs : {}\n".format(len(mail_ids)))
for mail_id in mail_ids[-2:]:
print("================== Start of Mail [{}] ====================".format(mail_id))
resp_code, mail_data = imap_ssl.fetch(mail_id, '(RFC822)') ## Fetch mail data.
message = email.message_from_bytes(mail_data[0][1]) ## Construct Message from mail data
print("From : {}".format(message.get("From")))
print("To : {}".format(message.get("To")))
print("Bcc : {}".format(message.get("Bcc")))
print("Date : {}".format(message.get("Date")))
print("Subject : {}".format(message.get("Subject")))
print("Body : ")
for part in message.walk():
if part.get_content_type() == "text/plain":
body_lines = part.as_string().split("\n")
print("\n".join(body_lines[:6])) ### Print first few lines of message
print("================== End of Mail [{}] ====================\n".format(mail_id))
############# Close Selected Mailbox #######################
print("\nClosing selected mailbox....")
imap_ssl.close()
As a part of our eleventh example, we'll demonstrate how we can delete mails from the mailbox using store() method by changing flags.
Below mentioned RFC has very detailed explanations of flags.
Our code for this example starts as usual by establishing a connection and logging into the server. It then select mailbox INBOX using select() method and retrieves emails ids from particular sender using search() method. We have set readonly parameter of select() method to False so that we can modify the mailbox otherwise we'll get an error when performing operations that try to modify the mailbox. It then loops through mail ids and sets the flag as \Deleted for the first two mail ids using store() method. It prints details with mail id, data, and subject informing which mails will be deleted. The store() method will set a flag indicating that these mails need to be deleted. Once flags are modified for two mail ids, we are calling expunge() method which will permanently delete both mails.
Please make a NOTE that we have used two backslashes inside the string of \\Deleted flag because a single backslash is used as an escape character and we need to escape it.
import imaplib
import email
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############### Set Mailbox #############
resp_code, mail_count = imap_ssl.select(mailbox="INBOX", readonly=False)
############### Search and delete mails in a given Directory #############
resp_code, mails = imap_ssl.search(None, '(FROM "Neil Patel")')
mail_ids = mails[0].decode().split()
print("Total Mail IDs : {}\n".format(len(mail_ids)))
print("Deleting Mails...")
for mail_id in mail_ids[:2]:
resp_code, mail_data = imap_ssl.fetch(mail_id, '(RFC822)') ## Fetch mail data.
message = email.message_from_bytes(mail_data[0][1]) ## Construct Message from mail data
print("Mail ID : {}, Date : {}, Subject : {}".format(mail_id, message.get("Date"), message.get("Subject")))
resp_code, response = imap_ssl.store(mail_id, '+FLAGS', '\\Deleted')
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
resp_code, response = imap_ssl.expunge()
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############# Close Selected Mailbox #######################
print("\nClosing selected mailbox....")
imap_ssl.close()
As a part of our twelfth example, we are demonstrating how we can mark the mail as important (starred) using store() method.
Our code for this example starts by establishing a connection with the server and then logs in to the server. It then selects INBOX as a mailbox to work with. It then retrieves mail ids of all mails in the mailbox. It then loops through the 5 latest mail ids and sets their flag (+FLAGS) as \Flagged using store() method. This will make mails as important mails. In our Gmail and Yahoo mail mailboxes, these mails will be starred. We are then again looping through mail ids and removing \Flagged emails from the latest two mails to mark them as unimportant again (-FLAGS). We are also printing details of mails (mail id, date, and subject) which are getting marked as important and unimportant.
import imaplib
import email
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
############### Set Mailbox #############
resp_code, mail_count = imap_ssl.select(mailbox="INBOX", readonly=False)
############### Mark few latest mails as important in a given Directory #############
resp_code, mails = imap_ssl.search(None, 'ALL')
mail_ids = mails[0].decode().split()
print("Total Mail IDs : {}\n".format(len(mail_ids)))
print("Flagging Important Mails...")
for mail_id in mail_ids[-5:]:
resp_code, mail_data = imap_ssl.fetch(mail_id, '(RFC822)') ## Fetch mail data.
message = email.message_from_bytes(mail_data[0][1]) ## Construct Message from mail data
print("Mail ID : {}, Date : {}, Subject : {}".format(mail_id, message.get("Date"), message.get("Subject")))
resp_code, response = imap_ssl.store(mail_id, '+FLAGS', '\\Flagged')
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode() if response[0] else response[0]))
############### Mark few latest mails as unimportant in a given Directory #############
print("Unflagging few Mails...")
for mail_id in mail_ids[-2:]:
resp_code, mail_data = imap_ssl.fetch(mail_id, '(RFC822)') ## Fetch mail data.
message = email.message_from_bytes(mail_data[0][1]) ## Construct Message from mail data
print("Mail ID : {}, Date : {}, Subject : {}".format(mail_id, message.get("Date"), message.get("Subject")))
resp_code, response = imap_ssl.store(mail_id, '-FLAGS', '\\Flagged')
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode() if response[0] else response[0]))
############# Close Selected Mailbox #######################
print("\nClosing selected mailbox....")
imap_ssl.close()
As a part of our thirteenth example, we'll explain how we can send NOOP command to the server to indicate no command at all. It can be used to keep the connection alive.
import imaplib
import email
################ IMAP SSL ##############################
with imaplib.IMAP4_SSL(host="imap.gmail.com", port=imaplib.IMAP4_SSL_PORT) as imap_ssl:
print("Connection Object : {}".format(imap_ssl))
############### Login to Mailbox ######################
print("Logging into mailbox...")
resp_code, response = imap_ssl.login("mail2sunny.2309@gmail.com", "app_password")
print("Response Code : {}".format(resp_code))
print("Response : {}\n".format(response[0].decode()))
################## Keeping Connection Alive ###############
resp_code, response = imap_ssl.noop() ## Keep connection Alive
print("Response Code : {}".format(resp_code))
print("Response : {}".format(response[0].decode()))
This ends our small tutorial explaining how we can use IMAP4 protocol through imaplib Python library to perform various operations with a mailbox. Please feel free to let us know your views in the comments section.
Thank You for visiting our website. If you like our work, please support us so that we can keep on creating new tutorials/blogs on interesting topics (like AI, ML, Data Science, Python, Digital Marketing, SEO, etc.) that can help people learn new things faster. You can support us by clicking on the Coffee button at the bottom right corner. We would appreciate even if you can give a thumbs-up to our article in the comments section below.
If you want to