Skip to content

Instantly share code, notes, and snippets.

@bryhal
Created November 4, 2012 01:04
Show Gist options
  • Select an option

  • Save bryhal/4009671 to your computer and use it in GitHub Desktop.

Select an option

Save bryhal/4009671 to your computer and use it in GitHub Desktop.
PYTHON: SMTP Email with HTML and Multiple Attachments
import smtplib, os, re, sys, glob, string, datetime
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
from HTMLParser import HTMLParser
class MLStripper(HTMLParser):
def __init__(self):
self.reset()
self.fed = []
def handle_data(self, d):
self.fed.append(d)
def get_data(self):
return ''.join(self.fed)
def strip_tags(html):
s = MLStripper()
s.feed(html)
return s.get_data()
# Found this at http://ryrobes.com/python/python-snippet-sending-html-email-with-an-attachment-via-google-apps-smtp-or-gmail/
# Adapted to accept a list of files for multiple file attachments
# From other stuff I googled, a little more elegent way of converting html to plain text
# This works and my brain gets it. In my application, there will always be at least 1 attachment - you might want to test for that
attachments = ['test_pdf.pdf', 'test_waiver.pdf']a
username = '[email protected]'
password = 'fg23io98'
server = 'smtp.gmail.com:587' # specify port if required using this notation
fromaddr = '[email protected]' #must be a vaild 'from' addy in your GApps account
toaddr = '[email protected]'
replyto = fromaddr #unless you want a different reply-to
msgsubject = 'This is for the email subject!'
htmlmsgtext = """<h1>This is my message body in HTML</h1>
<p>Yup, Yup, Yup, got a paragraph here. A lovely paragraph it is.</p>
<p><strong>Here are your attachments:</strong></p><br />"""
############### In normal use nothing changes below this line ######################
try:
# Make text version from HTML - First convert tags that produce a line break to carriage returns
msgtext = htmlmsgtext.replace('</br>',"\r").replace('<br />',"\r").replace('</p>',"\r")
# Then strip all the other tags out
msgtext = strip_tags(msgtext)
# msgtext = re.sub('<.*?>','',msgtext)
#pain the ass mimey stuff
msg = MIMEMultipart()
msg.preamble = 'This is a multi-part message in MIME format.\n'
msg.epilogue = ''
body = MIMEMultipart('alternative')
body.attach(MIMEText(msgtext))
body.attach(MIMEText(htmlmsgtext, 'html'))
msg.attach(body)
if 'attachments' in globals(): # should be testing if len('attachments') > 0, oh well....
for filename in attachments:
f = filename
part = MIMEBase('application', "octet-stream")
part.set_payload( open(f,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
msg.attach(part)
msg.add_header('From', fromaddr)
msg.add_header('To', toaddr)
msg.add_header('Subject', msgsubject)
msg.add_header('Reply-To', replyto)
# The actual email sendy bits
server = smtplib.SMTP(server)
# server.set_debuglevel(True) #commenting this out, changing to False will make the script give NO output at all upon successful completion
server.starttls()
server.login(username,password)
server.sendmail(msg['From'], [msg['To']], msg.as_string())
server.quit() #bye bye
print 'Email sent'
except:
print ('Email NOT sent to %s successfully. %s ERR: %s %s %s ', str(toaddr), 'tete', str(sys.exc_info()[0]), str(sys.exc_info()[1]), str(sys.exc_info()[2]) )
#just in case
@fri3ndlygiant
Copy link

Looks great! How would I send a whole folder?

@VictoryChang
Copy link

Thank you for sharing!

@andyp14feb
Copy link

andyp14feb commented Feb 14, 2020

In this Part : **if 'attachments' in globals() and len('attachments') > 0: # are there attachments?**

condition len('attachments') > 0 will always true , you should write it as len(attachments) > 0 (wihtout the quote characters) then it will check wether the attachment list contain something or empty

note: I am using python 3.4 right now

@araidz
Copy link

araidz commented May 7, 2021

Looks great! How would I send a whole folder?

Make a list of files in the directory and iterate over the list.

@powerscooter
Copy link

Thanks for the code!! Is there a way to send mails to multiple receivers?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment