How to Retrieve Emails Using IMAP in Python

A guide on retrieving emails using the IMAP protocol.


Harendra Verma

2 years ago | 5 min read

Good day there, In a recent piece, I discussed How to use Python SMTP to send emails?. It’s now time to start receiving emails via the IMAP protocol. But, before we begin, we must first understand IMAP, so let’s have a look.

What is IMAP?

IMAP stands for Internet Message Access Protocol, and it works similarly to SMTP in that it operates at the application layer via TCP/IP. Unencrypted connections utilize port 143, whereas encrypted connections use port 993.

Getting emails

POP Post Office Protocol is another option for this duty, but IMAP is preferable since it allows for greater synchronization between the client and the server, as well as access to more than just the email inbox.

Receiving emails is more difficult than sending them because you must additionally look for and understand the message:

Import packages

import email
import python-imap

We have to import these packages to use in our program.

Define credentials

EMAIL = ''
PASSWORD = 'password'

You have to define your Gmail email id and password(generate app password if you are using two-factor auth)

Create & use App Passwords

If you use 2-Step-Verification and get a “password incorrect” error when you sign in, you can try to use an App Password.

  1. Go to your Google Account.
  2. Select Security.
  3. Under “Signing in to Google,” select App Passwords. You may need to sign in. If you don’t have this option, it might be because:
  4. 2-Step Verification is not set up for your account.
  5. 2-Step Verification is only set up for security keys.
  6. Your account is through work, school, or other organizations.
  7. You turned on Advanced Protection.
  8. At the bottom, choose Select app and choose the app you using
  9. Select the device and choose the device you’re using
  10. Generate.
  11. Follow the instructions to enter the App Password. The App Password is the 16-character code in the yellow bar on your device.
  12. Tap Done.

Connect to the server and read inbox

mail = imaplib.IMAP4_SSL(SERVER)
mail.login(EMAIL, PASSWORD)'inbox')

Now we need to connect to the server by logging into the account with the email and password that we created before. When you pick the mailbox to read messages from, you may select whatever you want, such as spam, draught, or send, depending on your preferences.

Get emails

status, data =, 'ALL')
for block in data:
mail_ids += block.split()

We must now search for and pick email Ids from which to get emails; I am using None to select all emails from the inbox.

Fetch mail for each mail id

for i in mail_ids:
status, data = mail.fetch(i, '(RFC822)')

All emails for a certain email id are stored in the data variable.

Full code

import email
import python-imap

EMAIL = ''
PASSWORD = 'password'

# connect to the server and go to its inbox
mail = imaplib.IMAP4_SSL(SERVER)
mail.login(EMAIL, PASSWORD)
# we choose the inbox but you can select others'inbox')

# we'll search using the ALL criteria to retrieve
# every message inside the inbox
# it will return with its status and a list of ids
status, data =, 'ALL')
# the list returned is a list of bytes separated
# by white spaces on this format: [b'1 2 3', b'4 5 6']
# so, to separate it first we create an empty list
mail_ids = []
# then we go through the list splitting its blocks
# of bytes and appending to the mail_ids list
for block in data:
# the split function called without parameter
# transforms the text or bytes into a list using
# as separator the white spaces:
# b'1 2 3'.split() => [b'1', b'2', b'3']
mail_ids += block.split()

# now for every id we'll fetch the email
# to extract its content
for i in mail_ids:
# the fetch function fetch the email given its id
# and format that you want the message to be
status, data = mail.fetch(i, '(RFC822)')

# the content data at the '(RFC822)' format comes on
# a list with a tuple with header, content, and the closing
# byte b')'
for response_part in data:
# so if its a tuple...
if isinstance(response_part, tuple):
# we go for the content at its second element
# skipping the header at the first and the closing
# at the third
message = email.message_from_bytes(response_part[1])

# with the content we can extract the info about
# who sent the message and its subject
mail_from = message['from']
mail_subject = message['subject']

# then for the text we have a little more work to do
# because it can be in plain text or multipart
# if its not plain text we need to separate the message
# from its annexes to get the text
if message.is_multipart():
mail_content = ''

# on multipart we have the text message and
# another things like annex, and html version
# of the message, in that case we loop through
# the email payload
for part in message.get_payload():
# if the content type is text/plain
# we extract it
if part.get_content_type() == 'text/plain':
mail_content += part.get_payload()
# if the message isn't multipart, just extract it
mail_content = message.get_payload()

# and then let's show its result
print(f'From: {mail_from}')
print(f'Subject: {mail_subject}')
print(f'Content: {mail_content}')


How to generate credentials and start receiving emails using IMAP protocol” was described in the last instruction on getting emails with Gmail. I’m hoping you’ll enjoy it.

Thank you for reading this tutorial. If you have any doubt feel free to ask or provide your response and don’t forget to follow me. Happy coding!


Created by

Harendra Verma

Currently I am working as a Full-stack developer and I have expertise with Python, Angular , PHP, Node JS, Laravel, Codeigniter and Front end.







Related Articles