Updated On : Aug-07,2022 Time Investment : ~30 mins

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

> What is IMAP?

Internet Message Access Protocol (IMAPv4) 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, mark emails as important, search emails, 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.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

> How Can I Access My Mailbox using Python?

Python provides us with the library named 'imaplib' which lets us access our mailbox and read emails over IMAP Protocol.

> What Can You Learn From This Tutorial?

As a part of this tutorial, we have explained how to use Python library imaplib to access mailboxes, read emails, copy emails between directories, create directories, search emails, delete emails, star emails, etc with simple examples. We have connected to Gmail server to explain various operations with mailboxes for a majority of our examples. Though same code can be used with Yahoo or any other mailboxes as well. We have connected to Yahoo server as well for one or two of our examples.

> How to Send Mails Using Python?

> How to Represent Mails in Python?

> How to Determine MIME Type Of an Attachment File in Python?

Below, we have listed important sections of Tutorial to give an overview of the material covered.

Important Sections Of Tutorial

  1. Steps to Create Gmail and Yahoo App for Connecting to Mailboxes
  2. Establish Connection to Mail Server
  3. Log in, Log Out ((Authenticate User) )
  4. List Mailboxes within Given Directory
  5. List Mailboxes Matching given a Pattern
  6. Use IMAP4_SSL as a Context Manager
  7. Display Mail Counts Per Directory
  8. Read Mails from Mailbox
  9. Create, Delete and Rename Mailboxes
  10. Copy Mails From Directory to Another
  11. Search for Mails Matching a Pattern in a Mailbox
  12. Delete Mails from Mailbox
  13. Flag Mails as Important (Starred)
  14. No Operation to Keep Connection Alive

1. Steps to Create Gmail and Yahoo App for Connecting to Mailboxes

This is the first step that we need to perform in order to access our mailbox.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

NOTE

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 that returns a token that will be used to authenticate that application/script. This is good for security of your account. We can anytime delete this app and application/script will not be able to access mailboxes. This can be useful if a hacker somehow gets access to your token/password.

Below we have given steps to create an app whose password we'll use to access Gmail and Yahoo mail mailboxes.

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

1.2. 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 old 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.

NOTE

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

2. Establish Connection to Mail Server

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.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python


  1. IMAP4(host='',port=IMAP4_PORT,timeout=None) - This constructor creates and returns an instance of IMAP4 by establishing connection with the host over the specified port. This instance can be used to communicate with the server. If the timeout parameter is specified then the process will timeout after trying for that many seconds if the connection is still not established.
  2. IMAP4_SSL(host='',port=IMAP4_SSL_PORT,timeout=None) - This constructor creates and returns an instance of IMAP4_SSL by establishing connection with host over specified port. It uses an SSL connection which is secure. It works exactly like IMAP4 but provides a connection over SSL.

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.

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

NOTE

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 links have information about hostname and port details about Gmail and Yahoo mail that we'll be using for our examples.

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))
ErrorType : abort, Error : socket error: EOF
Connection Object : None
Total Time Taken  : 10.68 Seconds

ErrorType : timeout, Error : timed out
Connection Object : None
Total Time Taken  : 3.15 Seconds

Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c64c550>
Total Time Taken  : 1.00 Seconds

3. Log in, Log Out (Authenticate User)

As a part of our second example, we are demonstrating how we can log in to the server using user credentials and log out once the connection is established using IMAP4 instance.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python


> Important Methods of IMAP4_SSL Object

  1. login(user, password) - It accepts user name and password as input and returns a tuple of two values. The first value in the tuple is a response code and the second value is a list with response messages.
  2. logout() - This method logs the user out of the server and returns a tuple of two values where the first value is the response code and the second value is a list with a response message.

NOTE

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, BYE or NONE.

The response message is a list with a single bytes string or a list of bytes 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 (bytes 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.

NOTE

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 Establish Connection #################
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()))
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c64c460>
Total Time Taken  : 0.87 Seconds

Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)


Logging Out....
Response Code : BYE
Response      : LOGOUT Requested

4. List Mailboxes within Given Directory

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.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python


> Important Methods of IMAP4_SSL Instance

  1. list(directory,pattern) - This method returns list of mailboxes present in the directory that matches given pattern as input. It returns a tuple of two values where the second value is a list of byte strings specifying directory names.

