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.
Formatting With HTML
00:00
In the previous lesson, I introduced you to Python’s smtplib and email modules. In this lesson, I’ll up my content game by adding optional HTML formatting to my mail message.
00:12 Email is a purely text-based medium. Remember that. I’ll likely say it again. But text doesn’t have to be boring. In fact, HTML is text-based as well. To make prettier email, you can include HTML formatting, and most email clients will display it.
00:29 The most in that sentence is important, because not all clients support it. The right way to use HTML is to attach it as an option. You could just embed HTML in your message body, but then a client that can’t read HTML would show the guts of the HTML. Instead, the mail body allows you to attach alternate body types. Sending both regular text and HTML is best practice. That way, the client can decide which to display. The other complication with HTML for email is that it’s a subset of the full HTML standard.
01:02 In fact, it isn’t quite a standard. It kind of grew organically because some of the cooler clients started to use it, and so it’s a bit of a mishmash of capabilities. Most email clients don’t support the header tag, which is where CSS style sheets get attached, so as a result, a lot of the modern styling mechanisms won’t work.
01:23 If you’re old enough to remember the web before CSS, you’ll remember the frustration of using HTML tables to provide formatting to the screen. Well, if you’re writing HTML for email, you can relive that little adventure.
01:36 Some clients do more, and some do less, so if you’re sending HTML email to a wide audience, you should do some googling to find out the latest recommendations on the subset of HTML to use to make sure all your recipients are able to see your message in its full glory.
01:51 Let’s update our program from before to add some HTML content.
01:57
I’ve created a new copy of our program called html_send.py. A lot of it is similar to before. Let me show you the changes. The constants at the top haven’t changed, so I’ll just scroll past them.
02:10 The first new thing I’ve added is a new value for the plain text body of our message. It’s similar to before, but it also has a URL inside of it. Next is a variable containing the HTML version of our message.
02:23 Not a lot of fancy HTML here, but through the use of a p tag and a link tag, I can make this a little prettier than our plain text. In most clients, the link will even be clickable.
02:34
Most of the with block stays the same. I’m still using the set_content() call, but this time instead of being a hard-coded string, it’s the variable I defined above.
02:45
set_content() specifies the default plain text content. The add_alternative() call is how you add HTML to go along with it. The first argument is the HTML value from above, while the second indicates what the type of the alternative content is.
03:02
This argument is called subtype because it’s specifying the subtype part of a MIME type. I’ll talk more about this in a second. And that’s all it takes to add HTML to your message.
03:14 In the background, I’ll run the server and then call my program. This is the output. At the top, you see the same headers as before, specifying the from, to, and subject fields.
03:27 This part is different though. Our Content-Type has gone from being plain text to multipart/alternative. This is still a MIME type, just a different one from before.
03:37 All MIME types have a primary type and a subtype. The primary type here is multipart, while the subtype is alternative. A second ago, when you were adding HTML as text, you specified HTML as the subtype to go along with the only acceptable primary type in that situation, which was text.
03:57 The Content-Type field also has an argument, the boundary value. The message that follows is split up into parts, hence the multipart thing. The boundary value indicates where one part stops and the next starts.
04:09 The number is randomly generated to greatly reduce the possibility that the mail body has content that would accidentally indicate a boundary. And here is our first boundary, the start of the plain text version.
04:22 Each section gets its own headers. These two are saying that this body is plain text in UTF-8. This is our actual content, similar to the previous lesson.
04:34 And this is the boundary between the plain text and HTML sections. Inside the HTML section, there are more headers.
04:43 Notice the MIME type here is text/html instead of text/plain.
04:47 And finally, our actual HTML content. Well, I guess using the word finally was premature. So finally, finally, a last boundary to indicate that the HTML section is also done.
05:01 In the next lesson, I’ll show you even more features for your email content.
Become a Member to join the conversation.