Sending e-mails with SMTP

We can send an e-mail from a Python script by using smtplib and e-mail packages. The smtplib module provides an SMTP objects which is used for sending mail by using either an SMTP or an Extended SMTP (ESMTP) protocol. The e-mail module helps us in constructing the e-mail messages with the help of the various header information and attachments. This module conforms to the Internet Message Format (IMF) described at http://tools.ietf.org/html/rfc2822.html.

Composing an e-mail message

Let us construct the e-mail message by using classes from the email module. The email.mime module provides classes for creating the e-mail and MIME objects from scratch. MIME is an acronym for Multi-purpose Internet Mail Extensions. This is an extension of the original Internet e-mail protocol. This is widely used for exchanging different kinds of data files, such as audio, video, images, applications, and so on.

Many classes have been derived from the MIME base class. We will use an SMTP client script using email.mime.multipart.MIMEMultipart() class as an example. It accepts passing the e-mail header information through a keyword dictionary. Let's have a look at how we can specify an e-mail header by using the MIMEMultipart() object. Multi-part mime refers to sending both the HTML and the TEXT part of an e-mail message in a single e-mail. When an e-mail client receives a multipart message, it accepts the HTML version if it can render HTML, otherwise it presents the plain text version, as shown in the following code block:

    from email.mime.multipart import MIMEMultipart()
    msg = MIMEMultipart()
    msg['To'] = recipient
    msg['From'] = sender
    msg['Subject'] = 'Email subject..'

Now, attach a plain text message to this multi-part message object. We can wrap a plain-text message by using the MIMEText() object. The constructor of this class takes the additional arguments. For example, we can pass text and plain as its arguments. The data of this message can be set by using the set_payload() method, as shown here:

    part = MIMEText('text', 'plain')
    message = 'Email message ….'
    part.set_payload(message)

Now, we will attach the plain text message to the Multi-part message, as shown here:

    msg.attach(part)

The message is ready to be routed to the destination mail server by using one or more SMTP MTA servers. But, obviously, the script only talks to a specific MTA and that MTA handles the routing of the message.

Sending an e-mail message

The smtplib module supplies us with an SMTP class, which can be initialized by an SMTP server socket. Upon successful initialization, this will give us an SMTP session object. The SMTP client will establish a proper SMTP session with the server. This can be done by using the ehlo() method for an SMTP session object. The actual message sending will be done by applying the sendmail() method to the SMTP session. So, a typical SMTP session will look like the following:

    session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
    session.ehlo()
    session.sendmail(sender, recipient, msg.as_string())
    session.quit()

In our example SMTP client script, we have made use of Google's free Gmail service. If you have a Gmail account, then you can send an e-mail from a Python script to that account by using SMTP. Your e-mail may get blocked initially, as Gmail may detect that it had been sent from a less secure e-mail client. You can change your Gmail account settings and enable your account to send/receive e-mails from less secure e-mail clients. You can learn more about sending e-mail from an app on the Google website, which can be found at https://support.google.com/a/answer/176600?hl=en.

If you don't have a Gmail account, then you can use a local SMTP server setup in a typical Linux box and run this script. The following code shows how to send an e-mail through a public SMTP server:

#!/usr/bin/env python3
# Listing 1 – First email client
import smtplib

from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

SMTP_SERVER = 'aspmx.l.google.com'
SMTP_PORT = 25

def send_email(sender, recipient):
    """ Send email message """
    msg = MIMEMultipart()
    msg['To'] = recipient
    msg['From'] = sender
    subject = input('Enter your email subject: ')
    msg['Subject'] = subject
    message = input('Enter your email message. Press Enter when finished. ')
    part = MIMEText('text', "plain")
    part.set_payload(message)
    msg.attach(part)
    # create smtp session
    session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
    session.ehlo()
    #session.set_debuglevel(1)
    # send mail
    session.sendmail(sender, recipient, msg.as_string())
    print("You email is sent to {0}.".format(recipient))
    session.quit()