Our code for this example tarts like our previous examples by establishing a connection with the server and logging in to it.

Then, we called list() method without any parameters to list down all mailboxes present. We are then looping through all directories and printing them.

After that, we called list() method again but this time with parameter directory set to [Gmail] so that it returns directory which are subdirectories of it.

At last, Our code logs out of the server.

NOTE

Please make a NOTE that yahoo mailbox has Spam directory available with name "Bulk". If you are not able to find Spam folder in mail list then you can look for "\Junk" flag. The directory with this flag is generally Spam directory.

import imaplib
import time

################ IMAP SSL Connection ##############################
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()))
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c665880>
Total Time Taken  : 1.18 Seconds

Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Response Code : OK
========= List of Directories =================

(\HasNoChildren) "/" "ELITMUS"
(\HasNoChildren) "/" "INBOX"
(\HasNoChildren) "/" "Myntra"
(\HasNoChildren) "/" "Personal"
(\HasNoChildren) "/" "Receipts"
(\HasNoChildren) "/" "Work"
(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"
Response Code : OK

========= List of Directories =================

(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"

Logging Out....
Response Code : BYE
Response      : LOGOUT Requested

5. List Mailboxes Matching Given Pattern

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

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. The pattern format is same as the Unix directory matching patterns.

Our code for this example starts by establishing a connection with the server and logs in to it like our previous examples.

Then, it 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.

Then, we 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 Connection ##############################
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()))
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c67a520>
Total Time Taken  : 1.55 Seconds

Logging into mailbox...
Response Code : OK
Response      : LOGIN completed

Response Code : OK
========= List of Directories =================

(\HasChildren) "/" "Coursera"
(\HasNoChildren) "/" "Coursera/Algorithms - 1"
(\HasNoChildren) "/" "Coursera/Algorithms 1 - Standford"
(\HasNoChildren) "/" "Coursera/Analysis of algorithms"
(\HasNoChildren) "/" "Coursera/Cloud Android"
(\HasNoChildren) "/" "Coursera/Cryptography"
(\HasNoChildren) "/" "Coursera/Enhance Your Career"
(\HasNoChildren) "/" "Coursera/Machine Learning"
(\HasNoChildren) "/" "Coursera/POSA"
(\HasNoChildren) "/" "Coursera/Programming Mobile Application"
Response Code : OK

========= List of Directories =================

(\HasNoChildren) "/" "Coursera/Algorithms - 1"
(\HasNoChildren) "/" "Coursera/Algorithms 1 - Standford"

Logging Out....
Response Code : BYE
Response      : IMAP4rev1 Server logging out

6. Use IMAP4_SSL as a Context Manager (Python "with" Statement)

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

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 (Python "with" statement).

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.

Context managers are a very important concept of Python. It let us execute particular code within a context. It handles enter and exit tasks which are common for some code like DB connection, etc so. It helps us prevent errors like forgetting to close DB connection, etc.

Python provides a library named 'contextlib' that let us easily create context managers. We recommend that you check it out in your free time by clicking a link.

import imaplib
import time

################ IMAP SSL Connection ##############################

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())
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c6650a0>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Response Code : OK
========= List of Directories =================

