Resource mentioned in this lesson: Common MIME Types
Join us and get access to thousands of tutorials and a community of expert Pythonistas.
This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.
Showing More Message Features
00:00 In the previous lesson, I showed you how to add alternate HTML text to your message. In this lesson, I’ll show you a few more message features.
00:08
Let’s talk about some more things you can add to your email message, including multiple recipients, using the CC and BCC fields, adding a reply-to field, using an Address class instead of plain text to indicate your recipients, and file attachments.
00:27 Remember when I said email is a text-based medium? I think I even said I’d say it again. Well, it is. When you attach a binary file, like an image or an audio file, you have to convert it into text first.
00:40
This is known as encoding. The most common mechanism for doing this in email is base64. Binary data is made up of bytes, each byte being a number between 0 and 255.
00:52
Those correspond to the values of the ASCII table, but not all of them are printable. For example, one of the ASCII values makes your computer go beep. What base64 does is use a subset of the ASCII table, 64 characters to be precise, and then translates each byte into multiple printable characters.
01:11
Of course, this increases the size of the result. Including a bit of metadata, the expansion is a little more than a third in size. You can perform this kind of encoding using the b64encode() function in the base64 Python module.
01:26
Its partner b64decode() undoes the encoding as well. Thankfully though, you don’t have to do any of that if you’re using email, as the EmailMessage class has a method that does all that for you.
01:40 In addition to attaching the translated content, you also want to add some meta information like the name of the file and what kind of file it is. You do this by adding mail headers.
01:51 I’ve mentioned MIME a few times now. Let’s dig into it a tiny bit more. MIME stands for Multipurpose Internet Mail Extensions. It’s a standard for describing what file content is involved in a data exchange.
02:05 You may have seen it used in other places than email as well, though. In fact, HTML uses it to specify types. A MIME type has a primary type and a subtype, separated by a slash.
02:17 Some common examples are image/jpeg, audio/mpeg, and video/mp4. There are hundreds of specifications in the current standard. For a full list of them, visit Mozilla’s comprehensive documentation.
02:31 OK, let’s go add attachments and fancier addresses to our program.
02:36
A new lesson, a new copy of our code. This one is more_send.py. The first change I’ll highlight is the use of the Address class.
02:45
This is part of the email module and provides an abstraction for email addresses. This is how you add a display name to any address. To attach a file, I need its contents. I’m going to use the pathlib module to read the file in and get at those contents.
03:01 This version of our program has lots of new address mechanisms. Here, I’m defining a variable for our reply-to field. If you’ve never seen these before, it tells the email client to use a different email address than the sender when replying.
03:15 They commonly get used by corporations so that a reply can be sent to a common inbox instead of the original sender’s address. I’m going to demonstrate several changes to our recipient fields. First, I’ll show you how to send to multiple people.
03:30 These two addresses are going to be used for that. CC means carbon copy. The idea predates email and is actually something that used to get put on memos, telling the secretary to prepare more copies for other people besides the original recipient.
03:45
For our CC field, I’m using an Address object. This isn’t CC specific. You can use one of these objects anywhere you specify an address in the EmailMessage object.
03:57
The main use of the Address object is to add the display name part to an addressee. BCC means blind carbon copy. That’s like CC, but the main recipient doesn’t see that you sent it to that person as well.
04:10
Very sneaky. Now that I’ve got the addressees all set up, it’s time to deal with our attachment. First, I specify the name of the file to load as a Path object.
04:20
Note, the file is included in the sample code in the Supporting Materials dropdown if you need it. Attachments work with binary contents. Path objects have a read_bytes() method that fetches the binary from the file.
04:33 Here, I’m storing all of it away for use in a second.
04:38
You probably guessed that the reply-to field is simply another key. I’ve set the value here. All of our recipient fields support three modes, plain text, Address object, and a list.
04:50
The list can contain plain text and Address objects. If you want multiple recipients, you pass in a list like I have here. Then this is our CC and BCC fields, and the EmailMessage object takes care of all the headers that go with this stuff.
05:06
To attach a file, you use the add_attachment() method. It takes a few arguments. The first is the bytes to encode and attach. The second is the main MIME specifier, and the third is the subtype MIME specifier.
05:22
The last argument is what name the file goes by. This doesn’t have to be the name of the file you encoded, but it’s the logical choice and what I’ve used here by turning our Path object into a string.
05:34
After that, it’s the usual send_message(), and you’re good to go. Once more, I’m going to run the server and client in the background and skip to the output.
05:44 And here it is. The first difference is the reply-to header. And because the to field had multiple recipients, inside the header you get a comma-separated list.
05:55
This is our CC field. Recall that I used an Address object here. The format for an email address with display name puts the name first and then the address in angle brackets.
06:06 Notice that there is no BCC header here. This is because what you’re seeing is the message going to the recipient who doesn’t get to know someone was BCC’d.
06:16 The BCC’s recipient will get something slightly different, including a BCC header so they know why they’re getting something that wasn’t addressed to them.
06:25 The attachment changes our Content-Type to be multipart/ mixed. It uses the same boundary concept as before.
06:33 At the top here is the text body, and then this is the start of the attachment section. Like with the HTML alternate, our attachment gets its own headers.
06:44
The MIME type here specifies that I attached a JPEG. Then the encoding header says how the image got encoded, using the aforementioned base64 in this case.
06:53
The disposition header is where you find the suggested filename, smiley.jpg here. And this big mess of text is the base64 encoded data. This goes on for quite some while, so I won’t bore you with all of it.
07:07 And after the encoded stuff, you’ll get another boundary marker just like in the HTML alternate you saw before.
07:14 You’ve got the main idea behind sending mail, so you’re ready to graduate from dev. Next up, connecting to real-world servers.
Become a Member to join the conversation.