Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I send a plot.ly image inline of an html email using smtp?

I'm automating a couple of bi-weekly reports so I've decided to use plot.ly to create a line plot. This line plot has a varying amount of traces depending on the report that is being run.
I've been able to create plots successfully but none of the methods I've found have worked for displaying the plot inline in my email. Here is my code:

SMTP_SERVER = "smtp.office365.com"
SMTP_PORT = 587
SMTP_USERNAME = username
SMTP_PASSWORD = password
EMAIL_TO = email_to
EMAIL_FROM = email_from

#here we loop through our data-set and pull out rows to make different traces
for deal in winGraph['DEAL_IDENTIFIER'].unique():
    matched_rows = winGraph.loc[winGraph['DEAL_IDENTIFIER'] == deal]
    date = matched_rows.DATE.tolist()
    winRate = matched_rows.WIN_RATE.tolist()
    traces.append(
                 go.Scatter(
                            x = date,
                            y = winRate,
                            name = str(deal)
                             )
                  )
plotly.tools.set_credentials_file(username = 'username', api_key = 'api_key')                        
fig = dict(data = traces)

imageURL = py.plot(fig,auto_open = False, filename = 'test' )

msg = MIMEMultipart('related')
msg['Subject'] = Header(u"Hello", 'utf-8')
msg['From'] = EMAIL_FROM
msg['To'] = EMAIL_TO
msg_alternative = MIMEMultipart('alternative')
msg.attach(msg_alternative)

msg_text =  MIMEText(u'[image: {title}]'.format(**img), 'plain', 'utf-8')
msg_alternative.attach(msg_text)
html = u"""\
<html>
<head></head>
<body style="background-color:#DDDDDD; font-family: calibri;">
<p>
<img src="cid:{cid}" alt="{alt}"><br>
   Hi!<br>
   How are you?<br>
   Below is a summary of your performance
   <br>
   Top 5 Deals:
   {df}

   Please review:<br>
   The following graph represents your deals win rate over the past two weeks:
   <br>
   Look at attached spreadsheet for more info. <br>
   <img src="data:image/png;base64,{image}">
   </a>
   <br>
</p>
</body>
</html>
"""

response = requests.get(imageURL + '.png') # request Plotly for the image
response.raise_for_status()
image_bytes = response.content
image = base64.b64encode(image_bytes)

html = html.format( df = topAdv.to_html(index = False, escape = False),image = image,alt=cgi.escape(img['title'], quote=True),**img)
part2 = MIMEText(html, 'html', 'utf-8')

msg_alternative.attach(part2)

with open(img['path'], 'rb') as file:
    msg_image = MIMEImage(file.read(), name=os.path.basename(img['path']))
    msg.attach(msg_image)
msg_image.add_header('Content-ID', '<{}>'.format(img['cid']))

mail = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
mail.ehlo()
mail.starttls()
mail.login(SMTP_USERNAME, SMTP_PASSWORD)
mail.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string())
mail.quit()
like image 557
LMP Avatar asked Apr 17 '17 14:04

LMP


People also ask

How do you insert a Plotly graph into a website?

To share a plot from the Chart Studio Workspace, click 'Share' button on the left-hand side after saving the plot. The Share modal will pop-up and display a link under the 'Embed' tab. You can then copy and paste this link to your website. You have the option of embedding your plot as an HTML snippet or iframe.


1 Answers

Instead of rendering the plot on plotly's servers and embedding it as an png, you can also try to embed the plot directly as HTML/SVG/JavaScript (assuming that most e-mail clients these days can deal with it due to browser rendering engines used for displaying emails) using plotly's offline capabilities. I guess people will like the interactive features of the plot ...

from plotly.offline import plot
# Generate your plotly figure as fig
div = plot(
    fig,
    output_type = 'div',
    include_plotlyjs = True
    )

This will give you a string containing your plot and the required JavaScript wrapped in a div-tag.

like image 83
s-m-e Avatar answered Oct 06 '22 02:10

s-m-e