Exchangelib Scan All Folders – Efficiency

Tags: ,



I am using exchangelib to connect to my exchange mailbox. Currently the code is scanning through all folders since the target email message can be in any of the folders for my task.

Is there a more efficient way for looping/scanning the folders here? (Looking for emails greater than a target start date)

 folder = account.root
        all_folders = folder.glob('**/*')
        for folder in all_folders:
            if folder.folder_class == 'IPF.Note': #Messages can only exist in 'IPF.Note' folder classes
                for email in folder.filter(datetime_received__gt=ews_bfr): #For all emails that are newer than the target date

Edit: Thanks for the help, Erik. This worked and made the run time increase dramatically:

        target_folders = FolderCollection(account=account, folders=(f for f in account.root.walk() if f.name in ['xxxxxx']))
            .filter(datetime_received__gt=ews_bfr)
        for email in target_folders:

Answer

A normal .filter() works on just the folder you call it on. EWS does not support searching items within all folders, but only the folders explicitly mentioned in the FindItems service call.

In exchangelib, the way to filter on multiple folders in one go is to use a FolderCollection:

from exchangelib import FolderCollection
FolderCollection(account=account, folders=[...]).filter(some_field='foo')

The folders argument can be any iterable of folders, e.g. [account.inbox, account.sent], account.root.walk() or (f for f in account.root.walk() if f.CONTAINER_CLASS == 'IPF.Note')

.glob(), .walk(), .children and other subfolder access methods also support calling .filter() on them:

account.root.glob('**/*').filter(datetime_received__gt=ews_bfr)
account.root.walk().filter(datetime_received__gt=ews_bfr)


Source: stackoverflow