Python imaplib

IMAP, or Internet Message Access Protocol, is a protocol used by email clients to retrieve and manage emails from a mail server. Unlike POP3, which downloads emails and often removes them from the server, IMAP allows users to view and manage their emails directly on the server. This means that changes made on one device, like marking an email as read or moving it to a folder, are reflected across all devices accessing that email account.

Key features of IMAP include:

1. Synchronization: Keeps emails and folders synchronized across multiple devices.
2. Folder Support: Allows users to organize emails into folders on the server.
3. Selective Downloading: Users can choose which emails to download and read, saving bandwidth.

IMAP is widely supported by most email services and is ideal for users who access their email from multiple devices.

The imaplib library in Python enables interaction with IMAP email servers for retrieving, managing, and deleting emails securely.

1. Install Dependencies

We can use the built-in imaplib and email libraries, so no additional installation is required.

2. Connect to IMAP Server

The following code demonstrates how we can connect to IMAP server using SSL.
import imaplib

# Connection details
username = "your_email@example.com"
password = "your_password"
imap_server = "imap.example.com"

# Connect to the IMAP server using SSL
mail = imaplib.IMAP4_SSL(imap_server)
mail.login(username, password)
print("Connected to the IMAP server.")

Output:

Connected to the IMAP server.

3. List Mailboxes

The following code demonstrates how we can list all the mailboxes.
# List all mailboxes
status, mailboxes = mail.list()
if status == 'OK':
    print("Mailboxes:")
    for mailbox in mailboxes:
        print(mailbox.decode())
else:
    print("Failed to retrieve mailboxes.")

Output:

Mailboxes:
* OK [UIDNEXT 4] Predicted next UID
* LIST (\HasNoChildren) "/" "INBOX"
* LIST (\HasNoChildren) "/" "Sent"
* LIST (\HasNoChildren) "/" "Spam"

4. Select a Mailbox

The following code demonstrates how we can select a mailbox and check the total messages.
# Select the INBOX mailbox
status, message_count = mail.select("INBOX")
if status == 'OK':
    print(f"Selected mailbox: INBOX, Total Messages: {message_count[0].decode()}")
else:
    print("Failed to select mailbox.")

Output:

Selected mailbox: INBOX, Total Messages: 15

5. Search for Emails

The following code demonstrates how we can search for all unseen emails.
# Search for all unseen emails
status, email_ids = mail.search(None, 'UNSEEN')
if status == 'OK':
    email_id_list = email_ids[0].split()
    print(f"Unseen emails: {len(email_id_list)}")
else:
    print("Failed to search emails.")

Output:

Unseen emails: 3

6. Fetch an Email

The following code demonstrates how we can fetch the first unseen email.
import email
from email.header import decode_header

# Fetch the first unseen email
email_id = email_id_list[0]
status, email_data = mail.fetch(email_id, '(RFC822)')
if status == 'OK':
    raw_email = email_data[0][1]
    parsed_email = email.message_from_bytes(raw_email)
    
    # Print email details
    subject, encoding = decode_header(parsed_email["Subject"])[0]
    if isinstance(subject, bytes):
        subject = subject.decode(encoding or 'utf-8')
    print("Subject:", subject)
    print("From:", parsed_email.get("From"))
    
    # Print email body
    if parsed_email.is_multipart():
        for part in parsed_email.walk():
            content_type = part.get_content_type()
            content_disposition = str(part.get("Content-Disposition"))
            if content_type == "text/plain" and "attachment" not in content_disposition:
                body = part.get_payload(decode=True).decode()
                print("Body:", body)
    else:
        body = parsed_email.get_payload(decode=True).decode()
        print("Body:", body)
else:
    print("Failed to fetch email.")

Output:

Subject: Your Monthly Report
From: reports@example.com
Body: Hello, here is your monthly report as requested.

7. Mark Email as Seen (Read)

The following code demonstrates how we can mark an email as seen.
# Mark the email as seen
mail.store(email_id, '+FLAGS', '\\Seen')
print(f"Email ID {email_id.decode()} marked as seen.")

Output:

Email ID 5 marked as seen.

8. Deleting Emails

The following code demonstrates how we can mark an email for deletion.
# Mark email for deletion
mail.store(email_id, '+FLAGS', '\\Deleted')
print(f"Email ID {email_id.decode()} marked for deletion.")

# Permanently delete marked emails
mail.expunge()
print("Deleted emails expunged.")

Output:

Email ID 5 marked for deletion.
Deleted emails expunged.

9. Logging Out and Closing Connection

The following code demonstrates how we can logout and close the connection.
# Close the selected mailbox and log out
mail.close()
mail.logout()
print("IMAP session closed.")

Output:

IMAP session closed.

Full Example Script

Now, we will see the full example script of all the operations, we discussed above.
import imaplib
import email
from email.header import decode_header

# Connection details
username = "your_email@example.com"
password = "your_password"
imap_server = "imap.example.com"

# Connect and login
mail = imaplib.IMAP4_SSL(imap_server)
mail.login(username, password)
mail.select("INBOX")

# Search unseen emails
status, email_ids = mail.search(None, 'UNSEEN')
if status == 'OK':
    email_id_list = email_ids[0].split()
    if email_id_list:
        email_id = email_id_list[0]
        status, email_data = mail.fetch(email_id, '(RFC822)')
        raw_email = email_data[0][1]
        parsed_email = email.message_from_bytes(raw_email)
        
        # Print email details
        subject, encoding = decode_header(parsed_email["Subject"])[0]
        if isinstance(subject, bytes):
            subject = subject.decode(encoding or 'utf-8')
        print("Subject:", subject)
        print("From:", parsed_email.get("From"))
        
        # Print email body
        if parsed_email.is_multipart():
            for part in parsed_email.walk():
                content_type = part.get_content_type()
                content_disposition = str(part.get("Content-Disposition"))
                if content_type == "text/plain" and "attachment" not in content_disposition:
                    body = part.get_payload(decode=True).decode()
                    print("Body:", body)
        else:
            body = parsed_email.get_payload(decode=True).decode()
            print("Body:", body)

        # Mark email as seen
        mail.store(email_id, '+FLAGS', '\\Seen')

        # Delete email and expunge
        mail.store(email_id, '+FLAGS', '\\Deleted')
        mail.expunge()

# Close connection
mail.close()
mail.logout()
print("IMAP session closed.")

Output:

Subject: Your Monthly Report
From: reports@example.com
Body: Hello, here is your monthly report as requested.
IMAP session closed.
This tutorial offers a comprehensive set of commands for connecting, searching, retrieving, and managing emails securely using Python's imaplib.

Previous: Paramiko SFTP | Next: Python List

<
>