How do I integrate a HTML code in a Python Script?
Asked Answered
A

3

7

I have a Python code that creates a report for a data frame from Reddit, and converts it to simple HTML and then email's it out. Below is the code:

#Clean all the Dataframes
test_clean = clean(test_test_df)
brand_clean = clean(brands_df)
competitor_clean = clean(competitors_df)
#Convert to HTML
test_html = test_clean.render()
brand_html = brand_clean.render()
competitor_html = competitor_clean.render()


# In[27]:


brand_clean


# # Email Integration

# #### Import Libraries for Email

# In[ ]:


import smtplib
from email.mime.multipart import MIMEMultipart 
from email.mime.text import MIMEText
from datetime import date


# #### Send Email If No Data is Available

# In[ ]:


if test_test_df.empty:
    today = str(date.today())

    fromaddr = "[email protected]"
    toaddr = "[email protected]"
    msg = MIMEMultipart()
    msg['From'] = fromaddr
    msg['To'] = toaddr
    msg['Subject'] = "Daily Reddit Monitor " + today


    message = "There are no relevant posts above the 100 score threshold today!"

    #email = df_complete.render()

    part1 = MIMEText(message, 'plain')


    msg.attach(part1)
    #msg.attach(part2)

    server = smtplib.SMTP('smtp.postmarkapp.com', 587)
    server.starttls()
    server.login('API-KEY”, “API-KEY')
    text = msg.as_string()
    server.sendmail(fromaddr, toaddr, text)
    server.quit()
    IpyExit 

The email that is received is very simple in format. I wanted that email to look good so wrote a HTML code with header image logo etc using HTML Tables inline CSS, in short a HTML code for news letter. Now I want that Python script to use my HTML code while sending the email so that the email when received in Inbox looks good like a news letter. Any suggestion or solution how I can achieve this?

Below is my HTML code.

<table width="689" border="0" cellspacing="0" cellpadding="1" align="center" bgcolor="#353A71">
<tr>
     <td valign="middle" align="center">

     <table width="689" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
    <tr align="left"> 
         <td valign="top" colspan="2"> 

          <table width="100%" border="0" cellpadding="3" cellspacing="0" bgcolor="#FFFFFF">
        <tr> 
             <td width="0%">&nbsp;</td>
            <td valign="top" width="100%">

               <center><h1 style="font-family:helvetica;">Top Reddit Posts</h1></center>



                <td width="0%">&nbsp;</td>
        </tr>
        <tr>

             <td width="0%">&nbsp;</td>
               <td>&nbsp;</td>     

            <td width="0%">&nbsp;</td>
        </tr>
          <tr> 
             <td width="0%" bgcolor="#FFFFFF">&nbsp;</td>
            <td align="center" class="profileCaptionWhiteBold" width="100%" valign="top" bgcolor="#FFFFFF"> 
               </td>
               <td width="0%" bgcolor="#FFFFFF">&nbsp;</td>
        </tr>
        </table>

So I want the out put of the script to go after:

Top Reddit Posts

Arterialize answered 30/5, 2019 at 15:36 Comment(10)
It looks like you already have the code for it: MIMEText(email,'html')?Doting
Yes but the email I get is very plane in format see this sample imgur.com/hCoCrGuArterialize
Have you tried manually sending html email and see if it works? Because a lot of formatting (CSS) don't work in emails.Doting
Yes that email is working and looks perfect in the inbox when I test it out. The HTML email is not a issue integrating that HTML code with this Python script is issueArterialize
Is the script you attached in question the actual one you're using? because it has the html part commented out.Doting
Do not worry about that I removed that lineArterialize
That was the correct code... change MIMEText(message, 'plain') to MIMEText(message, 'html')Doting
Actually, I feel like the code you put on question is irrelevant/not the part you're asking: there are no html you're trying to send at all in the code.Doting
The HTML code I have created is in a different file so my question is how do I integrate that HTML code into the above Python script while sending the email out.Arterialize
@error2007s - see my answer on integrating HTML code into python for merging the HTML report from your data frameKiefer
K
2

Your sample code wasn't very clear, but I think you are just trying to embed an existing HTML fragment (the report for a data frame from Reddit) into a larger HTML page that presents it nicely.

To do this, you can simply use a template held in a multi-line string then substitute values for placemarkers {} within it:

# Placeholder for current html report from dataframe (replace with your code)
df = pd.DataFrame([{'Title': 'Story 1 title', 'Description': 'Story 1 description'}])
redditHTML = df.to_html()

# HTML news letter template
template='''
<table width="689" border="0" cellspacing="0" cellpadding="1" align="center" bgcolor="#353A71">
    <tr>
        <td valign="middle" align="center">
            <table width="689" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
                <tr align="left"> 
                    <td valign="top" colspan="2"> 
                        <table width="100%" border="0" cellpadding="3" cellspacing="0" bgcolor="#FFFFFF">
                            <tr> 
                                <td width="0%">&nbsp;</td>
                                <td valign="top" width="100%">
                                    <center><h1 style="font-family:helvetica;">Top Reddit Posts</h1></center>

                                    {}

                                </td>
                                <td width="0%">&nbsp;</td>
                            </tr>
                            <tr>
                                <td width="0%">&nbsp;</td>
                                <td>&nbsp;</td>     
                                <td width="0%">&nbsp;</td>
                            </tr>
                            <tr> 
                                <td width="0%" bgcolor="#FFFFFF">&nbsp;</td>
                                <td align="center" class="profileCaptionWhiteBold" width="100%" valign="top" bgcolor="#FFFFFF"></td>
                                <td width="0%" bgcolor="#FFFFFF">&nbsp;</td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>
'''

