Python - Send an email with attachments


  1. End result. Email with 2 attachments. data1.csv, data2.csv

  2. Create an app password on Gmail.

  3. Make a new directory, cd into the folder and open VS code.

    $ mkdir python-send-email-with-attachments
    $ cd python-send-email-with-attachments
    $ code .
  4. Create a new virtual env and activate it on terminal within VS Code.

    $ python3 -m venv venv
    $ source venv/bin/activate
  5. Create file, .env file and data files for testing on the root directory.

    +-- .env
    +-- venv
    +-- data
        +-- data1.csv
        +-- data2.csv
  6. Open .env and add variables.
    EMAIL_PASSWORD=app password 16 characters;
  7. install dotenv library to use .env file.

    $ pip install python-dotenv
  8. Open and copy/paste following codes.

    import os
    import smtplib
    import ssl
    from email import encoders
    from email.header import Header
    from email.mime.base import MIMEBase
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from glob import glob
    from pathlib import Path
    from dotenv import load_dotenv
    def email_with_attachment(header: str, recipient: list, body: str, attachments: list) -> None:
    port = 465  # For SSL
    smtp_server = ""
    from_email = os.getenv("EMAIL_ID")
    email_password = os.getenv("EMAIL_PASSWORD")
    message = MIMEMultipart()
    message['From'] = from_email
    message['To'] = email_password
    message['Subject'] = Header(header, 'utf-8')
    if(attachments is not None):
        message.attach(MIMEText(body, 'plain', 'utf-8'))
        for attachment in attachments:
            attachment = open(attachment, 'rb')
            attachment_name = os.path.basename(str(
            part = MIMEBase('application', 'octet-stream')
                            'attachement; filename={}'.format(attachment_name))
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        server.login(from_email, email_password)
        server.sendmail(from_email, recipient, message.as_string())
    if __name__ == '__main__':
    to_email = os.getenv("TO_EMAIL").split(';')
    attachments = glob('data/*.csv')
    email_with_attachment(header='header...', recipient=to_email, body='body...', attachments=attachments)
  9. Run Ctrl + F5 or Right click >> "Run Python File in Terminal" within VS Code.



taeheechoi © 2023