To send an HTML email with attachment, we need to create a MIMEMultipart object with subject, to email address, from email address and attachment. Please change the values of each of the following variables as per your requirement.,Python is a powerful language that allows you to do tons of things. It even allows you to send HTML emails. In this article, we will look at how to send HTML mail with attachment using python.,That’s it. We have created python script to send HTML email with attachment. The key is to create MIMEText and MIMEMultipart message objects, assemble them and send it via sendmail() function.,Python provides smtplib module that allows you to send emails. First we need to import it into our python script
Python provides smtplib module that allows you to send emails. First we need to import it into our python script
import smtplib
Next, we need to import email package along with a few important classes – MIMEText, MIMEBase and MIMEMultipart.
import email
from email
import encoders
from email.mime.base
import MIMEBase
from email.mime.text
import MIMEText
from email.mime.multipart
import MIMEMultipart
To send an HTML email with attachment, we need to create a MIMEMultipart object with subject, to email address, from email address and attachment. Please change the values of each of the following variables as per your requirement.
msg = MIMEMultipart("alternative")
msg["Subject"] = "multipart test"
msg["From"] = sender_email
msg["To"] = receiver_email
filename = "document.pdf"
We need to convert above string to MIMEText object.
part = MIMEText(html, "html")
We attach this MIMEText object to MIMEMultipart object we created above.
msg.attach(part)
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 = "my@email.com"
you = "your@email.com"
# 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://www.python.org"
html = """\
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the <a href="http://www.python.org">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()
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 = "my@email.com"
you = "your@email.com"
# 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://www.python.org"
html = """\
<html>
<head></head>
<body>
<p>Hi!<br>
How are you?<br>
Here is the <a href="http://www.python.org">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()
You might try using my mailer module.
from mailer import Mailer
from mailer import Message
message = Message(From="me@example.com",
To="you@example.com")
message.Subject = "An HTML Email"
message.Html = """<p>Hi!<br>
How are you?<br>
Here is the <a href="http://www.python.org">link</a> you wanted.</p>"""
sender = Mailer('smtp.example.com')
sender.send(message)
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'] = 'sender@test.com'
msg['To'] = 'recipient@test.com'
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()
- use
email.message.EmailMessage
instead ofemail.message.Message
to construct email. - use
email.set_content
func, assignsubtype='html'
argument. instead of low level funcset_payload
and add header manually. - use
SMTP.send_message
func instead ofSMTP.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'] = 'sender@test.com'
email['To'] = 'recipient@test.com'
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)
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 <sender@host.com>') server = smtplib.SMTP("smtp_server_address","smtp_port") server.login('username', 'password') server.sendmail('sender@host.com', 'target@otherhost.com', message) server.quit()
Upasana | November 02, 2019 | 3 min read | 132 views
fromaddr = "xxx@gmail.com"(1)
toaddr = "yyy@gmail.com"(2)
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "Today's morning quote"(3)
body = "Never lose hope"(1)
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "****password****")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
from email.mime.multipart
import MIMEMultipart
from email.mime.text
import MIMEText
import smtplib
fromaddr = "xxx@gmail.com"
toaddr = "yyy@gmail.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "Today's morning quote"
body = "Never Lose hope"
msg.attach(MIMEText(body, 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "***password***")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
html = """
<h1 style="text-align: center;"><span style="color: #ff6600;"><strong>Morning Quote</strong></span></h1>
<h4><span style="color: #008000;"><strong>I believe that everything happens for a reason. People change so that you can learn to let go, things go wrong so that you appreciate them when they're right, you believe lies so you eventually learn to trust no one but yourself, and sometimes good things fall apart so better things can fall together.</strong></span></h4>
<p> </p>
"""
msg.attach(MIMEText(html, 'html'))
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
fromaddr = "xxx@gmail.com"
toaddr = "yyy@gmail.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "Morning Quote"
html = """
<h1 style="text-align: center;"><span style="color: #ff6600;"><strong>Morning Quote</strong></span></h1>
<h4><span style="color: #008000;"><strong>I believe that everything happens for a reason. People change so that you can learn to let go, things go wrong so that you appreciate them when they're right, you believe lies so you eventually learn to trust no one but yourself, and sometimes good things fall apart so better things can fall together.</strong></span></h4>
<p> </p>
"""
msg.attach(MIMEText(html, 'html'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "***password***")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()
Home » How to Send Emails using Python: Tutorial with examples,In this tutorial, you’ve learned how to send emails using Python, from the most basic plain text emails, to more fancy HTML emails with attachments.,If you want to send emails using Python, this tutorial will take you a long way!,In this tutorial, we’ll show you how to send emails using Python.
- Create a Gmail account
- Allow less secure apps: turn the switch ON to give Python access to your account
Please make sure you are changing the setting of the new account
If you don’t change this setting, when running the code later, you’ll get an error message like below:
SMTPAuthenticationError: (535, b '5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials - gsmtp')
You need to send HTML mail and embed a message version in plain text, so that the message is also readable by MUAs that are not HTML-capable. ,The emails generated by this code have been successfully tested on Outlook 2000, Eudora 4.2, Hotmail, and Netscape Mail. It’s likely that they will work in other HTML-capable MUAs as well. MUTT has been used to test the acceptance of messages generated by this recipe in text-only MUAs. Again, others would be expected to work just as acceptably. ,This module is completed in the usual style with a few lines to ensure that, when run as a script, it runs a self-test by composing and sending a sample HTML mail: ,Ideally, your input will be a properly formatted text version of the message, as well as the HTML version. But if you don’t have this input, you can still prepare a text version on the fly; one way to do this is shown in the recipe. Remember that htmllib has some limitations, so you may want to use alternative approaches, such as saving the HTML string to disk and using:
def createhtmlmail(subjectl, html, text = None): "Create a mime-message that will render as HTML or text, as appropriate" import MimeWriter import mimetools import cStringIO if text is None: # Produce an approximate textual rendering of the HTML string, # unless you have been given a better version as an argument import htmllib, formatter textout = cStringIO.StringIO() formtext = formatter.AbstractFormatter(formatter.DumbWriter(textout)) parser = htmllib.HTMLParser(formtext) parser.feed(html) parser.close() text = textout.getvalue() del textout, formtext, parser 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.Place subject here # because smtplib.sendmail expects it to be in the # message body, as relevant RFCs prescribe. 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: just copied through, assuming iso - 8859 - 1 subpart = writer.nextpart() pout = subpart.startbody("text/plain", [("charset", 'iso-8859-1')]) pout.write(txtin.read()) txtin.close() # the HTML subpart of the message: quoted - printable, just in case subpart = writer.nextpart() subpart.addheader("Content-Transfer-Encoding", "quoted-printable") pout = subpart.startbody("text/html", [("charset", 'us-ascii')]) mimetools.encode(htmlin, pout, 'quoted-printable') htmlin.close() # You 're done; close your writer and return the message body writer.lastpart() msg = out.getvalue() out.close() return msg
if _ _name_ _ == "_ _main_ _":
import smtplib
f = open("newsletter.html", 'r')
html = f.read()
f.close()
try:
f = open("newsletter.txt", 'r')
text = f.read()
except IOError:
text = None
subject = "Today's Newsletter!"
message = createhtmlmail(subject, html, text)
server = smtplib.SMTP("localhost")
server.sendmail('agillesp@i-noSPAMSUCKS.com',
'agillesp@i-noSPAMSUCKS.com', message)
server.quit()