7

I’m attempting to attach a CSV file and email it.

Currently, I am doing the following but it simply attaches an empty CSV file, rather than attaching the CSV file I have in the same directory:

import smtplib

from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE
from email import encoders


def email_attachment():
    SUBJECT = 'Subject string'

    msg = MIMEMultipart()
    msg['From'] = 'my_email@yahoo.com'
    msg['To'] = COMMASPACE.join(['recepient_email@gmail.com'])
    msg['Subject'] = SUBJECT

    part = MIMEBase('application', "octet-stream")
    #    I have a CSV file named `attachthisfile.csv` in the same directory that I'd like to attach and email
    part.set_payload(open("./attachthisfile.csv", "rb").read())
    encoders.encode_base64(part)

    part.add_header('Content-Disposition', 'attachment', filename='attachthisfile.csv')

    msg.attach(part)

    smtpObj = smtplib.SMTP('smtp.mail.yahoo.com', 587)
    smtpObj.ehlo()
    smtpObj.starttls()
    smtpObj.login('my_email@yahoo.com', 'myemailpassword')
    smtpObj.sendmail('my_email@yahoo.com', 'recepient_email@gmail.com', msg.as_string())

    smtpObj.quit()

So my question is, what could I be doing wrong? How can I attach the CSV file in the same directory and email, rather than creating an empty CSV file and naming it the same, and emailing?

DSM
  • 342,061
  • 65
  • 592
  • 494
Jo Ko
  • 7,225
  • 15
  • 62
  • 120
  • Please see [revisions](http://stackoverflow.com/posts/43214684/revisions) for some of the other char fixes. – brennan Apr 05 '17 at 11:05

2 Answers2

8

The issue seems to be with this line:

part.add_header('Content-Disposition', 'attachment; filename=“attachthisfile.csv"')

It contains a Non-ASCII character '\xe2' after filename=. It's the old ascii encoding problem, in this case it's: vs "

As a side note, you can also change the add_header arguments to match this Python docs example:

part.add_header('Content-Disposition', 'attachment', filename='attachthisfile.csv')

Full working example:

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE
from email import encoders

SUBJECT = 'Subject string'
FILENAME = 'attachthisfile.csv'
FILEPATH = './attachthisfile.csv'
MY_EMAIL = 'example@yahoo.com'
MY_PASSWORD = '********************'
TO_EMAIL = 'example@gmail.com'
SMTP_SERVER = 'smtp.mail.yahoo.com'
SMTP_PORT = 587

msg = MIMEMultipart()
msg['From'] = MY_EMAIL
msg['To'] = COMMASPACE.join([TO_EMAIL])
msg['Subject'] = SUBJECT

part = MIMEBase('application', "octet-stream")
part.set_payload(open(FILEPATH, "rb").read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename=FILENAME)  # or
# part.add_header('Content-Disposition', 'attachment; filename="attachthisfile.csv"')
msg.attach(part)

smtpObj = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login(MY_EMAIL, MY_PASSWORD)
smtpObj.sendmail(MY_EMAIL, TO_EMAIL, msg.as_string())
smtpObj.quit()

Edit: Added full example

Community
  • 1
  • 1
brennan
  • 3,392
  • 24
  • 42
  • Appreciate your response! Gave it an attempt as suggested but still no luck – Jo Ko Apr 05 '17 at 17:08
  • Thank you for the revision and gave it a try, but it still just attaches a new CSV file named `attachthisfile.csv` rather than grabbing the existing `attachthisfile.csv` in the same directory. – Jo Ko Apr 06 '17 at 19:26
  • Weird! I tested it from yahoo to gmail. Were all the non-ascii backticks and quotes replaced? Are you running Python 2 or 3? What is the encoding of the csv file? – brennan Apr 06 '17 at 19:47
  • Maybe make start with a fresh utf-8 test csv to rule that out? http://stackoverflow.com/questions/18766955/how-to-write-utf-8-in-a-csv-file – brennan Apr 06 '17 at 19:54
  • Yup sure did. Running Python 2. Sorry but how do I determine the encoding of the csv file? – Jo Ko Apr 06 '17 at 20:48
  • Maybe try this on your python files as well as your csv http://stackoverflow.com/a/11021413/6085135 – brennan Apr 06 '17 at 23:00
  • If you're stuck in Python 2 and stdlib, this really works for attaching a csv. Thank you. – scharfmn Oct 13 '20 at 14:48
0

Question. So my question is, what could I be doing wrong?

Your code is working for me, nothing wrong.

Please edit your Question and add the following output:

def environ():
    import os
    for f in os.listdir('.'):
        print('%s\tuid=%s,\tgid=%s,\tsize=%s' % (f, os.stat(f)[4], os.stat(f)[5], os.stat(f)[6])  )  

Be sure to run it from the same *.py file and same def email_attachment()

def email_attachment():
    environ()
    #...
stovfl
  • 14,998
  • 7
  • 24
  • 51