Win32 not recognising the outlook email in Jupyter notebook

Question:

Tried to read the outlook email in jupyter notebook for creating a ML algorithm but the win32 is not recognising my outlook account. It was working fine yesterday but somehow same code not wrking today.

Any suggestions please?

Attached my code below.

import win32com #.client
import pyttsx3
#other libraries to be used in this script
import os
from datetime import datetime, timedelta

outlook = win32com.client.Dispatch('outlook.application').GetNamespace("MAPI")
# mapi = outlook.GetNamespace("MAPI")
# mapi
# for account in outlook.Accounts:
#     print(account.DeliveryStore.DisplayName)
# account
# inbox = outlook.GetDefaultFolder(6) 
outlook.Accounts

The result I’m getting is
enter image description here

Asked By: Pravin

||

Answers:

The following line of code contains multiple method calls:

outlook = win32com.client.Dispatch('outlook.application').GetNamespace("MAPI")

So, I’d recommend splitting them by declaring each method call on a separate line of code:

outlook = win32com.client.Dispatch('outlook.application')
nameSpaceObj = outlook.GetNamespace("MAPI")

Following that way you can find which method exactly gives the error (if any).

Sometimes you need to get the standard folder first (for example, Inbox) to get MAPI subsystems initialized:

inbox = nameSpaceObj.GetDefaultFolder(6)

Another possible cause is already running Outlook instance. In that case you need to try to retrieve the running instance on the system. Use the GetObject function instead:

outlook = win32com.client.GetObject('outlook.application')

You can’t run two instances of Outlook at the same time on the computer.

Answered By: Eugene Astafiev

I’ve hit something similar in this question.

EDIT: An update. It seems that the Python iter(obj) function implicit in the for loop is not necessarily calling obj.__iter__() but calls instead obj.__class__.__iter__(obj) and this isn’t working properly for some reason (I read this in an SO answer that I have lost), so one solution is to call __iter__() directly.

eg this works:

import win32com.client
ns = win32com.client.Dispatch('outlook.application').GetNamespace("MAPI")

accs = ns.Accounts
for ac in accs.__iter__():
    print(ac.DisplayName)

//EDIT

The issue seems to be that all of a sudden the Collection objects are not iterable when they should be. For example:

import win32com.client
ns = win32com.client.Dispatch('outlook.application').GetNamespace("MAPI")
accs = ns.Accounts

then:

accs.Count

returns 1 (I have one account)

But this subsequent code:

for ac in accs:
    print(ac.DisplayName)

gives this error:

TypeError                                 Traceback (most recent call last)
Cell In [20], line 1
----> 1 for ac in accs:
      2     print(ac.DisplayName)

TypeError: 'Accounts' object is not iterable

If you don’t use the generator, but iterate by (1-based) index:

accs = ns.Accounts
for n in range(1,accs.Count+1):
    ac = accs.Item(n)
    print(ac.DisplayName)

you get a list of accounts as expected.

I did raise a bug-report for win32com here but I am not sure anything happened. Interestingly I don’t get this issue with the Folders collection, eg

fldrs = ns.Folders
for f in fldrs:
    print(f.Name)

works as expected.

So the workaround is to use explicit indexing using the Item() method of the collection.

EDIT: You can also try deleting everything in your %APPDATA%LocalTempgen_pyx.x folder (where x.x is the Python version) and re-trying.

Answered By: DS_London