I am trying to send a binary attachment using the python 3.5.2 smtplib over TLS. My platform is OSX and I am using python installed from homebrew.
When I receive the attachment, the encoding appears to be munged. Instead of the original file that starts with this hex:
ffd8 ffe0 0010 4a46 4946 0001 0100 0001
the starting hex of my attachment as received has some weird base64 leftovers:
5c75 6463 6666 5c75 6463 6438 5c75 6463 6666 5c75 6463 6530 0010 4a46 4946 0001
This is a minimal case that fails, which is pretty much exactly what is in the official documentation with the exception of the addition of the TLS logic and gnupg
gpg = gnupg.GPG('/path/to/gpg')
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
msg = MIMEMultipart()
msg['Subject'] = 'subject'
msg['From'] = 'XXXX@gmail.com'
msg['To'] = 'YYYY@gmail.com'
with open('/tmp/image.jpg', mode='rb') as image_file:
image = MIMEImage(image_file.read())
s = smtplib.SMTP('smtp.gmail.com', 587)
Based on another question on here, I tried this instead of
and it also failed:
s.sendmail('XXXX@gmail.com', ['YYYY@gmail.com'], msg.as_string())
I have also tried explicitly adding
when I init
, adding a
header, and adding a
header and none of those seemed to make a difference.
I have verified that I do not have a problem with my email client when it receives base64 encoded attachments from other clients.
I looked at the smtplib source and noticed that the way smtplib handles line separators looks a little odd and wonder if this is possibly related. (also see ref: https://bugs.python.org/issue14645
Do I need to encode something differently, set something special for my platform, or is this a glitch? Thanks!
Update: This problem only exists when I am running Flask and does not occur outside of Flask. I am in the process of attempting to isolate the problem inside my Flask environment. I thought it might be flask_mail but removing that did not solve the issue. The below code fails when run from Flask on my system, but not if I run it from a shell script from within the same virtual environment and same python binary. I don't expect any answers at this point due to complexity but will leave this open for posterity.
Update 2: I have narrowed this problem down to an interaction with the gnupg library from https://github.com/isislovecruft/python-gnupg/. I have updated my minimal example to reflect this. This monkey-patch of python codecs in python-gnupug is responsible for the problem: