Once upon a time (when I started learning Python) I wrote for one project:
import six import smtplib import email.utils import email.encoders from six.moves import email_mime_multipart # import email.mime.multipart from six.moves import email_mime_text # import email.mime.text from six.moves import email_mime_base # import email.mime.base def send_mail( send_to, subject, text, send_from, files=[], headers={}, cc=None, smtp_server='localhost', smtp_port=0, smtp_login=None, smtp_password=None ): """ sends email via SMTP server parameters: send_to - email recipient(s) [str | basestring | list] subject - subject string [str | basestring] text - email body [str | basestring] send_from - sender's email [str | basestring] files - list of attached files [list of strings] headers - custom headers [dict, like: {'X-My-Header':'My Header'}] cc - email CC recipient(s) [str | basestring | list] default: None smtp_server - SMTP hostname or IP [str | basestring] default: 'localhost' smtp_port - SMTP port default: 0 smtp_login - SMTP server login [str | basestring] default: None smtp_password - SMTP server password [str | basestring] default: None ) """ assert isinstance(send_to, list) or isinstance(send_to, six.string_types) assert isinstance(files, list) msg = email_mime_multipart.MIMEMultipart() msg['From'] = send_from msg['Date'] = email.utils.formatdate(localtime=True) msg['Subject'] = subject # convert the list of recipients to the comma-separated string if isinstance(send_to, list): msg['To'] = email.utils.COMMASPACE.join(send_to) elif isinstance(send_to, six.string_types): msg['To'] = send_to if cc: # convert the list of recipients to the comma-separated string if isinstance(cc, list): msg['Cc'] = email.utils.COMMASPACE.join(cc) elif isinstance(cc, six.string_types): msg['Cc'] = cc msg.attach(email_mime_text.MIMEText(text)) # attach file-attachments # use set in order to get rid of duplicates for f in set(files): part = email_mime_base.MIMEBase('application', 'octet-stream') part.set_payload(open(f, 'rb').read()) email.encoders.encode_base64(part) part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f)) msg.attach(part) # attach custom eMail headers if any for h in headers.keys(): msg[h] = headers[h] smtp = smtplib.SMTP(smtp_server, port=smtp_port) # perform authentication if both login and password were specified if smtp_login and smtp_password: smtp.starttls() smtp.login(smtp_login, smtp_password) smtp.sendmail(send_from, send_to, msg.as_string()) smtp.close()