This blog is available for sale. More than 150 published articles. Please 'contact us' if interested.
Advertise with us
automation email   1   26425
Accessing Gmail Inbox using Python imaplib module

For accessing the Gmail inbox and reading emails, we will be using imaplib python module. To connect to the Gmail server, we need the below information.

- SMTP server DNS. Its value will be '' in our case.
- SMTP server port. The value will be 993. This port is used for Internet message access protocol over TLS/SSL.

Getting Gmail App Password:

Gmail won't allow external applications to access the Inbox with the Google account password. For accessing Gmail Inbox, we need to create an application and create a passphrase for that application.

Go to your Google account -> security -> Signing in to Google -> App Password. Create a new App and copy the password.

gmail app password

Click on the 'Generate' button and a new password will be generated for you to use in your python script. This password will let us access the emails from Gmail.

generated password gmail app

Copy and paste this password in a separate text file. Do not use the password directly in the main Python script.

Creating mail client:

import imaplib

def get_mail_client(email_address):

password = ""
with open("password.txt", "r") as f:
password =

mail = imaplib.IMAP4_SSL(SMTP_SERVER)
mail.login(email_address, password)
return mail

In the line mail = imaplib.IMAP4_SSL(SMTP_SERVER), if the server is omitted, the localhost is used by default. If the port is omitted, 993 is used by default.

Fetching emails from Folders:

To access a specific folder, we need to select that folder. For example to search emails in the Inbox folder, select the Inbox folder.'INBOX')

To search the Spam folder,'[Gmail]/Spam')

We can search for specific category (Promotional / Updates / Forums) in Inbox.

def get_top_10_emails(category):
# category can be 'Promotional, Updates or Forums # returns tuple
status, response = mail.uid('search', 'X-GM-RAW "category:' + category + '"')

# get email ids list
response = response[0].decode('utf-8').split()
response = response[:min(10, len(response))]
return response

The above function will return a list of uid of the first 10 emails in the specified category in the Inbox folder. These uids are the universal identifier for an email. Even if an email is deleted, the uid of remaining mails remains the same. This is different from email Id which we will see after it.

Now we can iterate over this list to fetch email details.

for uid in get_top_1o_emails(category):
status, data = mail.uid('fetch', uid, '(RFC822)')
msg = get_msg_object(data) print(msg)

mail.uid('fetch', uid, '(RFC822)') function return a list of tuples. Each tuple contains the byte objects. get_msg_object iterate over the items in the list and pick the second item from the tuple. Now using the message_from_bytes method of the email module, the message object is returned.

import email

def get_msg_object(data):
for response_part in data:
if isinstance(response_part, tuple):
return email.message_from_bytes(response_part[1])

When msg is printed, the output will be as below.

Received: by 4567:123:123:123:0:0:0:0 with SMTP id 21dfr2888589nju;
        Sat, 17 Oct 2020 22:04:41 -0700 (PDT)
X-Received: by xxxx:xxx:xxxx:: with SMTP id q129xxxxxxxxxx.13.160xxxxxxxx04;
        Sat, 17 Oct 2020 22:04:41 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1602997481; cv=none;; s=arc-20160816;
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;; s=arc-20160816;
ARC-Authentication-Results: i=1;;
       dkim=pass header.s=20161025 header.b=jHcNbSwC;
       spf=pass ( domain of designates as permitted sender);
       dmarc=pass (p=REJECT sp=REJECT dis=NONE)
Return-Path: <>
Received: from ( [])
        by with SMTPS id k184sor1479766vsk.94.2020.
        for <>
        (Google Transport Security);
        Sat, 17 Oct 2020 22:04:41 -0700 (PDT)
Received-SPF: pass ( domain of designates as permitted sender) client-ip=;
       dkim=pass header.s=20161025 header.b=jHcNbSwC;
       spf=pass ( domain of designates as permitted sender);
       dmarc=pass (p=REJECT sp=REJECT dis=NONE)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025;
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025;
X-Gm-Message-State: AOAM530j8mOsvWgyElljWsqH1qqyt+xxxxxx/GtDkY0nrnmvYnGVzr
X-Google-Smtp-Source: ABdhPJyBHNYWZ9UYMgsSI/xxxxxxxxxxxx+v2m4CN2Rdm/hEq1e/nhkvW+LpFOuWg4v5pNCnA==
MIME-Version: 1.0
X-Received: by 2002:a67:edcb:: with SMTP id xxxxxxxxx.11.1602997481361;
 Sat, 17 Oct 2020 22:04:41 -0700 (PDT)
Date: Sun, 18 Oct 2020 05:04:40 GMT
X-Account-Notification-Type: 20
Feedback-ID: 20:account-notifier
X-Notifications: xxxxxxxxxxx
Message-ID: <>
Subject: App password created
From: Google <>
Content-Type: multipart/alternative; boundary="00000000000073d34005b1eaef17"

