Fetching multiple IMAP messages at once

Dan Benamy picture Dan Benamy · Aug 27, 2010 · Viewed 7.2k times · Source

The examples I've seen about loading emails over IMAP using python do a search and then for each message id in the results, do a query. I want to speed things up by fetching them all at once.

Answer

Dan Benamy picture Dan Benamy · Aug 27, 2010

RFC 3501 says fetch takes a sequence set, but I didn't see a definition for that and the example uses a range form (2:4 = messages 2, 3, and 4). I figured out that a comma separated list of ids works. In python with imaplib, I've got something like:

    status, email_ids = con.search(None, query)
    if status != 'OK':
        raise Exception("Error running imap search for spinvox messages: "
                        "%s" % status)

    fetch_ids = ','.join(email_ids[0].split())
    status, data = con.fetch(fetch_ids, '(RFC822.HEADER BODY.PEEK[1])')
    if status != 'OK':
        raise Exception("Error running imap fetch for spinvox message: "
                        "%s" % status)
    for i in range(len(email_ids[0].split())):
        header_msg = email.message_from_string(data[i * 3 + 0][1])
        subject = header_msg['Subject'],
        date = header_msg['Date'],
        body = data[i * 3 + 1][1] # includes some mime multipart junk