Reputation: 294
I am trying to send an email with Python with an inline image.
I wrote a script:
from pretty_html_table import build_table
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
message = MIMEMultipart('alternative')
message['Subject'] = f"Data for {last_date.date()}"
message['From'] = sender
message['To'] = receiver
# Builds HTML Table
output_table = build_table(table_for_email, "blue_light")
text = MIMEText(
f'''<html>
<head></head>
<body>
<p>Hello!</p>
<p>Please check out the new data.</p>
{output_table}
<img src="cid:plots">
</body>
</html>
''', "html"
)
message.attach(text)
image = MIMEImage(open('figure.png', 'rb').read())
image.add_header('Content-ID', '<plots>')
message.attach(image)
attach_file_name = 'figure.png'
attach_file = open(attach_file_name, 'rb')
payload = MIMEBase('application', 'octate-stream')
payload.set_payload((attach_file).read())
encoders.encode_base64(payload)
payload.add_header('Content-Decomposition', 'attachment', filename=attach_file_name)
message.attach(payload)
msg_body = message.as_string()
server = smtplib.SMTP_SSL(mail_server)
server.login(sender, password)
server.sendmail(from_addr=sender,
to_addrs=receiver,
msg=msg_body)
server.quit()
When I open an email with Gmail, it shows the image, but it does not in Outlook client.
I have unchecked "Don't download pictures automatically..." in Outlook trust center, but still it doesn't work. Looks like it download the files (shows in progress bar) but doesn't show them in email priview.
Upvotes: 1
Views: 1947
Reputation: 294
I solved the problem by using EmailMessage library instead of email.mime...
from email.message import EmailMessage
from email.utils import make_msgid
from pretty_html_table import build_table
import smtplib
import imghdr
output_table = build_table(table_for_email, "blue_light")
newMessage = EmailMessage()
newMessage['Subject'] = f"Data for {last_date.date()}"
newMessage['From'] = sender
newMessage['To'] = receiver
newMessage.set_content('Hello, please check the new data.')
figure_id = make_msgid()
newMessage.add_alternative("""\
<html>
<head></head>
<body>
<p>Hello, please check the new data.</p>
""" + output_table + """
<img src="cid:{figure_id}" />
</body>
</html>
""".format(figure_id=figure_id[1:-1]), subtype='html')
# Inline image
with open("figure.png", 'rb') as img:
newMessage.get_payload()[1].add_related(img.read(), 'image', 'png',
cid=figure_id)
# Image as attachment
with open('figure.png', 'rb') as f:
image_data = f.read()
image_type = imghdr.what(f.name)
image_name = f.name
newMessage.add_attachment(image_data, maintype='image', subtype=image_type, filename=image_name)
# Send E-mail
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(sender, password)
smtp.send_message(newMessage)
Upvotes: 2