Search code examples
pythonpython-3.xemailimapemail-attachments

PermissionError: [Errno 13] Permission denied when downloading email attachment


I'm using reference from here to download attachments from email. This is the code:

import os
from imbox import Imbox # pip install imbox
import traceback

# enable less secure apps on your google account
# https://myaccount.google.com/lesssecureapps

host = "imap.gmail.com"
username = "username"
password = 'password'
download_folder = "D:/PreProject/email_auto/attachments"

if not os.path.isdir(download_folder):
    os.makedirs(download_folder, exist_ok=True)
    
mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=None, starttls=False)
messages = mail.messages() # defaults to inbox

for (uid, message) in messages:
    mail.mark_seen(uid) # optional, mark message as read

    for idx, attachment in enumerate(message.attachments):
        try:
            att_fn = attachment.get('filename')
            download_path = f"{download_folder}/{att_fn}"
            print(download_path)
            with open(download_path, "wb") as fp:
                fp.write(attachment.get('content').read())
        except:
            print(traceback.print_exc())

mail.logout()

But when I running it, I got problems. This error shows up:

Traceback (most recent call last):
  File "app.py", line 27, in <module>
    with open(download_path, "wb") as fp:
PermissionError: [Errno 13] Permission denied: 'D:/PreProject/email_auto/attachments/'

The code still running with that error message shows up. I already tried about changing folder permission on user, still no good result. But about 5 minutes later when the code still running, all attachment on the email successfully downloaded to the directory then it stopped, either I'm changed the folder permission or make it to default settings.

The code works, yes. But it's not well executed and I'm afraid will be problems in the future.

Any help would be appreciated.


Solution

  • First thanks to @BoarGules and @Max for the comments. But my problem solved after I add unread=True parameters so it will only download attachments from unread email and exactly what I want. I changed this:

    messages = mail.messages()
    

    To this:

    messages = mail.messages(unread=True)
    

    Attachments downloaded quickly after the code is running. I didn't change other thing like directory path, etc. It's still not clear why, but for now I got what I want.