Welcome, guest | Sign In | My Account | Store | Cart

This code constructs a multipart MIME email message and sends it using smtplib.

Python, 25 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sys, smtplib, MimeWriter, base64, StringIO

message = StringIO.StringIO()
writer = MimeWriter.MimeWriter(message)
writer.addheader('Subject', 'The kitten picture')
writer.startmultipartbody('mixed')

# start off with a text/plain part
part = writer.nextpart()
body = part.startbody('text/plain')
body.write('This is a picture of a kitten, enjoy :)')

# now add an image part
part = writer.nextpart()
part.addheader('Content-Transfer-Encoding', 'base64')
body = part.startbody('image/jpeg')
base64.encode(open('kitten.jpg', 'rb'), body)

# finish off
writer.lastpart()

# send the mail
smtp = smtplib.SMTP('smtp.server.address')
smtp.sendmail('from@from.address', 'to@to.address', message.getvalue())
smtp.quit()

The order of the calls to the writer are important. Note that headers are always added before body contents are added.

The top-level body is added with a sub-type of 'mixed', which is appropriate for mixed content like this example. Other sub-types may be found by reading RFCs 1521 ('mixed', 'alternative', 'digest', 'parallel'), 1847 ('signed', 'encrypted') and 2387 ('related'). RFCs are available at http://www.ietf.org/rfc/rfcNNNN.txt.

3 comments

Michael Strasser 20 years, 9 months ago  # | flag

MimeWriter.py is not writing a required header. RFC 2045 states that the header:

MIME-Version: 1.0

is required for MIME Internet message bodies. Some mail programs don't care (e.g. Outlook) but others do (like PMMail).

MimeWriter.py should put that in by itself. You can either edit MimeWriter.py by changing the MimeWriter class's __init__ method to have:

self._headers = ["MIME-Version: 1.0\n"]

instead of

self._headers = []

Or you can use MimeWriter.py as shipped and work around it by putting:

writer.addheader('MIME-Version', '1.0')

before starting the multipart body in this cookbook example.

Now, how do I submit a bugfix request to Python... Michael Strasser

Michael Strasser 20 years, 9 months ago  # | flag

You can include the filename of an attachment. You can include the filename of an attachment, like so:

body = part.startbody('image/jpeg; name=kitten.jpg')

MimeWriter will generate this header:

Content-Type: image/jpeg; name=kitten.jpg

and the mail reader will read that name.

If the name contains spaces, surround it with double quotes. Michael Strasser

Dirk Holtwick 20 years, 8 months ago  # | flag

Wrap the whole stuff into a class. Some time ago I tried to solve the same problem and wrote a class doing that job. See http://sourceforge.net/snippet/detail.php?type=snippet&id=100444 for details. Would be nice to have a class like this in the Python distribiution but a request for that was not successful.