How to send HTML content in email using Python? I can send simple texts.

2

12 Answers

From Python v2.7.14 documentation - 18.1.11. email: Examples:

Here’s an example of how to create an HTML message with an alternative plain text version:

#! /usr/bin/python import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText # me == my email address # you == recipient's email address me = "" you = "" # Create message container - the correct MIME type is multipart/alternative. msg = MIMEMultipart('alternative') msg['Subject'] = "Link" msg['From'] = me msg['To'] = you # Create the body of the message (a plain-text and an HTML version). text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://" html = """\ <html> <head></head> <body> <p>Hi!<br> How are you?<br> Here is the <a href="">link</a> you wanted. </p> </body> </html> """ # Record the MIME types of both parts - text/plain and text/html. part1 = MIMEText(text, 'plain') part2 = MIMEText(html, 'html') # Attach parts into message container. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. msg.attach(part1) msg.attach(part2) # Send the message via local SMTP server. s = smtplib.SMTP('localhost') # sendmail function takes 3 arguments: sender's address, recipient's address # and message to send - here it is sent as one string. s.sendmail(me, you, msg.as_string()) s.quit() 
12

Here is a Gmail implementation of the accepted answer:

import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText # me == my email address # you == recipient's email address me = "" you = "" # Create message container - the correct MIME type is multipart/alternative. msg = MIMEMultipart('alternative') msg['Subject'] = "Link" msg['From'] = me msg['To'] = you # Create the body of the message (a plain-text and an HTML version). text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://" html = """\ <html> <head></head> <body> <p>Hi!<br> How are you?<br> Here is the <a href="">link</a> you wanted. </p> </body> </html> """ # Record the MIME types of both parts - text/plain and text/html. part1 = MIMEText(text, 'plain') part2 = MIMEText(html, 'html') # Attach parts into message container. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. msg.attach(part1) msg.attach(part2) # Send the message via local SMTP server. mail = smtplib.SMTP('smtp.gmail.com', 587) mail.ehlo() mail.starttls() mail.login('userName', 'password') mail.sendmail(me, you, msg.as_string()) mail.quit() 
5

You might try using my mailer module.

from mailer import Mailer from mailer import Message message = Message(From="", To="") message.Subject = "An HTML Email" message.Html = """<p>Hi!<br> How are you?<br> Here is the <a href="">link</a> you wanted.</p>""" sender = Mailer('smtp.example.com') sender.send(message) 
5

Here is a simple way to send an HTML email, just by specifying the Content-Type header as 'text/html':

import email.message import smtplib msg = email.message.Message() msg['Subject'] = 'foo' msg['From'] = '' msg['To'] = '' msg.add_header('Content-Type','text/html') msg.set_payload('Body of <b>message</b>') # Send the message via local SMTP server. s = smtplib.SMTP('localhost') s.starttls() s.login(email_login, email_passwd) s.sendmail(msg['From'], [msg['To']], msg.as_string()) s.quit() 
2

for python3, improve @taltman 's answer:

  • use email.message.EmailMessage instead of email.message.Message to construct email.
  • use email.set_content func, assign subtype='html' argument. instead of low level func set_payload and add header manually.
  • use SMTP.send_message func instead of SMTP.sendmail func to send email.
  • use with block to auto close connection.
from email.message import EmailMessage from smtplib import SMTP # construct email email = EmailMessage() email['Subject'] = 'foo' email['From'] = '' email['To'] = '' email.set_content('<font color="red">red color text</font>', subtype='html') # Send the message via local SMTP server. with smtplib.SMTP('localhost') as s: s.login('foo_user', 'bar_password') s.send_message(email) 
2

Here's sample code. This is inspired from code found on the Python Cookbook site (can't find the exact link)

def createhtmlmail (html, text, subject, fromEmail): """Create a mime-message that will render HTML in popular MUAs, text in better ones""" import MimeWriter import mimetools import cStringIO out = cStringIO.StringIO() # output buffer for our message htmlin = cStringIO.StringIO(html) txtin = cStringIO.StringIO(text) writer = MimeWriter.MimeWriter(out) # # set up some basic headers... we put subject here # because smtplib.sendmail expects it to be in the # message body # writer.addheader("From", fromEmail) writer.addheader("Subject", subject) writer.addheader("MIME-Version", "1.0") # # start the multipart section of the message # multipart/alternative seems to work better # on some MUAs than multipart/mixed # writer.startmultipartbody("alternative") writer.flushheaders() # # the plain text section # subpart = writer.nextpart() subpart.addheader("Content-Transfer-Encoding", "quoted-printable") pout = subpart.startbody("text/plain", [("charset", 'us-ascii')]) mimetools.encode(txtin, pout, 'quoted-printable') txtin.close() # # start the html subpart of the message # subpart = writer.nextpart() subpart.addheader("Content-Transfer-Encoding", "quoted-printable") # # returns us a file-ish object we can write to # pout = subpart.startbody("text/html", [("charset", 'us-ascii')]) mimetools.encode(htmlin, pout, 'quoted-printable') htmlin.close() # # Now that we're done, close our writer and # return the message body # writer.lastpart() msg = out.getvalue() out.close() print msg return msg if __name__=="__main__": import smtplib html = 'html version' text = 'TEST VERSION' subject = "BACKUP REPORT" message = createhtmlmail(html, text, subject, 'From Host <>') server = smtplib.SMTP("smtp_server_address","smtp_port") server.login('username', 'password') server.sendmail('', '', message) server.quit() 
2

