I wrote some python code that does the following:
My code works as described but seems to crash when it iterates through the emails (or maybe dates), only extracting 4 out of the 30 or so reports I need. A copy of the code is below.
When it crashes, Vs Code is telling me the issue is on line 54 "outlook.GetNamespace.Quit()" and advising that it is "AttributeError: GetNamespace.Getnamespace"
Any thoughts and insight into this issue, would be greatly appreciated.
import os
import win32com.client
import datetime as dt
from datetime import date, timedelta
from pathlib import Path
EMAIL_ADDRESS = "emailaddress@example.com"
FOLDER_NAME = "subfolder_name"
OUTPUT_FOLDER = Path(r"Specify Path") #specify the path
def connect_to_outlook():
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace ("MAPI")
inbox_folder = outlook.GetDefaultFolder(6) # Inbox folder
sub_folder = inbox_folder.Folders(FOLDER_NAME)
return sub_folder, outlook, inbox_folder, outlook
def extract_csv_attachments(emails):
csv_attachments = [(email.Subject.split("[INSERT TEXT TO PARSE/SPLIT")[0].strip(), attachment)
for email in emails
for attachment in email.Attachments if attachment.FileName == "report.csv"]
return csv_attachments
try:
# Connect to Outlook
sub_folder, outlook, inbox_folder, outlook = connect_to_outlook()
# Get target date from user input
target_date_str = input("Enter a target date (YYYY-MM-DD): ")
target_date = dt.datetime.strptime(target_date_str, '%Y-%m-%d')
# Construct search criteria and filter emails
search_criteria = f'[SenderEmailAddress] = "{EMAIL_ADDRESS}" AND [ReceivedTime] >= "{target_date.strftime("%m/%d/%Y")}" AND [ReceivedTime] < "{(target_date + dt.timedelta(days=1)).strftime("%m/%d/%Y")}"'
filtered_emails = sub_folder.Items.Restrict(search_criteria)
# Extract CSV attachments from filtered emails
csv_attachments = extract_csv_attachments(filtered_emails)
# Save extracted attachments to output folder
for email_subject, attachment in csv_attachments:
attachment.SaveAsFile(OUTPUT_FOLDER / f"{email_subject}.csv")
finally:
# Release Outlook resources
sub_folder = None
inbox_folder = None
outlook.GetNamespace.Quit()
outlook.Quit()
Use Application.Quit
method - there is no Namespace.Quit
method.
Also keep in mind that most end users won't appreciate their Outlook closing on them: Outlook is a singleton, and creating an instance of the Outlook.Application
object will return a pointer to the already running instance. If it is your code that created Outlook.Application
object, there is no reason to call Application.Quit
- Outlook will exit when your code reference to it is gone. If you really want to close it, at least check to make sure that both Application.Explorers.Count == 0
and Application.Inspectors.Count == 0
to ensure there are no open windows opened by the user.