Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to attach CSV file with MIME/SMTP and email?

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'] = '[email protected]'
    msg['To'] = COMMASPACE.join(['[email protected]'])
    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('[email protected]', 'myemailpassword')
    smtpObj.sendmail('[email protected]', '[email protected]', 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?

like image 846
Jo Ko Avatar asked Apr 04 '17 18:04

Jo Ko


People also ask

How do I email a CSV file?

In the CSV files manager, when you select a CSV template, the button “Send by Email” appears in the header. This function allows you to send a CSV file by email instead of uploading it through our system. Just remember that you can only send a file to an already-existing template.

How do you attach a csv file?

On the File menu, click Import. In the Import dialog box, click the option for the type of file that you want to import, and then click Import. In the Choose a File dialog box, locate and click the CSV, HTML, or text file that you want to use as an external data range, and then click Get Data.


1 Answers

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 = '[email protected]'
MY_PASSWORD = '********************'
TO_EMAIL = '[email protected]'
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

like image 197
brennan Avatar answered Oct 17 '22 02:10

brennan