How do I send attachments?

How do I send attachments using SMTP?

  • I want to write a program that sends email using Python's http://docs.python.org/library/smtplib.html. I searched through the document and the RFCs, but couldn't find anything related to attachments. Thus, I'm sure there's some higher-level concept I'm missing out on. Can someone clue me in on how attachments work in SMTP?

  • Answer:

    What you want to check out is the email module. It lets you build http://en.wikipedia.org/wiki/MIME-compliant messages that you then send with smtplib.

Jason Baker at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

Well, attachments are not treated in any special ways, they are "just" leaves of the Message-object tree. You can find the answers to any questions regarding MIME-compliant mesasges in http://docs.python.org/library/email.message.html section of the documentation on the http://docs.python.org/library/email.html python package. In general, any kind of attachment (read: raw binary data) can be represented by using base64 (or similar) Content-Transfer-Encoding.

shylent

Here's an example I snipped out of a work application we did. It creates an HTML email with an Excel attachment. import smtplib,email,email.encoders,email.mime.text,email.mime.base smtpserver = 'localhost' to = ['[email protected]'] fromAddr = '[email protected]' subject = "my subject" # create html email html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">' html +='<body style="font-size:12px;font-family:Verdana"><p>...</p>' html += "</body></html>" emailMsg = email.MIMEMultipart.MIMEMultipart('alternative') emailMsg['Subject'] = subject emailMsg['From'] = fromAddr emailMsg['To'] = ', '.join(to) emailMsg['Cc'] = ", ".join(cc) emailMsg.attach(email.mime.text.MIMEText(html,'html')) # now attach the file fileMsg = email.mime.base.MIMEBase('application','vnd.ms-excel') fileMsg.set_payload(file('exelFile.xls').read()) email.encoders.encode_base64(fileMsg) fileMsg.add_header('Content-Disposition','attachment;filename=anExcelFile.xls') emailMsg.attach(fileMsg) # send email server = smtplib.SMTP(smtpserver) server.sendmail(fromAddr,to,emailMsg.as_string()) server.quit()

Mark

Here is an example of a message with a PDF attachment, a text "body" and sending via Gmail. # Import smtplib for the actual sending function import smtplib # For guessing MIME type import mimetypes # Import the email modules we'll need import email import email.mime.application # Create a text/plain message msg = email.mime.Multipart.MIMEMultipart() msg['Subject'] = 'Greetings' msg['From'] = '[email protected]' msg['To'] = '[email protected]' # The main body is just another attachment body = email.mime.Text.MIMEText("""Hello, how are you? I am fine. This is a rather nice letter, don't you think?""") msg.attach(body) # PDF attachment filename='simple-table.pdf' fp=open(filename,'rb') att = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf") fp.close() att.add_header('Content-Disposition','attachment',filename=filename) msg.attach(att) # send via Gmail server # NOTE: my ISP, Centurylink, seems to be automatically rewriting # port 25 packets to be port 587 and it is trashing port 587 packets. # So, I use the default port 25, but I authenticate. s = smtplib.SMTP('smtp.gmail.com') s.starttls() s.login('[email protected]','xyzpassword') s.sendmail('[email protected]',['[email protected]'], msg.as_string()) s.quit()

Kevin Buchs

Here's how to send e-mails with zip file attachments and utf-8 encoded subject+body. It was not straightforward to figure this one out, due to lack of documentation and samples for this particular case. Non-ascii characters in replyto needs to be encoded with, for instance, ISO-8859-1. There probably exists a function that can do this. Tip: Send yourself an e-mail, save it and examine the content to figure out how to do the same thing in Python. Here's the code, for Python 3: #!/usr/bin/env python3 # -*- coding: utf-8 -*- # vim:set ts=4 sw=4 et: from os.path import basename from smtplib import SMTP from email.mime.text import MIMEText from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.header import Header from email.utils import parseaddr, formataddr from base64 import encodebytes def send_email(recipients=["[email protected]"], subject="Test subject æøå", body="Test body æøå", zipfiles=[], server="smtp.somewhere.xyz", username="bob", password="password123", sender="Bob <[email protected]>", replyto="=?ISO-8859-1?Q?M=F8=F8=F8?= <[email protected]>"): #: bool """Sends an e-mail""" to = ",".join(recipients) charset = "utf-8" # Testing if body can be encoded with the charset try: body.encode(charset) except UnicodeEncodeError: print("Could not encode " + body + " as " + charset + ".") return False # Split real name (which is optional) and email address parts sender_name, sender_addr = parseaddr(sender) replyto_name, replyto_addr = parseaddr(replyto) sender_name = str(Header(sender_name, charset)) replyto_name = str(Header(replyto_name, charset)) # Create the message ('plain' stands for Content-Type: text/plain) try: msgtext = MIMEText(body.encode(charset), 'plain', charset) except TypeError: print("MIMEText fail") return False msg = MIMEMultipart() msg['From'] = formataddr((sender_name, sender_addr)) msg['To'] = to #formataddr((recipient_name, recipient_addr)) msg['Reply-to'] = formataddr((replyto_name, replyto_addr)) msg['Subject'] = Header(subject, charset) msg.attach(msgtext) for zipfile in zipfiles: part = MIMEBase('application', "zip") b = open(zipfile, "rb").read() # Convert from bytes to a base64-encoded ascii string bs = encodebytes(b).decode() # Add the ascii-string to the payload part.set_payload(bs) # Tell the e-mail client that we're using base 64 part.add_header('Content-Transfer-Encoding', 'base64') part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(zipfile)) msg.attach(part) s = SMTP() try: s.connect(server) except: print("Could not connect to smtp server: " + server) return False if username: s.login(username, password) print("Sending the e-mail") s.sendmail(sender, recipients, msg.as_string()) s.quit() return True def main(): send_email() if __name__ == "__main__": main()

Alexander

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.