Actually, yagmail took a bit different approach.

It will by default send HTML, with automatic fallback for incapable email-readers. It is not the 17th century anymore.

Of course, it can be overridden, but here goes:

import yagmail yag = yagmail.SMTP("", "mypassword") html_msg = """<p>Hi!<br> How are you?<br> Here is the <a href="">link</a> you wanted.</p>""" yag.send("", "the subject", html_msg) 

For installation instructions and many more great features, have a look at the github.

1

Here's a working example to send plain text and HTML emails from Python using smtplib along with the CC and BCC options.

#!/usr/bin/env python import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText def send_mail(params, type_): email_subject = params['email_subject'] email_from = "" email_to = params['email_to'] email_cc = params.get('email_cc') email_bcc = params.get('email_bcc') email_body = params['email_body'] msg = MIMEMultipart('alternative') msg['To'] = email_to msg['CC'] = email_cc msg['Subject'] = email_subject mt_html = MIMEText(email_body, type_) msg.attach(mt_html) server = smtplib.SMTP('YOUR_MAIL_SERVER.DOMAIN.COM') server.set_debuglevel(1) toaddrs = [email_to] + [email_cc] + [email_bcc] server.sendmail(email_from, toaddrs, msg.as_string()) server.quit() # Calling the mailer functions params = { 'email_to': '', 'email_cc': '', 'email_bcc': '', 'email_subject': 'Test message from python library', 'email_body': '<h1>Hello World</h1>' } for t in ['plain', 'html']: send_mail(params, t) 
1

Here is my answer for AWS using boto3

 subject = "Hello" html = "<b>Hello Consumer</b>" client = boto3.client('ses', region_name='us-east-1', aws_access_key_id="your_key", aws_secret_access_key="your_secret") client.send_email( Source='ACME <>', Destination={'ToAddresses': [email]}, Message={ 'Subject': {'Data': subject}, 'Body': { 'Html': {'Data': html} } } 

Simplest solution for sending email from Organizational account in Office 365:

from O365 import Message html_template = """ <html> <head> <title></title> </head> <body> {} </body> </html> """ final_html_data = html_template.format(df.to_html(index=False)) o365_auth = ('sender_username@company_email.com','Password') m = Message(auth=o365_auth) m.setRecipients('receiver_username@company_email.com') m.setSubject('Weekly report') m.setBodyHTML(final_html_data) m.sendMessage() 

here df is a dataframe converted to html Table, which is being injected to html_template

1

I may be late in providing an answer here, but the Question asked a way to send HTML emails. Using a dedicated module like "email" is okay, but we can achieve the same results without using any new module. It all boils down to the Gmail Protocol.

Below is my simple sample code for sending HTML mail only by using "smtplib" and nothing else.

 import smtplib FROM = "" TO = "" SUBJECT= "Subject" PWD = "thesecretkey" TEXT=""" <h1>Hello</h1> """ #Your Message (Even Supports HTML Directly) message = f"Subject: {SUBJECT}\nFrom: {FROM}\nTo: {TO}\nContent-Type: text/html\n\n{TEXT}" #This is where the stuff happens try: server=smtplib.SMTP("smtp.gmail.com",587) server.ehlo() server.starttls() server.login(FROM,PWD) server.sendmail(FROM,TO,message) server.close() print("Successfully sent the mail.") except Exception as e: print("Failed to send the mail..", e) 
1

In case you want something simpler:

from redmail import EmailSender email = EmailSender(host="smtp.myhost.com", port=1) email.send( subject="Example email", sender="", receivers=[""], html="<h1>Hi, this is HTML body</h1>" ) 

Pip install Red Mail from PyPI:

pip install redmail 

Red Mail has most likely all you need from sending emails and it has a lot of features including:

Documentation:

Source code: