Viewing content of outlook attachment in python

Question:

I’m trying to use python to get some data that is in an attachment on an outlook email and then use that data in python. I’ve managed to write the code that will get into the outlook inbox and folder I want and then get the attachments of a specific message, however I’m not sure how to view the content of that attachment. A lot of the other questions and tutorials I’ve found seem to be more related to saving the attachment in a folder location rather than viewing the attachment in python itself.

For context the data I’m trying to get to is an exported report from adobe analytics, this report is a csv file that is attached to an email as a zip file. The CSV file shows some data for a specific time period and I’m planning on scheduling this report to run weekly so what I want to do is get python to look through all the emails with this report on then stack all this data into one dataframe so that I have all the history plus the latest week’s data in one place then export this file out.

Please find the code below that I’ve written so far. If you need more details or I haven’t explained anything very well please let me know. I am fairly new to python especially the win32com library so there might be obvious stuff I’m missing.

#STEP 1---------------------------------------------
#import all methods needed
from pathlib import Path
import win32com.client
import requests
import time
import datetime
import os
import zipfile
from zipfile import ZipFile
import pandas as pd


#STEP 2 --------------------------------------------
#connect to outlook
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")



#STEP 3 --------------------------------------------
#connect to inbox
inbox = outlook.GetDefaultFolder(6)


#STEP 4 --------------------------------------------
#connect to adobe data reports folder within inbox
adobe_data_reports_folder = inbox.Folders['Cust Insights'].Folders['Adobe data reports']



#STEP 5 --------------------------------------------
#get all messages from adobe reports folder
messages_from_adr_folder = adobe_data_reports_folder.Items



#STEP 6 ---------------------------------------------
#get attachement for a specific message (this is just for testing in real world I'll do this for all messages)
for message in messages_from_adr_folder:
    if message.SentOn.strftime("%d-%m-%y") == '07-12-22':
        attachment = message.Attachments
    else:
        pass


#STEP 7 ----------------------------------------------
#get the content of the attachment

##????????????????????????????
Asked By: Thomas Chamberlain

||

Answers:

With the Outlook Object Model, the best you can do is save the attachment as a file (Attachment.SaveAsFile) – keep in mind that MailItem.Attachments property returns the Attachments collection, not a single Attachment object – loop through all attachments in the collection, figure out which one you want (if there is more than one), and save it as file.

To access file attachment data directly without saving as a file, you will need to use Extended MAPI (C++ or Delphi only) or Redemption (any language, I am its author).

Dmitry mentioned below that there isn’t the option to view attachment content with an outlook object model.

So I’ve come up with a solution for this which basically involves using the save method to save the attachment into a folder location on the current working directory and then once that file is save just load that file back up into python as a dataframe. The only thing to note is that I’ve added an if statement that only saves files that are csvs, obviously this part can be removed if needed.

If you wanted to do this with multiple files and stack all of these into a single dataframe then I just created a blank dataframe at the start (with the correct column names of the file that will be loaded) and concatenated this blank dataframe with the "importeddata" then added this code into the "attachment" for loop so that each time it’s appending the data that is saved and loaded from the attachment

#STEP 1---------------------------------------------
#import all methods needed
from pathlib import Path
import win32com.client
import requests
import time
import datetime
import os
import zipfile
from zipfile import ZipFile
import pandas as pd

#STEP 1b ---------------------------------------------
#create a directory where I can save the files
output_dir = Path.cwd() / "outlook_testing"

#STEP 2 --------------------------------------------
#connect to outlook
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")



#STEP 3 --------------------------------------------
#connect to inbox
inbox = outlook.GetDefaultFolder(6)


#STEP 4 --------------------------------------------
#connect to adobe data reports folder within inbox
adobe_data_reports_folder = inbox.Folders['Cust Insights'].Folders['Adobe data 
reports']



#STEP 5 --------------------------------------------
#get all messages from adobe reports folder
messages_from_adr_folder = adobe_data_reports_folder.Items



#STEP 6 ---------------------------------------------
#get attachement for a specific message (this is just for testing in real world 
#I'll do this for all messages)
for message in messages_from_adr_folder:
    body = message.Body
    if message.SentOn.strftime("%d-%m-%y") == '07-12-22':
        attachments = message.Attachments
        for attachment in attachments:
            stringofattachment = str(attachment)
        
            #STEP 6b - if the attachment is a csv file then save the attachment to a folder
            if stringofattachment.find('.csv') != - 1:   
                attachment.SaveAsFile(output_dir / str(attachment))
                print(output_dir / str(attachment))
            
                #STEP 6C - reload the saved file as a dataframe
                importeddata = pd.read_csv(output_dir / str(attachment))
            else:
                print('NOT CSV')
                pass
    else:
        pass
Answered By: Thomas Chamberlain