0

I am using MIMEMultipart to send emails from Python. The code is as follows:

sender = "EMAIL"
recipients = ["EMAIL"]
msg = MIMEMultipart('alternative')
msg['Subject'] = "Subject Text"
msg['From'] = sender
msg['To'] = ", ".join(recipients)

html = PandasDataFrame.to_html()
part2 = MIMEText(html, 'html')
msg.attach(part2)

SERVER = "SERVER"
server = smtplib.SMTP(SERVER)
server.sendmail(sender, recipients, msg.as_string())
server.quit()  

This inserts a Python Pandas dataframe as HTML and works fine. Is it possible to add footnotes as text to the email body as well? How would the code work for doing both? Alternatively, I'm fine adding comments as HTML but more of less need some footnotes added to the email body.

Thanks

6
  • As long as this isn't a spam script :P Commented Mar 16, 2017 at 17:39
  • @CharlieG No, for internal work process automation. Sending alerts based on dynamically updating data that comes from the Pandas Dataframe but needing instructions in the email so people understand what it means. Commented Mar 16, 2017 at 18:12
  • Any result? Upvote or accept an answer if it's right! Commented Mar 17, 2017 at 15:06
  • @CharlieG sorry just seeing this now give me a few to try it out. Thanks Commented Mar 17, 2017 at 15:20
  • @CharlieG I posted the correct code. How do I remove your answers without changing your reputation. Downarrow seems to imply I might be saying you weren't helpful. Thx Commented Mar 20, 2017 at 18:13

2 Answers 2

1

This code works:

First, import:

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication #Used for attachments
import smtplib

And the code:

sender = "EMAIL"
recipients = ["EMAIL1","EMAIL2"]
msg = MIMEMultipart('mixed') #use mixed instead of alternative to load multiple things 
msg['Subject'] = "Subject Text"
msg['From'] = sender
msg['To'] = ", ".join(recipients)

html = PandasDataFrame1.to_html() #first dataframe

 #insert text as follows
html += '''
    <br><br>
    This is a new line of random text.
    <br><br>
'''

html += PandasDataFrame2.to_html() #second dataframe

#put the html into the email body
html = MIMEText(html, 'html') 
msg.attach(html)

If you also want to attach a file to the email, use this code

ATTACHMENT_PATH = 'path\\file.type'
with open(ATTACHMENT_PATH, 'r') as fileobj:
    attachment = MIMEApplication(fileobj.read(), Name='file.type')
attachment['Content-Disposition'] = 'attachment; filename="file.type"'
msg.attach(attachment)

And the code to send using a server

SERVER = "SERVER"
server = smtplib.SMTP(SERVER)
server.sendmail(sender, recipients, msg.as_string())
server.quit()  
Sign up to request clarification or add additional context in comments.

Comments

0

So the below didn't work, check out the correct answer

Maybe this?

html = pd.DataFrame([[1,2,3], ['dog', 'cat', 42]]).to_html()
part1 = MIMEText(html, 'html')
msg.attach(part1)
part2 = MIMEText('html')
coolstring = 'This is a dope-ass DataFrame yo'
part2.set_payload(coolstring)
msg.attach(part2)

though I think it's too similiar to to #2 below. Output follows:

>> print msg
# ...header with my email whoops...
--===============0888735609==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
<table border="1" class="dataframe">
    #...DataFrame html...
</table>
--===============0888735609==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
This is a dope-ass DataFrame yo
--===============0888735609==--

Found a couple of ways looking through the examples and by listing out the methods on MIMEMultipart through the equivalent of dir(MIMEMultipart)

Three guesses that you'll have to test:

1) You can set an epilogue by

msg.epilogue = 'This is a dope-ass DataFrame yo' 

Not sure where or if this ends up on the email body however.

2) Create another MIMEText and attach it too. This seems to be how they accomplish sending loads of pictures at once in the examples, so this may be your best bet. Probably should have led with this.

part_text = MIMEText('This is some text, yessir')
msg.attach(part_text)

It kinda looks like it got there since the boundary divisions are the same.

>> print msg.as_string()
Content-Type: multipart/alternative; boundary="===============1672307235=="
MIME-Version: 1.0
Subject: Subject Text
From: EMAIL
To: EMAIL
--===============1672307235==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
<table border="1" class="dataframe">
  # ...DataFrame in HTML here...
</table>
--===============1672307235==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
This is some text, yessir
--===============1672307235==--

3) Since to actually send it in server.sendmail(sender, recipients, msg.as_string()) you convert msg to a string, your other option would be to manually add some HTML text into msg.as_string() directly. Something like

msg.as_string().replace('</table>', '</table>\n<p>...your text here</p>')

would be messy but should work.

Let me know if any of these are helpful! I'm kinda shooting in the dark because I can't test it right now. Good luck!

5 Comments

Tried all three, none of them worked. #1 and #2 ran fine but the resultant email still only had the dataframe, no text. #3 threw an error: of "invalid syntax". Seems like adding the code after as_string() created an error where server quit failed. So perhaps I implemented it wrong?
Hmm probably not, I was just guessing anyway. Let me try some things by sending it to myself and get back to you?
@GC123 what package is smtplib.SMTP(SERVER) from? Also what server to I specify?
Updated. Did that work? I can't import smtplib to my work computer because of reasons
No, unfortunately this didn't work either. I reached out to a contact off stackoverflow who should be able to help (but might be a day or three). Will post working code when I have it. Welcome any other thoughts in the meantime from anyone. Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.