Archivo binario problema de archivo adjunto de correo electrónico

Uso de Python 3.1.2 Tengo problemas para enviar archivos de datos binarios (jpeg, pdf, etc.): los archivos adjuntos de MIMEText funcionan bien. El código en cuestión es el siguiente …

for file in self.attachments: part = MIMEBase('application', "octet-stream") part.set_payload(open(file,"rb").read()) encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % file) msg.attach(part) # msg is an instance of MIMEMultipart() server = smtplib.SMTP(host, port) server.login(username, password) server.sendmail(from_addr, all_recipients, msg.as_string()) 

Sin embargo, en la parte inferior de la stack de llamadas (ver seguimiento a continuación), parece que msg.as_string () ha recibido un archivo adjunto que crea una carga útil de tipo “bytes” en lugar de cadena.

¿Alguien tiene alguna idea de lo que podría estar causando el problema? Cualquier ayuda sería apreciada.

Alan


 builtins.TypeError: string payload expected:  File "c:\Dev\CommonPY\Scripts\email_send.py", line 147, in send server.sendmail(self.from_addr, all_recipients, msg.as_string()) File "c:\Program Files\Python31\Lib\email\message.py", line 136, in as_string g.flatten(self, unixfrom=unixfrom) File "c:\Program Files\Python31\Lib\email\generator.py", line 76, in flatten self._write(msg) File "c:\Program Files\Python31\Lib\email\generator.py", line 101, in _write self._dispatch(msg) File "c:\Program Files\Python31\Lib\email\generator.py", line 127, in _dispatch meth(msg) File "c:\Program Files\Python31\Lib\email\generator.py", line 181, in _handle_multipart g.flatten(part, unixfrom=False) File "c:\Program Files\Python31\Lib\email\generator.py", line 76, in flatten self._write(msg) File "c:\Program Files\Python31\Lib\email\generator.py", line 101, in _write self._dispatch(msg) File "c:\Program Files\Python31\Lib\email\generator.py", line 127, in _dispatch meth(msg) File "c:\Program Files\Python31\Lib\email\generator.py", line 155, in _handle_text raise TypeError('string payload expected: %s' % type(payload)) 

solución de esta respuesta SO

 from base64 import encodebytes for file in self.attachments: fp = open(file, 'rb') part = MIMEBase('application', "octet-stream") part.set_payload(encodebytes(fp.read()).decode()) fp.close() part.add_header('Content-Transfer-Encoding', 'base64') part.add_header('Content-Disposition', 'attachment; filename="%s"' % file) msg.attach(part) # msg is an instance of MIMEMultipart() server = smtplib.SMTP(host, port) server.login(username, password) server.sendmail(from_addr, all_recipients, msg.as_string()) 

Ok, después de mucha frustración y búsqueda en la web, he encontrado que el problema es un error conocido que se aplica a Python 3.x, encoders.py, función encode_base64, que debería leerse de la siguiente manera …

 def encode_base64(msg): """Encode the message's payload in Base64. Also, add an appropriate Content-Transfer-Encoding header. """ orig = msg.get_payload() encdata = _bencode(orig) # new line inserted to ensure all bytes characters are converted to ASCII encdata = str(encdata, "ASCII") msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'base64' 

El error se ha planteado como problema # 4768 y se pasó a un estado crítico en 2010-05-10. Esperemos que se solucione en la próxima versión (3.1.3?)

Saludos, Alan

 for file in self.attachments: fp = open(file,"rb") part = MIMEApplication( fp.read() ) fp.close() encoders.encode_base64(part) # the miracle part.set_payload( part.get_payload().decode('ASCII') ) part.add_header('Content-Disposition', 'attachment; filename="%s"' % file) msg.attach(part)