how to send a email body part through MIMEMultipart

The purpose of a multipart container is to contain other MIME parts. If you only have one part, by definition it's not multipart.

multipart/alternative is useful when you have the same content in different renderings. A common case is to have the message body in both text/plain (no fonts, colors, images, or other "rich" content) and text/html. Typically, the user will have configured their client to prefer one over the other, and so it will then display whatever the user prefers. Somewhat less commonly, the user has a client which can display one type and not the other, so then it's a matter of technical necessity, not user preference, to display the supported version.

multipart/related is useful when you have multiple parts constituting a message. For example, the text/html part in the multipart/alternative might want to pull in images which are supplied as "related" parts. So a common structure in fact is

multipart/alternative
    +---- text/plain
    +---- multipart/related
              +---- text/html
              +---- image/png
              +---- image/png

or even another multipart/related above that if there is an attachment which is independent of the multipart/alternative renderings.

For your concrete example, just declare the body part as text/plain instead:

msg = MIMEText(text)
msg["From"] = emailfrom
msg["To"] = emailto
msg["Subject"] = "hi find the attached file"

For what it's worth, you should normally not need to mess with the MIME preamble, or imagine that a client will display it. (There will only be a preamble when there are multiple parts.)

If you do have an actual attachment you want to include, then this:

msg = MIMEMultipart()
msg["From"] = emailfrom
msg["To"] = emailto
msg["Subject"] = "hi find the attached file"
msg.attach(MIMEText(text))
attachment = MIMEBase('application', 'octet-stream')
attachment.set_payload(data)
msg.attach(attachment)

This works for me:

msg = MIMEMultipart()
msg['From'], msg['To'], msg['Subject'] = ... # specify your sender, receiver, subject attributes
body = 'This is the body of the email.'
body = MIMEText(body) # convert the body to a MIME compatible string
msg.attach(body) # attach it to your main message

You attach the body to the msg, and body in your case should be the MIMEText object.


I would advise to just use some email package that does not "bother" you with knowing anything about types.

Introducing yagmail (I'm the developer).

It will automatically do what you want (attachments, images, html code, fall back and many other features).

pip install yagmail

then

import yagmail
yag = yagmail.SMTP('myemail', 'mypass')
mixed_contents = ['some text', '/path/to/local/img', '/path/to/mp3', 
                  '<h1>a big header text</h1>']
yag.send('[email protected]', 'subject', mixed_contents)

You will end up with some text, some header, inline image and an attached file.

Tags:

Python

Email