(\HasNoChildren) "/" "ELITMUS"
(\HasNoChildren) "/" "INBOX"
(\HasNoChildren) "/" "Myntra"
(\HasNoChildren) "/" "Personal"
(\HasNoChildren) "/" "Receipts"
(\HasNoChildren) "/" "Work"
(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"
Response Code : OK

========= List of Directories =================

(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"

7. Display Mail Counts Per Directory

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.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python


> Important Methods of IMAP4_SSL Instance

  1. select(mailbox='INBOX',readonly=False) - This method sets 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.

    • The readonly parameter accepts a boolean value. If we set this parameter to True then it'll not let us modify mails inside of the mailbox. If set to False then it'll let us modify messages. If we set this parameter to False and retrieve mails from the mailbox then it'll be marked as read if it’s not read yet.
  2. 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.

Then, it 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 + '"'
        if directory_name == '"[Gmail]"':
            continue
        try:
            resp_code, mail_count = imap_ssl.select(mailbox=directory_name, readonly=True)
            print("{} - {}".format(directory_name, mail_count[0].decode()))
        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()
Connection Object : <imaplib.IMAP4_SSL object at 0x7fefa7f9c668>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Response Code : OK
========= List of Directories =================

(\HasNoChildren) "/" "ELITMUS"
(\HasNoChildren) "/" "ELITMUS_3"
(\HasNoChildren) "/" "INBOX"
(\HasNoChildren) "/" "Personal"
(\HasNoChildren) "/" "Receipts"
(\HasNoChildren) "/" "Work"
(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"

=========== Mail Count Per Directory ===============

"ELITMUS" - 63
"ELITMUS_3" - 0
"INBOX" - 6024
"Personal" - 5
"Receipts" - 0
"Work" - 0
"[Gmail]/All Mail" - 9777
"[Gmail]/Drafts" - 2
"[Gmail]/Important" - 3441
"[Gmail]/Sent Mail" - 3749
"[Gmail]/Spam" - 15
"[Gmail]/Starred" - 58
"[Gmail]/Trash" - 0

8. Read Mails from Mailbox

As a part of our seventh example, we are demonstrating how we can retrieve mails from mailboxes using search() method.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python


> Important Methods of IMAP4_SSL Object

  1. search(charset, criterion) - This method searches mailbox based on criteria provided using criterion parameter. The criterion parameter accepts strings 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.

  2. fetch(message_set,message_parts) - This method accepts a string specifying a list of message ids and a string specifying message parts to retrieve for all messages.

    • The message_set accepts strings like 1:4 (retrieve mails from id 1 to 4), 1:4,6:10 (retrieve mails from id 1 to 4 and 6 to 10), 5 (retrieve mail with id 5), 5: (retrieve mail using id 5 till the end), 1,2,3 (retrieve mails with id 1,2 and 3), etc.
    • The message_parts parameter accepts string values like RFC822 (returns whole message), UID (unique identifier of the message), BODY (body of message), etc. We can provide more than one string separated by space.

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.

After establishing a connection, it "logs in" to the server and then selects ELITMUS as a mailbox.

Then, it "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 emails in the box. The number 1 represents the oldest mail and the maximum number represents the latest mail id.

From a list of mail ids, we take the last two mail ids and "retrieve mail contents" using 'fetch()' method. The mail contents are returned as bytes string and we need to convert them to human-readable format for looking at contents.

To "construct email message", we are creating an instance of 'EmailMessage' which is a wrapper class provided by 'email' module which is used to represent mails in Python. We can generate an instance of EmailMessage by calling message_from_bytes() method of email module. The method accepts a message represented as a bytes string as input and returns EmailMessage instance.

Once an email message is created, we are "printing various parts of the mail" like from, to, bcc, date, subject, and body. We are calling walk() method instance of EmailMessage to retrieve all parts of the message and print only part which is text.

The message can have multiple parts like audio, video, image, and attachments that we have ignored here, and printing only body text content.

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. It'll help you with handling various parts of mail other than body text.

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, mail_ids = imap_ssl.search(None, "ALL")

    print("Mail IDs : {}\n".format(mail_ids[0].decode().split()))

    ############### Display Few Messages for given Directory #############
    for mail_id in mail_ids[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 #######################
    imap_ssl.close()
Connection Object : <imaplib.IMAP4_SSL object at 0x7fefa7fc84e0>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Mail IDs : ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63']

================== Start of Mail [62] ====================
From       : eLitmus DoNotReply <elitmus.donotreply.fresher1@gmail.com>
To         : undisclosed-recipients:;
Bcc        : elitmus-jobs@googlegroups.com
Date       : Mon, 3 Jan 2022 19:31:13 +0530
Subject    : Onsitego | 12 LPA | 2022 batch | Bangalore
Body :
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi Friends,

Onsitego, India's leading after sales service provider is hiring 2022 batch
candidates.

Onsitego is on a mission to create one of the most sophisticated service
delivery platforms comprising a suite of Web & Mobile-based solutions

   - Rapidly grew to become India=E2=80=99s leading after-sales service pro=
================== End of Mail [62] ====================

================== Start of Mail [63] ====================
From       : eLitmus DoNotReply <elitmus.donotreply.fresher1@gmail.com>
To         : undisclosed-recipients:;
Bcc        : elitmus-jobs@googlegroups.com
Date       : Wed, 12 Jan 2022 20:02:09 +0530
Subject    : =?UTF-8?Q?Sinope_=7C_=E2=82=B9_11=2E5_LPA_=7C_Canada_=28Remote_for_now=29_=7C_20?=
	=?UTF-8?Q?22_=2F_21?=
Body :
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi Friends,

Sinope, the Canadian firm conceiving the smart houses of tomorrow, is
hiring for the role of Full Stack Web Developer.

   - Offers a wide variety of turnkey solutions including platform, gateway
   and smart devices that can be combined to already existing connected hom=
e
   - Includes developing smart thermostats, heating systems, lighting,
================== End of Mail [63] ====================

9. Create, Delete and Rename Mailboxes

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

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.


> Important Methods of IMAP4_SSL Instance

  1. create(mailbox) - This method creates a mailbox.
  2. delete(mailbox) - This method deletes a mailbox.
  3. rename(oldmailbox,newmailbox) - This method renames a mailbox.
  4. expunge() - This method permanently removes deleted items from the mailbox.

Our code for this example starts by establishing a connection to the server by creating an instance of IAP4_SSL.

We are then logged 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_4 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, response = 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, response = 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, response = imap_ssl.rename(oldmailbox="ELITMUS_2", newmailbox="ELITMUS_4")

    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, response = imap_ssl.expunge()

    print("\nResponse Code : {}".format(resp_code))
    print("Response      : {}".format(response[0].decode() if response[0] else None))

    ############# Close Selected Mailbox #######################
    imap_ssl.close()
Connection Object : <imaplib.IMAP4_SSL object at 0x7fefa7713f98>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Creating Mailbox : ELITMUS_2
Response Code : OK
Response      : Success

Response Code : OK
========= List of Directories =================

(\HasNoChildren) "/" "ELITMUS"
(\HasNoChildren) "/" "ELITMUS_2"
(\HasNoChildren) "/" "ELITMUS_3"
(\HasNoChildren) "/" "INBOX"
(\HasNoChildren) "/" "Myntra"
(\HasNoChildren) "/" "Personal"
(\HasNoChildren) "/" "Receipts"
(\HasNoChildren) "/" "Work"
(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"

Deleting Mailbox : Myntra
Response Code : OK
Response      : Success

Response Code : OK
========= List of Directories =================

(\HasNoChildren) "/" "ELITMUS"
(\HasNoChildren) "/" "ELITMUS_2"
(\HasNoChildren) "/" "ELITMUS_3"
(\HasNoChildren) "/" "INBOX"
(\HasNoChildren) "/" "Personal"
(\HasNoChildren) "/" "Receipts"
(\HasNoChildren) "/" "Work"
(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"

Renaming Mailbox : ELITMUS_2
Response Code : OK
Response      : Success

Response Code : OK
========= List of Directories =================

(\HasNoChildren) "/" "ELITMUS"
(\HasNoChildren) "/" "ELITMUS_3"
(\HasNoChildren) "/" "ELITMUS_4"
(\HasNoChildren) "/" "INBOX"
(\HasNoChildren) "/" "Personal"
(\HasNoChildren) "/" "Receipts"
(\HasNoChildren) "/" "Work"
(\HasChildren \Noselect) "/" "[Gmail]"
(\All \HasNoChildren) "/" "[Gmail]/All Mail"
(\Drafts \HasNoChildren) "/" "[Gmail]/Drafts"
(\HasNoChildren \Important) "/" "[Gmail]/Important"
(\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
(\HasNoChildren \Junk) "/" "[Gmail]/Spam"
(\Flagged \HasNoChildren) "/" "[Gmail]/Starred"
(\HasNoChildren \Trash) "/" "[Gmail]/Trash"

Finalizing changes...

Response Code : OK
Response      : None

10. Copy Mails From Directory to Another

As a part of the ninth example, we'll explain how we can copy emails from one directory to another using copy() method of IMAP4_SSL instance.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python


> Important Methods of IMAP4 / IMAP4_SSL Instance

  1. copy(message_set,new_mailbox) - It accepts message_set specifying ids of emails from selected mailbox and copies those mails to new_mailbox mailbox. The message_set parameter works exactly same as it works with fetch() method.

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 again 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] ## Copying first two mails

    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()
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c1e4ee0>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Mail IDs : ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32']


Copying few mails of ELITMUS to different directory....
31:32
Response Code : OK
Response      : [COPYUID 626162797 1591,1598 4,8] (Success)

Copying few mails of ELITMUS to different directory....
Response Code : OK
Response      : [COPYUID 626162797 1480 6] (Success)
Response Code : OK
Response      : [COPYUID 626162797 1525 7] (Success)

Closing selected mailbox....

11. Search for Mails Matching a Pattern in a Mailbox

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.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

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 emails 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": ## Only Printing Text of mail. It can have attachements
                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": ## Only Printing Text of mail.
                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()
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c61f460>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Total Mail IDs : 40

================== Start of Mail [3010] ====================
From       : "Neil Patel" <np@neilpatel.com>
To         : "Sunny" <mail2sunny.2309@gmail.com>
Bcc        : None
Date       : Tue, 23 Feb 2021 14:13:33 +0000 (UTC)
Subject    : Today's the day I teach you marketing
Body :
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Mime-Version: 1.0

I hope you are excited because my marketing summit starts today,
where my team and I teach you marketing.
================== End of Mail [3010] ====================

================== Start of Mail [3033] ====================
From       : "Neil Patel" <np@neilpatel.com>
To         : "Sunny" <mail2sunny.2309@gmail.com>
Bcc        : None
Date       : Sat, 27 Feb 2021 16:24:04 +0000 (UTC)
Subject    : This is what's changing in marketing
Body :
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Mime-Version: 1.0

Advertising is getting more expensive, regulations are more
strict, and marketing is changing.
================== End of Mail [3033] ====================

Total Mail IDs : 13

================== Start of Mail [2829] ====================
From       : Medium Daily Digest <noreply@medium.com>
To         : mail2sunny.2309@gmail.com
Bcc        : None
Date       : Thu, 28 Jan 2021 02:30:00 +0000 (UTC)
Subject    : Reproducible Experiments with Jupyter Notebooks and Guild AI |
 Garrett Smith in Towards Data Science
Body :
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=utf-8
Mime-Version: 1.0

From your following

================== End of Mail [2829] ====================

================== Start of Mail [3031] ====================
From       : "Medium Daily Digest" <noreply@medium.com>
To         : mail2sunny.2309@gmail.com
Bcc        : None
Date       : Sat, 27 Feb 2021 01:30:00 +0000 (UTC)
Subject    : The new age of Jupyter widgets | Dimitris Poulopoulos in Towards Data Science
Body :
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Mime-Version: 1.0

From your following

================== End of Mail [3031] ====================


Closing selected mailbox....

12. Delete Mails from Mailbox

As a part of our eleventh example, we'll demonstrate how we can delete mails from the mailbox using store() method by changing flags.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python


> Important Methods of IMAP4 / IMAP4_SSL Instance

  1. store(message_set,command,flag_list) - This method changes flat details for give set of mail ids.
    • message_set - This parameter works exactly like it works for fetch() and copy() methods.
    • command - This method accepts one of the three arguments (FLAGS, +FLAGS, -FLAGS). The FLAGS indicates replacing existing flags. The +FLAGS indicates adding new flags to existing ones. The -FLAGS indicates to remove flags from existing flags.
    • flag_list - This parameter accepts flags separated by space that will be replaced, added, or removed from mail data based on the value of command parameter. It accepts flags like (\Seen, \Answered, \Flagged, \Deleted, \Draft, \Recent)

Below mentioned RFC has very detailed explanations of flags.

  1. RFC-2060

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 emails will be deleted. The 'store()' method will set a flag indicating that these emails need to be deleted.

Once flags are modified for two mail ids, we are calling expunge() method which will permanently delete both mails.

NOTE

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') ## Setting Deleted Flag
        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() if response[0] else None))

    ############# Close Selected Mailbox #######################
    print("\nClosing selected mailbox....")
    imap_ssl.close()
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c1e4d00>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Total Mail IDs : 40

Deleting Mails...
Mail ID : 1978, Date : Tue, 07 Jul 2020 13:30:46 +0000 (UTC), Subject : SEO Pack: 21 Worksheets, Templates, and Cheat Sheets
Response Code : OK
Response      : 1978 (FLAGS (\Seen \Deleted))

Mail ID : 2012, Date : Sat, 11 Jul 2020 14:29:35 +0000 (UTC), Subject : How to Market on Amazon
Response Code : OK
Response      : 2012 (FLAGS (\Seen \Deleted))

Response Code : OK
Response      : 1978


Closing selected mailbox....

13. Flag Mails as Important (Starred)

As a part of our twelfth example, we are demonstrating how we can mark the mail as important (starred) using store() method.

imaplib - Simple Guide to Manage Mailboxes (Gmail, Yahoo, etc) using Python

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 emails 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 emails 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 emails (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()
Connection Object : <imaplib.IMAP4_SSL object at 0x7f848c64ce80>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Total Mail IDs : 3070

Flagging Important Mails...
Mail ID : 3066, Date : Mon, 01 Mar 2021 06:50:58 -0800 (PST), Subject : Test Email
Response Code : OK
Response      : 3066 (FLAGS (\Seen \Flagged))

Mail ID : 3067, Date : Mon, 1 Mar 2021 15:47:01 +0000, Subject : =?UTF-8?Q?Sunny_Solanki,_here_are_toda?=
 =?UTF-8?Q?y=E2=80=99s_highlights:_markets_ended?=
 =?UTF-8?Q?_green,_Feb_auto_sales,_gold_bonds_tranche_12_open,_&_more?=
Response Code : OK
Response      : 3067 (FLAGS (\Seen \Flagged))

Mail ID : 3068, Date : Mon, 01 Mar 2021 12:03:51 -0800, Subject : Google Cloud Platform & APIs: Your invoice is available for 012B9E-8BAD8E-73B348
Response Code : OK
Response      : 3068 (FLAGS (\Seen \Flagged))

Mail ID : 3069, Date : Mon, 01 Mar 2021 16:45:47 -0600, Subject : You wrote a ton! Way to go!
Response Code : OK
Response      : 3069 (FLAGS (\Seen \Flagged))

Mail ID : 3070, Date : Tue, 02 Mar 2021 02:30:00 +0000 (UTC), Subject : Improve visualization readability with meaningful text and annotations | Jan Majewski in Towards Data Science
Response Code : OK
Response      : 3070 (FLAGS (\Seen \Flagged))

Unflagging few Mails...
Mail ID : 3069, Date : Mon, 01 Mar 2021 16:45:47 -0600, Subject : You wrote a ton! Way to go!
Response Code : OK
Response      : 3069 (FLAGS (\Seen))

Mail ID : 3070, Date : Tue, 02 Mar 2021 02:30:00 +0000 (UTC), Subject : Improve visualization readability with meaningful text and annotations | Jan Majewski in Towards Data Science
Response Code : OK
Response      : 3070 (FLAGS (\Seen))


Closing selected mailbox....

14. No Operation to Keep Connection Alive

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.


> Important Methods of IMAP4 / IMAP4_SSL Instance

  • noop() - It sends NOOP command to the mail server.

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()))
Connection Object : <imaplib.IMAP4_SSL object at 0x7f34e6262550>
Logging into mailbox...
Response Code : OK
Response      : mail2sunny.2309@gmail.com authenticated (Success)

Response Code : OK
Response      : Success

This ends our small tutorial explaining how we can use IMAP4 protocol through 'imaplib' Python library to perform various operations with a mailbox.

References

How to send mails using Python?

How to Represent Mail with Different Types (text, HTML, attachments, etc) of Data in Python?

How to Determine MIME Type Of an Attachment File in Python?

Sunny Solanki  Sunny Solanki

Share Views Stuck Somewhere? Need Help with Coding? Have Doubts About the Topic/Code?

When going through coding examples, it's quite common to have doubts and errors.

If you have doubts about some code examples or are stuck somewhere when trying our code, send us an email at coderzcolumn07@gmail.com. We'll help you or point you in the direction where you can find a solution to your problem.

You can even send us a mail if you are trying something new and need guidance regarding coding. We'll try to respond as soon as possible.

Share Views Want to Share Your Views? Have Any Suggestions?

If you want to

  • provide some suggestions on topic
  • share your views
  • include some details in tutorial
  • suggest some new topics on which we should create tutorials/blogs
Please feel free to contact us at coderzcolumn07@gmail.com. We appreciate and value your feedbacks. You can also support us with a small contribution by clicking DONATE.