Проблема с прикреплением файлов в двоичном файле
Использование Python 3.1.2 У меня возникла проблема с отправкой файлов двоичных вложений (jpeg, pdf и т.д.). Вложения MIMEText работают нормально. Этот код выглядит следующим образом:
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())
Тем не менее, путь вниз в вызывающем стеке (см. трассировку ниже), похоже, что msg.as_string() получил вложение, которое создает полезную нагрузку типа "байты" вместо строки.
Кто-нибудь знает, что может вызвать проблему? Любая помощь будет оценена.
Алан
builtins.TypeError: string payload expected: <class 'bytes'>
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))
Ответы
Ответ 1
Хорошо - после многих разочарований и веб-поиска я обнаружил, что проблема - известная ошибка, которая применяется к Python 3.x, encoders.py, function encode_base64, которая должна читаться следующим образом...
def encode_base64(msg):
"""Encode the message 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'
Ошибка была поднята как проблема № 4768 и была перешла в критический статус
on 2010-05-10. Надеюсь, он будет исправлен в следующей версии (3.1.3?)
С уважением, Алан
Ответ 2
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)
Ответ 3
из этого 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())