Python smtplib send_message() failing, returning AttributeError: 'str' object has no attribute 'get_all'

RPiAwesomeness picture RPiAwesomeness · Apr 27, 2015 · Viewed 8k times · Source

I'm working on an project where I have to use the smtplib and email modules in Python 3.4 to send an email.

I'm able to create the email itself and I'm able to connect to the server, but then it returns this Exception:

reply: b'235 2.7.0 Accepted\r\n'
reply: retcode (235); Msg: b'2.7.0 Accepted'
send: 'QUIT\r\n'
reply: b'221 2.0.0 closing connection s66sm8304113yhp.2 - gsmtp\r\n'
reply: retcode (221); Msg: b'2.0.0 closing connection s66sm8304113yhp.2 - gsmtp'
Traceback (most recent call last):
  File "base.py", line 108, in <module>
    send(fromaddr, toaddrs, msg)
  File "base.py", line 61, in send
    server.send_message(fromaddr, toaddrs, msg)
  File "/usr/lib/python3.4/smtplib.py", line 829, in send_message
    resent = msg.get_all('Resent-Date')
AttributeError: 'str' object has no attribute 'get_all'

The code (troublesome line linked directly to) is available here. Strangely enough, the code actually sends QUIT prior to actually sending any of the email body - not sure if that's something that would affect this.

Does anyone know what is causing this error?

EDIT Turns out that part of my issue was that I was using the incorrect format. send_message() requires the variables in the order of Message, From, To, while my code was sending it in the order of From, To, Message.

However, I'm now getting this error:

reply: b'235 2.7.0 Accepted\r\n'
reply: retcode (235); Msg: b'2.7.0 Accepted'
send: 'QUIT\r\n'
reply: b'221 2.0.0 closing connection s66sm8443316yhp.2 - gsmtp\r\n'
reply: retcode (221); Msg: b'2.0.0 closing connection s66sm8443316yhp.2 - gsmtp'
Traceback (most recent call last):
  File "MIME-base.py", line 108, in <module>
    send(fromaddr, toaddrs, msg)
  File "MIME-base.py", line 61, in send
    server.send_message(msg, fromaddr, toaddrs)
  File "/usr/lib/python3.4/smtplib.py", line 839, in send_message
    g.flatten(msg_copy, linesep='\r\n')
  File "/usr/lib/python3.4/email/generator.py", line 109, in flatten
    self._write(msg)
  File "/usr/lib/python3.4/email/generator.py", line 189, in _write
    self._write_headers(msg)
  File "/usr/lib/python3.4/email/generator.py", line 416, in _write_headers
    self._fp.write(self.policy.fold_binary(h, v))
  File "/usr/lib/python3.4/email/_policybase.py", line 325, in fold_binary
    folded = self._fold(name, value, sanitize=self.cte_type=='7bit')
  File "/usr/lib/python3.4/email/_policybase.py", line 352, in _fold
    parts.append(h.encode(linesep=self.linesep,
AttributeError: 'list' object has no attribute 'encode'

Answer

ekhumoro picture ekhumoro · Apr 27, 2015

The signature for SMTP.send_message is not the same as SMTP.sendmail. So try:

    server.send_message(msg, fromaddr, toaddrs)

EDIT:

You also need to add the To: headers separately, rather than as a list:

    for item in input("To: ").split():
        msg['To'] = item