Sending Emails Via Gmail SMTP With Python

This is the third post in the article series “Playing With Python And Gmail”. This will be a tutorial on how to send mails using Python smtplib through Gmail SMTP.
The smtplib module defines an SMTP client session object that can be used to send mail to any Internet machine with an SMTP or ESMTP listener daemon.
[vinod@mercury ~]$ python Python 2.5.2 (r252:60911, Jan 24 2010, 14:53:14) [GCC 4.3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import smtplib
The first step is to create a SMTP connection to the server. The smtplib.SMTP class encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional host and port parameters are given, the SMTP connect() method is called with those parameters during initialization. An SMTPConnectError is raised if the specified host doesn’t respond correctly. The optional timeout parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used).
Remember Google’s SMTP server is ‘smtp.gmail.com’ and the port is 587.
>>> session = smtplib.SMTP('smtp.gmail.com', 587) |
Next we will identify ourself to an ESMTP server using EHLO. The SMTP HELO clause is the stage of the SMTP protocol where a SMTP server introduce them selves to each other. EHLO is just like HELO except that the server’s response text provides computer-readable information about the server’s abilities.
>>> session.ehlo() (250, 'mx.google.com at your service, [x.x.x.x]\nSIZE 35651584\n8BITMIME\nSTARTTLS\nENHANCEDSTATUSCODES') |
Next we call SMTP.starttls function to put the SMTP connection in TLS (Transport Layer Security) mode. All SMTP commands that follow will be encrypted. You should then call ehlo() again.
If keyfile and certfile are provided, these are passed to the socket module’s ssl() function.If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first.
>>> session.starttls() (220, '2.0.0 Ready to start TLS') >>> session.ehlo > >>> |
OK, now we are safe to login to the server using SMTP.login(user, password). After successful login we use SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]) to send mails via Gmail.
>>> session.login('username@gmail.com', 'topsecret') (235, '2.7.0 Accepted') |
We will cerate some SMTP headers before sending our mail.
headers = ["from: " + sender, "subject: " + subject, "to: " + recipient, "mime-version: 1.0", "content-type: text/html"] headers = "\r\n".join(headers) |
Finally send our mail
session.sendmail(sender, recipient, headers + "\r\n\r\n" + body) |
Sample code
#!/usr/bin/python import smtplib SMTP_SERVER = 'smtp.gmail.com' SMTP_PORT = 587 sender = 'you@gmail.com' recipient = 'user@example.com' subject = 'Gmail SMTP Test' body = 'blah blah blah' "Sends an e-mail to the specified recipient." body = "" + body + "" headers = ["From: " + sender, "Subject: " + subject, "To: " + recipient, "MIME-Version: 1.0", "Content-Type: text/html"] headers = "\r\n".join(headers) session = smtplib.SMTP(server, port) session.ehlo() session.starttls() session.ehlo session.login(sender, password) session.sendmail(sender, recipient, headers + "\r\n\r\n" + body) session.quit() |
Sending Attachments
The email package is a library for managing email messages, including MIME and other RFC 2822-based message documents. The central class in the email package is the Message class, imported from the email.message module. It is the base class for the email object model. Message provides the core functionality for setting and querying header fields, and for accessing message bodies. This is the base class for all the MIME-specific subclasses of Message. Ordinarily you won’t create instances specifically of MIMEBase, although you could. MIMEBase is provided primarily as a convenient base class for more specific MIME-aware subclasses.
We import MIMEMultipart class, a sub class of MIMEBase to create the enclosing (outer) message.
from email.MIMEMultipart import MIMEMultipart msg = MIMEMultipart() msg['From'] = sender msg['To'] = recipient msg['Subject'] = subject |
The MIMEImage class is used to create MIME message objects of major image types. We create a MIMEImage object containing out raw image data and attach it to our outer message.
from email.MIMEImage import MIMEImage img = MIMEImage(open("test.gif","rb").read(), _subtype="gif") img.add_header('Content-Disposition', 'attachment; filename="test.gif"') msg.attach(img) |
Finally we create MIMEText object to add some plain text to our mail.The MIMEText class is used to create MIME objects of type text.
from email.MIMEText import MIMEText part = MIMEText('text', "plain") part.set_payload("Image attached.") msg.attach(part) |
Now send the mail
session.sendmail(sender, recipient, msg.as_string()) |
You can create MIME objects for audio, application etc. Find the documentation here.
A Simple Example
Send all .gif files in a directory as attachment.
#!/usr/bin/python import os, re import sys import smtplib from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText SMTP_SERVER = 'smtp.gmail.com' SMTP_PORT = 587 sender = 'you@gmail.com' password = "secret" recipient = 'user@example.com' subject = 'Python emaillib Test' message = 'Images attached.' directory = "/tmp/images/" def main(): msg = MIMEMultipart() msg['Subject'] = 'Python emaillib Test' msg['To'] = recipient msg['From'] = sender files = os.listdir(directory) gifsearch = re.compile(".gif", re.IGNORECASE) files = filter(gifsearch.search, files) for filename in files: path = os.path.join(directory, filename) if not os.path.isfile(path): continue img = MIMEImage(open(path, 'rb').read(), _subtype="gif") img.add_header('Content-Disposition', 'attachment', filename=filename) msg.attach(img) part = MIMEText('text', "plain") part.set_payload(message) msg.attach(part) session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) session.ehlo() session.starttls() session.ehlo session.login(sender, password) session.sendmail(sender, recipient, msg.as_string()) session.quit() if __name__ == '__main__': main() |
Recent Comments