Search code examples
pythonpandascsvexecutablesmtplib

Is there a way to send email with a dataframe attachment?


I currently have a script that manipulates a .csv file using pandas. I'm trying to send a MIMEMultipart email with the latest .csv version of the file that has been amended but for some reason, the email recipients keep receiving an older unaltered version of the .csv that I trying to send. I'm trying to make sense of it in my head because the old version of the .csv file is written over before it is sent but the original version of the .csv is sent to the recipients.

Maybe I need to specify a path for smtplib to get the file as opposed to just giving the name of the file. Is there a way to do that or is there another way around my problem? I've already tried to change the name to something else in order for smtplib to be able to differentiate between the old .csv and the new one.

This doesn't work though as the file is placed in the directory but my script says that the new file doesn't exist

This is my current code:

email_user = 'Bot@gmail.com'
email_password = 'Business101'
email_send = ('myemail@gmail.com', 'myfriendsemail@gmail.com')

subject = 'TOP 5 CONTRACTS'

msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = ",".join(email_send)
msg['Subject'] = subject

body = 'These are the latest contracts for this week!'
msg.attach(MIMEText(body,'plain'))

filename='CC.csv'
attachment  =open(filename,'rb')

part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',"attachment; filename= "+filename)

msg.attach(part)
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_user,email_password)


server.sendmail(email_user,email_send,text)
server.quit()

print("Emailed Recipients")

Might be worth mentioning that this process is an automated one so the script is being run from a Unix Executable file on my mac.

If you can assist, I'd really appreciate it!


Solution

  • This has been the best way to do it, thanks

    from email.mime.text import MIMEText
    from email.mime.application import MIMEApplication
    from email.mime.multipart import MIMEMultipart
    from smtplib import SMTP
    import smtplib
    import sys
    import pandas as pd
    
    df_test = pd.read_csv('/Users/emmanuelafoke/Documents/Selenium/CC.csv')
    
    email_user = 'myemailaddress@gmail.com'
    email_password = 'mypassword'
    
    recipients = ['theiremailaddress@gmail.com'] 
    emaillist = [elem.strip().split(',') for elem in recipients]
    msg = MIMEMultipart()
    msg['Subject'] = 'SUBJECT'
    msg['From'] = 'myemailaddress@gmail.com'
    
    
    html = """\
    <html>
      <head></head>
      <body>
        {0}
      </body>
    </html>
    """.format(df_test.to_html())
    
    part1 = MIMEText(html, 'html')
    msg.attach(part1)
    
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(email_user,email_password)
    server.sendmail(msg['From'], emaillist , msg.as_string())
    

    Thanks for all of your help!