jmarusiak
jmarusiak

Reputation: 145

Iterate through data frame rows to send email

I have a data frame that looks like this:

|num|data |     email       |
|-- | --- | --------------- |
|1  | x   |[email protected]|
|2  | y   |[email protected]|
|3  | z   |[email protected]|

I need to send the 'num', 'data', fields to the email in the 'email' column.

So for this dataframe, rows 1 and 2 would be sent to [email protected] and row 3 would be sent to [email protected]

My Idea is to create an 'sendemail' function with the following parameters: data, to_email

Then iterate through the data frame rows passing the parameters to the for-loop.

Here's where I am:

import pandas as pd
from tabulate import tabulate
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# import data into df
df1 = pd.read_excel("data.xlsx")

# define email function       
def sendemail(html, to_email):
   
    fromaddr = "[email protected]"
    toaddr = to_email
    msg = MIMEMultipart("alternative")
    msg["From"] = fromaddr
    msg["To"] = to_email
    msg["Subject"] = "new email"
    msg.add_header("reply-to", "[email protected]")

    body = MIMEText(html, "html")
    msg.attach(body)

    server = smtplib.SMTP("smtp.emailserver.com", 587)

    server.starttls()
      
    server.login(fromaddr, "pw")
    text = msg.as_string()
    server.sendmail(fromaddr, toaddr, text)

    server.quit()

#iterate trough rows and send email
for row in df1.itertuples(index=False):
    sendemail(df1.to_html(index=False), df1["email"])

I believe my error is passing the data into the for-loop. I am getting an error:

AttributeError: 'Series' object has no attribute 'encode'

Any assistance would be greatly appreciated!

Upvotes: 1

Views: 1162

Answers (2)

abby kaff
abby kaff

Reputation: 1

I used a different approach iterating through the email process to send it to each row level recipient. You can use a for loop and the zip() function to grab all necessary data. I used this on a relatively small data set and cannot speak to whether it performs well on large data sets.

for x,y,z,a in zip(fulldf['Employee Name'], fulldf['Store E-mail'], fulldf['E-mail'], fulldf['Date Hired']):
outlook = win32com.client.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = y
mail.CC = z
mail.Subject = 'Career Growth Conversation'
mail.HTMLBody = """\
    <html>
        <head></head>
        <body>
            <p>Congratulations – """+ x +" hire date: "+ a +""" is ready for a Career Growth Conversations!<br>
                
            </p>
        </body>
    </html>
    """
mail.Attachments.Add(r"")
mail.Send()

Upvotes: 0

SeaBean
SeaBean

Reputation: 23217

Try to change your for loop to:

for row in df1.itertuples(index=False):
    sendemail(df1.to_html(index=False), row.email)

Here, instead of passing df1['email'] as a pandas Series to the sendmail() function where it requires a string for the 2nd argument, you access the row value under column 'email' by the syntax row.email, which is now an element (a string, in particular) and can be used directly in your sendmail() function.

An alternative way to access row.email is getattr(row, "email")

Upvotes: 1

Related Questions