DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Send Email With Attachment(s) In Python

  • submit to reddit
        Can't remember if I wrote this or found it on the Web or a combination, so I won't take credit per se -- I'm just posting it as reference.

import smtplib
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders

def send_mail(send_from, send_to, subject, text, files=[], server="localhost"):
  assert type(send_to)==list
  assert type(files)==list

  msg = MIMEMultipart()
  msg['From'] = send_from
  msg['To'] = COMMASPACE.join(send_to)
  msg['Date'] = formatdate(localtime=True)
  msg['Subject'] = subject

  msg.attach( MIMEText(text) )

  for f in files:
    part = MIMEBase('application', "octet-stream")
    part.set_payload( open(file,"rb").read() )
    part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))

  smtp = smtplib.SMTP(server)
  smtp.sendmail(send_from, send_to, msg.as_string())


Fanbin Kong replied on Tue, 2009/12/08 - 2:06am

it is good for me

Snippets Manager replied on Tue, 2007/06/05 - 10:43am

Thanks so much for this example, very useful! Is there an easier way to do this? With all the steps involved, I don't think I'll be memorizing it without error. It would be great to find a way more in line with the 'batteries included' philosophy of Python. This feels so much like sending email in Java (ick). Anyone recommend more simple ways to email with attachments in Python? It's nice to use the standard libraries for portability, but I would have to look this one up every time to get it right!

Snippets Manager replied on Fri, 2008/04/25 - 4:06pm

I found this useful, note the line: part.set_payload( open(file,"rb").read() ) should be: part.set_payload( open(f,"rb").read() ) (change file to f in the loop)

Snippets Manager replied on Mon, 2012/05/07 - 1:23pm

I changed "file" to "f" so built-in "file" won't get stepped on. I found this somewhere on the Web -- don't know if you could do it with less.

Snippets Manager replied on Thu, 2006/12/28 - 12:37am

do you need to import all those things? really. COMMASPACE???

Snippets Manager replied on Mon, 2006/12/04 - 4:10pm

I think geon was pointing out that the use of file in the for loop obscures the built-in file keyword.

Snippets Manager replied on Mon, 2012/05/07 - 1:23pm

ok, fixed the missing import, but I don't know what you mean by your second comment.

Snippets Manager replied on Wed, 2006/10/04 - 1:40pm

and: "file" should stay keyword

Snippets Manager replied on Wed, 2006/10/04 - 1:40pm

import os ... missing