Sending Email With Python
Sending Email With Python
Sending an Email
T
his chapter helps you understand the process of sending an email using
Python. More important, this chapter is generally about helping you under-
use when performing other tasks. For example, when working with an external
So, the information you see in this chapter can help you understand all sorts of
communication needs.
To make working with email as easy as possible, this chapter uses standard mail
modeled on real-world mail. Originally, the term email was used for any sort of
electronic document transmission, and some forms of it required the sender and
downloadable source code for the examples in this chapter in the BPPD_17_
Sending_an_Email.ipynb
actually work as intended. The following sections examine what happens when
When you work with email, you see a lot of references to Simple Mail Transfer Protocol
(SMTP). Of course, the term looks really technical, and what happens under the covers
truly is technical, but all you really need to know is that it works. On the other hand,
understanding SMTP a little more than as a “black box” that takes an email from the
sender and spits it out at the other end to the recipient can be useful. Taking the term
apart (in reverse order), you see these elements:
Documents are sent from one place to another, much the same as
on short commands that your email application issues to the SMTP server. For
example, the MAIL FROM command tells the SMTP server who is sending the email,
while the RCPT TO command states where to send it.
•
The fewer parts to anything, the more reliable it becomes.
why most of them appear to work about the same (even though their resources and
324 PART 4
-
ments the rules found in RFC1123 (see http://www.faqs.org/rfcs/rfc2821.html
for details). The point is, a whole lot of rules are written in jargon that only a true geek
want the shortest possible description of SMTP, page 4 is probably the right place to look.
The same can be said of email. An email actually consists of these components:
• Header: The part of the email content that includes the subject, the list of
recipients, and other features, such as the urgency of the email.
• Body: The part of the email content that contains the actual message.
The message can be in plain text, formatted as HTML, and consisting of
one or more documents, or it can be a combination of all these elements.
1.
2. The email application uses the account information to contact the SMTP server
and send the message for you.
3. The SMTP server reads only the information found in the message envelope
and redirects your email to the recipient.
4. The recipient email application logs on to the local server, picks up the email,
and then displays only the message part for the user.
email application is replaced by you on one end and the recipient at the other. The
both cases.
contains:
» The host is akin to the city and state used by a physical mail envelope. A
host address is the address used by the card that is physically connected to
of ways, but the host address for all these uses is the same.
»
example, an SMTP server used for outgoing messages normally relies on port 25.
However, the Point-of-Presence (POP3) server used for incoming email messages
with websites. However, secure websites (those that use https as a protocol,
rather than http) rely on port 443 instead. You can see a list of typical ports at
http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers.
326 PART 4
Python takes care of these details behind the scenes for you, so normally
information is available.
A host address
The connection used to access a combination of a host address and a port is called
a socket.
useful in understanding how email works. The following steps help you see host-
names and host addresses at work. More important, you begin to understand the
1.
BPPD_17_Sending_an_Email.
ipynb, which contains the application code.
2. import socket
Before you can work with sockets, you must import the socket library. This
library contains all sorts of confusing attributes, so use it with caution.
However, this library also contains some interesting functions that help you
3. print(socket.gethostbyname(“localhost”))
127.0.0.1 as
output because localhost is a standard hostname. The address, 127.0.0.1,
is associated with the host name, localhost.
4. print(socket.gethostbyaddr(“127.0.0.1”))
However, instead of getting localhost as the name of the host, you get the
name of your machine. You use localhost as a common name for the local
machine, but when you specify the address, you get the machine name
5. print(socket.gethostbyname(“www.johnmuellerbooks.com”))
The addresses
that you use to
send email are
unique across the
A port
time you use a host address, the port is implied. Access is always granted using a
combination of the host address and the port. The following steps help illustrate
1. import socket
Remember that a socket provides both host address and port information. You
use the socket to create a connection that includes both items.
328 PART 4
2. socket.getaddrinfo(“localhost”, 110)
need them. However, the last entry, ('127.0.0.1', 110), shows the address
and port for localhost port 110.
The localhost
host provides
3.
http://www.networkcomputing.com/networking/
six-benefits-of-ipv6/d/d-id/1232791
locations provide
address.
4. socket.getservbyport(25)
socket.getservbyport()
method provides the means to determine how a particular port is used.
Port 25 is always dedicated to SMTP support on any server. So, when you
on every server.
assignments as a security feature. Always get into the habit of using the port
A hostname
1. import socket
2. socket.gethostname()
you use.
Sometimes you
need to know the
name of the local
system.
330 PART 4
3. socket.gethostbyname(socket.gethostname())
method you can use in your applications to determine the address of the
Avoid using
hard-coded
values for the
local system
whenever
possible.
you see the email in your email application, all that is present is the letter, not the
that matter, neither the sender nor the recipient information may be correct in the
letter that you see onscreen in your email reader.
»
just the email address of the sender.
» The receiver information tells you who will receive the message. This is
actually a list of recipient email addresses. Even if you want to send the message
to only one person, you must supply the single email address in a list.
• Visible recipients who also received the message, even though they
email that is sent, a message could include all sorts of additional information.
-
mation you need to send an email from your application. The following sections
describe the process used to generate a letter and its components in more detail.
»
»
» Allows a single message to contain multiple subparts, such
as including both text and graphics in a single message
» -
dardized format
332 PART 4
Although you can create any sort of an email message with Python, the easiest type
to create is one that contains plain text. The lack of formatting in the content lets
you focus on the technique used to create the message, rather than on the message
content. The following steps help you understand how the message-creating
1.
from email.mime.text import MIMEText
msg = MIMEText("Hello There")
msg['Subject'] = "A Test Message"
msg['From']='John Mueller <John@JohnMuellerBooks.com>'
msg['To'] = 'John Mueller <John@JohnMuellerBooks.com>'
This is a basic plain-text message. Before you can do anything, you must
import the required class, which is MIMEText
email.mime
module as a whole.
The MIMEText() constructor requires message text as input. This is the body
At this point, you assign values to standard attributes. The example shows
Subject, From, and To.
From and To, contain both a human-readable name
and the email address. All you have to include is the email address.
2. msg.as_string()
The Content-Type
plain-text message. The charset tells what kind of characters are used in the
message so that the recipient knows how to handle them. The MIME-Version
-
lope is used to transfer the message from one location to another. The process of
-
the particulars of the transmission. The following steps help you understand the
result in a successful transmission unless you modify them to match your setup.
1.
import smtplib
s = smtplib.SMTP('localhost')
2. s.sendmail(‘SenderAddress RecipientAddress
For this step to work, you must replace SenderAddress and RecipientAddress
typed everything correctly, try sending the message a second time before you
panic. See the sidebar “Considering the SMTP server” for additional details.
334 PART 4
This is the step that actually creates the envelope, packages the email mes-
recipient information separately from the message, which the SMTP server
someone a text message, you need to know what sort of text it is before you can
seeing the type, so messages require a subtype. The type is text and the subtype
message.
-
types at http://www.freeformatter.com/mime-types-list.html. The nice
extension associated with the subtype and a reference to obtain additional infor-
mation about it.
put them together and see how they actually work. The following sections show
1.
from email.mime.text import MIMEText
import smtplib
msg = MIMEText("Hello There!")
msg['Subject'] = 'A Test Message'
msg['From']='SenderAddress'
msg['To'] = 'RecipientAddress'
s = smtplib.SMTP('localhost')
s.sendmail('SenderAddress',
['RecipientAddress'],
msg.as_string())
print("Message Sent!")
real life).
SenderAddress and
RecipientAddress with real addresses. These entries are meant only as
placeholders. As with the example in the previous section, you may also
encounter errors when other situations occur, so always try to send the
2.
The application tells you that it has sent the message to the recipient.
has an SMTP server connected to localhost. The reason for the examples to use
localhost is to provide a placeholder that you replace later with the information for your
particular setup.
336 PART 4
world email account. Of course, you could install all the software required to create
such an environment on your own system, and some developers who work extensively
with email applications do just that. Most platforms come with an email package that
you can install, or you can use a freely available substitute such as Sendmail, an open
source product available for download at https://www.sendmail.com/sm/open_
source/download/. The easiest way to see the example work is to use the same SMTP
server that your email application uses. When you set up your email application, you
either asked the email application to detect the SMTP server or you supplied the SMTP
-
tain the required information. The exact location of this information varies widely by
email application, so you need to look at the documentation for your particular product.
on that server in most cases to use the functionality it provides. Replace the information
in the examples with the information for your SMTP server, such as smtp.myisp.com,
along with your email address for both sender and receiver. Otherwise, the example
1.
from email.mime.text import MIMEText
import smtplib
msg = MIMEText(
"<h1>A Heading</h1><p>Hello There!</p>","html")
msg['Subject'] = 'A Test HTML Message'
msg['From']='SenderAddress'
msg['To'] = 'RecipientAddress'
s = smtplib.SMTP('localhost')
s.sendmail('SenderAddress',
['RecipientAddress'],
msg.as_string())
print("Message Sent!")
The most important part of this example is the text that comes after the
message. The "html" argument changes the subtype from text/plain to
text/html
2.
The application tells you that it has sent the message to the recipient.
application.)
338 PART 4
-
are the essentials of creating and transmitting the message using the correct
arguments.