Content-Type: text/plain; charset="UTF-8"; format=flowed; delsp=yes
Content-Transfer-Encoding: base64

-------------- CONTENT REMOVED ---------------------------------------------
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE html><html lang=3D"en"><head><meta name=3D"format-detection" cont=
ent=3D"email=3Dno"/><meta name=3D"format-detection" content=3D"date=3Dno"/>=
<style nonce=3D"xxxxxxxxxxxx">.awl a {color: #FFFFFF; text-decora=
tion: none;} .abml a {color: #000000; font-family: Roboto-Medium,Helvetica,=
------------ CONTENT REMOVED -----------------------------------------------
USA</div></td></tr></table></td></tr></table></td></tr></table></td><td wid=
th=3D"32" style=3D"width: 32px;"></td></tr><tr height=3D"32" style=3D"heigh=
t: 32px;"><td></td></tr></table></body></html>

Searching Spam folder:

# search in spam'[Gmail]/Spam')
print("Looking in Spams")
id_list = get_email_ids(mail, "[Gmail]/Spam", max_mails_to_look=50)
for email_id in id_list:
msg = get_email_msg(email_id)

get_email_ids function will return a list of email ids in reverse order i.e. recent email first.

def get_email_ids(mail, label='INBOX', criteria='ALL', max_mails_to_look=10):
type, data =, criteria)
mail_ids = data[0]
id_list = mail_ids.split()
# revers so that latest are at front
id_list = id_list[: min(len(id_list), max_mails_to_look)]
return id_list

Please note that id_list is not a list of uid. These ids or message number can change if an email is deleted. Hence it is always recommended to work with uid.

get_email_msg will return the message detail for each message number.

import email

def get_email_msg(email_id):
email_id = str(int(email_id))
type, data = mail.fetch(str(email_id), '(RFC822)')
for response_part in data:
if isinstance(response_part, tuple):
return email.message_from_bytes(response_part[1])

Getting headers from the message:

We can fetch any header from a message using the get method. To get the SPF, DMARC, and DKIM details from message headers, first, get the Authentication-Results header.

auth_results = msg.get("Authentication-Results", None)

auth_results will contain the below data. 

       dkim=pass header.s=20161025 header.b=jHcNbSwC;
       spf=pass ( domain of designates as permitted sender);
       dmarc=pass (p=REJECT sp=REJECT dis=NONE)

Now we can parse this string to get the DKIM, SPF and, DMARC results.

Similarly, we can check if the unsubscribe header is present in the message.

def is_unsubscribe_present(msg):
return "List-Unsubscribe" in msg.keys()

Searching by subject:

To search an email by subject we can iterate over the emails and then get the subject of each email. Compare the subject of each email with the expected subject.

def search_by_subject(email_ids_list, subject_substring):
for email_id in email_ids_list:
msg = get_email_msg(email_id)
if "Subject" in msg.keys():
subject = msg.get("Subject", "")
if subject_substring.lower() in subject.lower():
return msg

return None

- Here is a list of some awesome python books
Host your Django Application for free on PythonAnyWhere.
- If you want full control of your application and server, you should consider 
- Create a
 DigitalOcean account with this link and get $100 credits.

Photo by Krsto Jevtic on Unsplash
automation email   1   26425
1 comment on 'Accessing Gmail Inbox Using Python Imaplib Module'
Login to comment

Simon Bingham June 20, 2021, 6:44 p.m.
Thanks so much, but I could not get to work just kept getting a auth error back File "", line 13, in get_mail_client mail.login(email_address,password) File "/usr/lib64/python3.6/", line 598, in login raise self.error(dat[-1])imaplib.error: b'[ALERT] Invalid credentials (Failure)'

Related Articles:
Django application to automate the WhatsApp messaging
Django application with REST API endpoints to automate the WhatsApp messaging. Automating WhatsApp web using selenium to send messages. Using selenium to automate whatsapp messaging. Sending bulk messages via whatsapp using automation. Source code Django application Whatsapp Automation...
Automating WhatsApp web using selenium to send messages
Automating WhatsApp web using selenium to send messages. Using selenium to automate whatsapp messaging. Sending bulk messages via whatsapp using automation....
Automating PDF generation using Python reportlab module
Generating PDF using python reportlab module, Adding table to PDF using Python, Adding Pie Chart to PDF using Python, Generating PDF invoice using Python code, Automating PDF generation using Python reportlab module...
Automating Facebook page posts using python script
posting on facebook page using python script, automating the facebook page posts, python code to post on facebook page, create facebook page post using python script...
DigitalOcean Referral Badge

© 2022-2023 Python Circle   Contact   Sponsor   Archive   Sitemap