This is a note from learning Python’s email
and smtplib
modules.
Most of emails nowadays consists of 3 parts: plain text content, HTML content and attachments. Python’s smtplib
library indeed saved us a lot of work.
1. Create a multipart/alternative email envelope.
from email.mime.multipart import MIMEMultipart alter = MIMEMultipart('alternative') msg = MIMEMultipart()
This will create an envelope that will contain all 3 mentioned parts. In mutt’s view:
1[multipa/alternativ, 7bit, 16K] 2 ├─> [text/plain, base64, utf-8, 0.1K] 3 ├─> [text/html, base64, utf-8, 0.1K] 4 ca.crt [applica/octet-stre, base64, 1.5K]
Some MIME type is truncated, but you get the idea.
2. Unicode
You will have to append the coding part in the source file.
#!/usr/bin/python # -*- coding: utf-8 -*-
The second line must exist.
Then a unicode title and text:
from email.mime.text import MIMEText # msg and alter is derived from the previous example msg['Subject'] = u'中文' text = u'正在用Python写东西' alter.attach(MIMEText(text, 'plain', 'utf-8')) msg.attach(alter)
Appending HTML just change the plain
to html
when you call MIMEText
against HTML content.
3. Add attachments
Mind the relative / absolute path from the location you execute the script. It’s recommend to use absolute path.
from os.path import basename, dirname, realpath # assuming I will attach all the files in the same location as the script itself, also a file from other relative path. cwd = dirname(realpath(__file__)) files = ['myfile.bin', 'herfile.bin', '../other/dir/s.bin'] for f in files: # use absolute path with open(cwd + '/' + f, "rb") as fil: msg.attach(MIMEApplication( fil.read(), Content_Disposition='attachment; filename="%s"' % basename(f), Name=basename(f) ))
4. Message ID.
Some SMTP server supports adding message id to your email on a specific port, e.g. 25. But when you use starttls
to connect the SMTP or use a different port, e.g. 587, Message-Id may not be added automatically. So your email probably won’t be received as it’s required in RFC 2822.
One way to get around that is to generate your own message id. Then you could use starttls()
to send your emails securely.
from email.utils import make_msgid # Inherit the msg from above example. msg['Message-Id'] = make_msgid('example.com') smtp = smtplib.SMTP('smtp.example.com', 587) smtp.starttls() smtp.login('[email protected]', 'emailpassword') smtp.sendmail(sender, to, msg.as_string().encode('utf-8')) smtp.quit()
Note that the message id it generated will use the host name of your current machine if you do not specify.