Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I integrate a HTML code in a Python Script?

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

like image 480
error2007s Avatar asked May 30 '19 15:05

error2007s


2 Answers

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.

like image 167
Samuel Cooper Avatar answered Oct 06 '22 07:10

Samuel Cooper


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

like image 26
Mike Avatar answered Oct 06 '22 09:10

Mike