Emailing automated messages using Python was on my bucket list for a few projects, so here I will illustrate how to do that within SPSS. Basically the use case is if you have an automated report generated by SPSS and you want to send that automated report to certain parties (or to yourself while you are away from work). Emailing right within Python cuts out the middle annoying task of having to email yourself.
There are basically two parts of emailing within Python, 1) building the message and 2) opening your server and sending the mail. The latter is pretty simple, the former is quite tedious though. So adapting from several posts around the internet (1,2,3 plus others I don’t remember at this point), here is a function to build the email text.
*function to build message. BEGIN PROGRAM Python. from os.path import basename from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.MIMEBase import MIMEBase from email import Encoders from email.utils import COMMASPACE, formatdate def make_mail(send_from, send_to, subject, text, files=None): assert isinstance(send_to, list) msg = MIMEMultipart( From=send_from, To=COMMASPACE.join(send_to), Date=formatdate(localtime=True), Subject=subject ) msg.attach(MIMEText(text)) if files != None: for f in files: part = MIMEBase('application', 'base64') part.set_payload(open(f,"rb").read()) part.add_header('Content-Disposition', 'attachment', filename=basename(f)) Encoders.encode_base64(part) msg.attach(part) return msg.as_string() END PROGRAM.
The function subsequently takes as arguments:
send_from: Your email address as a string
send_to: A list of email addresses to send to.
subject: A text string for the subject (please use a subject when you send an email!)
text: The text composition of the email in a string
files: A list of files with the full directory
Basically an email message is just a particular text format (which actually looking at the markup I’m slightly amazed email still functions at all). Building the markup for the to, from, subject and text in the email is tedious but relatively straightforward. However, attaching files (the main motivation for this to begin with!) is rather a pain in the butt. Here I just encode all the files in base64, and CSV, PDF, and PNG files have all worked out so far for me in my tests. (You can attach images as binary, but this approach seems to work fine at least for PNG images.)
So here is an example constructing a message, and I attach three example files. Here I just use my gmail address as both the from and to address. You can uncomment the
print MyMsg at the end to see the particular markup, but it is quite long with the base64 attached files.
*Now lets make a message. BEGIN PROGRAM Python. us = "apwheele" fr = us + "@gmail.com" to = [fr] te = "Hello!" MyCSV = [r"C:\Users\andrew.wheeler\Dropbox\Documents\BLOG\Email_Python\Test.csv", r"C:\Users\andrew.wheeler\Dropbox\Documents\BLOG\Email_Python\Test.pdf", r"C:\Users\andrew.wheeler\Dropbox\Documents\BLOG\Email_Python\OUTPUT0.PNG"] MyMsg = make_mail(send_from=fr,send_to=to,subject="Test",text=te,files=MyCSV) #print MyMsg END PROGRAM.
The second part is opening your email server and sending the message — relatively straight forward. Many people have their python functions for emailing with the username and password as part of the function. This does not make much sense to me, as they will be basically constants for a particular user, so I find it simpler to make the message and then open the server and send it. If you want to send multiple messages it makes more sense to open up the server just once. Below to make it work for yourself you just have to insert your own username and password (and possibly update the port number for your server).
*Now set up the server and send a message. BEGIN PROGRAM Python. us = "!!Your Username!!" pa = "!!Your Password!!" import smtplib server = smtplib.SMTP('smtp.gmail.com',587) server.starttls() server.login(us,pa) server.sendmail(fr,to, MyMsg) server.quit() END PROGRAM.
I don’t have Outlook on any of my personal machines, but hopefully it is just as simple when sending an email through a client as it is through gmail.