if __name__ == '__main__':
    sender = input("Enter sender email address: ")
    recipient = input("Enter recipient email address: ")
    send_email(sender, recipient)

If you run this script, then you can see that the output is similar to what is mentioned here. For the sake of anonymity, real e-mail addresses have not been shown in the following example:

$ python3 smtp_mail_sender.py 
Enter sender email address: <SENDER>@gmail.com 
Enter recipeint email address: <RECEIVER>@gmail.com
Enter your email subject: Test mail
Enter your email message. Press Enter when finished. This message can be ignored
You email is sent to <RECEIVER>@gmail.com.

This script will send a very simple e-mail message by using Python's standard library module, smtplib. For composing the message, MIMEMultipart and MIMEText classes have been imported from the email.mime submodule. This submodule has various types of classes for composing e-mail messages with different types of attachments, for example, MIMEApplication(), MIMEAudio(), MIMEImage(), and so on.

In this example, the send_mail() function has been called by two arguments: sender and receiver. Both of these arguments are e-mail addresses. An e-mail message is constructed by the MIMEMultipart() message class. The essential headers, such as To, From, and Subject have been added to this class namespace. The body of the message is composed with the instance of the MIMEText() class. This is done by the class set_payload() method. Then, this payload is attached to the main message by the attach() method.

In order to communicate with the SMTP server, a session with the server will be created by instantiating the smtplib module's SMTP() class. The server name and the port arguments will be passed to the constructor. According to the SMTP protocol, an extended hello message through ehlo() method will be sent by the client to the server. The message will be sent by the sendmail() method.

Notice that if the set_debuglevel() method is called on an SMTP session object, then it will produce additional debug messages. The line is commented out in the preceding example. Un-commenting that line will produce a debug message such as:

$ python3 smtp_mail_sender.py 
Enter sender email address: <SENDER>@gmail.com
Enter recipeint email address: <RECEIVER>@gmail.com
Enter your 
email subject: Test email
Enter your email message. Press Enter when finished. This is a test email
send: 'mail FROM:<[email protected]> size=339
'
reply: b'250 2.1.0 OK hg2si4622244wib.38 - gsmtp
'
reply: retcode (250); Msg: b'2.1.0 OK hg2si4622244wib.38 - gsmtp'
send: 'rcpt TO:<[email protected]>
'
reply: b'250 2.1.5 OK hg2si4622244wib.38 - gsmtp
'
reply: retcode (250); Msg: b'2.1.5 OK hg2si4622244wib.38 - gsmtp'
send: 'data
'
reply: b'354  Go ahead hg2si4622244wib.38 - gsmtp
'
reply: retcode (354); Msg: b'Go ahead hg2si4622244wib.38 - gsmtp'
data: (354, b'Go ahead hg2si4622244wib.38 - gsmtp')
send: 'Content-Type: multipart/mixed; 
boundary="===============1431208306=="
MIME-Version: 1.0
To: [email protected]
From: [email protected]
Subject: Test  email

--===============1431208306==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content- Transfer-Encoding: 7bit

This is a test email
-- ===============1431208306==--
.
'
reply: b'250 2.0.0 OK 1414233177 hg2si4622244wib.38 - gsmtp
'
reply: retcode (250); Msg: b'2.0.0 OK 1414233177 hg2si4622244wib.38 - gsmtp'
data: (250, b'2.0.0 OK 1414233177 hg2si4622244wib.38 - gsmtp')
You email is sent to [email protected].
send: 'quit
'
reply: b'221 2.0.0 closing connection hg2si4622244wib.38 - gsmtp
'
reply: retcode (221); Msg: b'2.0.0 closing connection hg2si4622244wib.38 - gsmtp'

This is interesting because the message has been sent through a public SMTP server in a step-by-step fashion.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.5.201