Search code examples
pythonoutlookexchange-serverwin32commapi

python win32com bulk reading outlook emails - too many open items


i'm facing some issues while trying to fetch a bulk mail via python wincom32.client.

Basically, it seems like there's a limit on the number of items that could be opened on a single session, and that is a server-side flag or status.. the problem is that i didn't find out any way to resume/close/re-set and i can't ask for sysadmins to do it for me..

Here's my code snippet - i know it's ugly - but i'm using it on a jupiter notebook just to experiment/play around before arranging it down properly.

import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")

def create_message_list(folder):
    return [{
        "folder": folder.Name,
        "sender" : m.Sender,
        "recipients" : m.Recipients,
        "subject" : m.subject, 
        "body":m.body
        } for m in folder.Items]

for folder in outlook.Folders:
    if (folder.Name=="myfolder.name"):
        message_list = create_message_list(folder)

and here's what i get:

com_error: (-2147352567, 'Exception occurred.', (4096, 'Microsoft Outlook', 'Your server administrator has limited the number of items you can open simultaneously. Try closing messages you have opened or removing attachments and images from unsent messages you are composing.', None, 0, -2147220731), None).

Notice that i had my sketch code working for a while. i could fetch something like 10k messages before it messed up with that error.

Things i've been trying (with no result) - try to close the folder / mapi session - running a for loop on the same items and calling the message.Close(0) - using the GetFirst() / GetLast() methods on message instead of list comprehension

thanks anyone for ideas/suggestions/whatever.


Solution

  • the problem was due to using dictionary to store message data held somehow a reference to it, without letting the resource to be released, even if an explicit m.Close(0) was invoked.

    I've replaced them all with a "dictkey" : str(m.<field>) call and the error does not show up anymore.