9

I am trying to write a python script to send an email that uses html formatting and involves a lot of non-breaking spaces. However, when I run it, some of the &nbsp strings are interrupted by spaces that occur every 171 characters, as can be seen by this example:

#!/usr/bin/env python
import smtplib
import socket
from email.mime.text import MIMEText

emails = ["my@email.com"]
sender = "test@{0}".format(socket.gethostname())

message = "<html><head></head><body>"
for i in range(20):
        message += "&nbsp;" * 50
        message += "<br/>"
message += "</body>"
message = MIMEText(message, "html")
message["Subject"] = "Test"
message["From"] = sender
message["To"] = ", ".join(emails)
mailer = smtplib.SMTP("localhost")
mailer.sendmail(sender, emails, message.as_string())
mailer.quit()

The example should produce a blank email that consists of only spaces, but it ends up looking something like this:

         &nbsp ;                                    


                       &nb sp;                      


                                     & nbsp;        






             &nbs p;                                


                           &n bsp;          

Edit: In case it is important, I am running Ubuntu 15.04 with Postfix for the smtp client, and using python2.6.

Program man
  • 393
  • 3
  • 13

2 Answers2

7

I can replicate this in a way but my line breaks come every 999 characters. RFC 821 says maximum length of a line is 1000 characters including the line break so that's probably why.

This post gives a different way to send a html email in python, and i believe the mime type "multipart/alternative" is the correct way. Sending HTML email using Python

Community
  • 1
  • 1
timoh
  • 176
  • 1
  • 6
  • 4
    That was the problem, so it's trivial to just add a \n after every
    to cause this issue to disappear.
    – Program man Jun 24 '15 at 16:18
  • But the \n shows up in the email (at least as rendered in Outlook). How can you insert the line break without it being seen by the recipient as a \n? – user3450049 Dec 10 '16 at 01:00
2

I'm the developer of yagmail, a package that tries to make it easy to send emails.

You can use the following code:

import yagmail
yag = yagmail.SMTP('me@gmail.com', 'mypassword')

for i in range(20):
    message += "&nbsp;" * 50
    message += "<br/>"

yag.send(contents = message)

Note that by default it will send a HTML message, and that it also adds automatically the alternative part for non HTML browsers.

Also, note that omitting the subject will leave an empty subject, and without a to argument it will send it to self.

Furthermore, note that if you set yagmail up correctly, you can just login using yag.SMTP(), without having to have username & password in the script (while still being secure). Omitting the password will prompt a getpass.

Adding an attachment is as simple as pointing to a local file, e.g.:

yag.send(contents = [message, 'previously a lot of whitespace', '/local/path/file.zip']

Awesome isn't it? Thanks for the allowing me to show a nice use case for yagmail :)

If you have any feature requests, issues or ideas please let me know at github.

PascalVKooten
  • 20,643
  • 17
  • 103
  • 160