completeHTML = template.format(redditHTML)

msg.attach(MIMEText(completeHTML, 'html'))

Note that your HTML code example was missing a </td> to close the section containing the Top Reddit Posts, plus was missing the trailing </td> </tr> </table> to complete the news letter

Kiefer answered 8/6, 2019 at 6:40 Comment(1)
This is a partial correct answer that i was looking forArterialize
A
10

Say the HTML you have generated elsewhere is contained in the string messageHTML, then all you have to add is:

msg.attach(MIMEText(messageHTML, 'html'))

Leave the plain text in as well, so the two lines will look like

msg.attach(MIMEText(messagePlain, 'plain'))
msg.attach(MIMEText(messageHTML, 'html'))

To set up the HTML, create a variable messageHTML. Then you could create the table like so (assuming you want 1 row, with 2 columns, data_1 and data_2):

messagePlain = data_1 + " " + data_2
messageHTML = '<table><tr><td>' + data_1 + '</td><td>' + data_2 + '</td></tr></table>'

msg.attach(MIMEText(messagePlain, 'plain'))
msg.attach(MIMEText(messageHTML, 'html'))

I'd recommend starting off with a simple table, maybe not even with dynamically obtained data, to ensure that the HTML Is rendering correctly when you send it, and then it extend the HTML to the content and style you want later.

Altimetry answered 2/6, 2019 at 13:4 Comment(11)
If you don't mind me asking, where can I find the documentation for the MIMEText method?Sunstone
The officail documentaion is on the python docs, however I've found this guide on python emails on nitrate useful in the past.Altimetry
@error2007s are you taking the HTML template you just provided as a string??Altimetry
@SamuelCooper I can keep it a separate file or I can make it a string so if you can provide me a full code in the answer that will be really helpful.Arterialize
I've added an example case.Altimetry
Ok Implementing the above code in our big data tool script will get back to youArterialize
@SamuelCooper I am getting a email which has data_1 and data_2 in the bodyArterialize
Is it in a table?Altimetry
Yes but it just have the word data_1 and data_2 in the emaul bodyArterialize
Assign a value to the variables data_1 and data_2 and it should fill that data into the table.Altimetry
@SamuelCooper I Defined the variable but still the same thing in the email "data_1"Arterialize
K
2

Your sample code wasn't very clear, but I think you are just trying to embed an existing HTML fragment (the report for a data frame from Reddit) into a larger HTML page that presents it nicely.

To do this, you can simply use a template held in a multi-line string then substitute values for placemarkers {} within it:

# Placeholder for current html report from dataframe (replace with your code)
df = pd.DataFrame([{'Title': 'Story 1 title', 'Description': 'Story 1 description'}])
redditHTML = df.to_html()

# HTML news letter template
template='''
<table width="689" border="0" cellspacing="0" cellpadding="1" align="center" bgcolor="#353A71">
    <tr>
        <td valign="middle" align="center">
            <table width="689" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
                <tr align="left"> 
                    <td valign="top" colspan="2"> 
                        <table width="100%" border="0" cellpadding="3" cellspacing="0" bgcolor="#FFFFFF">
                            <tr> 
                                <td width="0%">&nbsp;</td>
                                <td valign="top" width="100%">
                                    <center><h1 style="font-family:helvetica;">Top Reddit Posts</h1></center>

                                    {}

                                </td>
                                <td width="0%">&nbsp;</td>
                            </tr>
                            <tr>
                                <td width="0%">&nbsp;</td>
                                <td>&nbsp;</td>     
                                <td width="0%">&nbsp;</td>
                            </tr>
                            <tr> 
                                <td width="0%" bgcolor="#FFFFFF">&nbsp;</td>
                                <td align="center" class="profileCaptionWhiteBold" width="100%" valign="top" bgcolor="#FFFFFF"></td>
                                <td width="0%" bgcolor="#FFFFFF">&nbsp;</td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>
'''

completeHTML = template.format(redditHTML)

msg.attach(MIMEText(completeHTML, 'html'))

Note that your HTML code example was missing a </td> to close the section containing the Top Reddit Posts, plus was missing the trailing </td> </tr> </table> to complete the news letter

Kiefer answered 8/6, 2019 at 6:40 Comment(1)
This is a partial correct answer that i was looking forArterialize
Z
-2

You can create an HTML-formatted email (on windows) like so:

    import win32com.client as win32   
    outlook = win32.Dispatch('outlook.application')
    mail = outlook.CreateItem(0)   
    mail.HtmlBody = html_string
    mail.To = ''
    mail.Subject = ''

etc.

Zephyr answered 3/6, 2019 at 13:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.