Search code examples
pythonpandasemailmultipartsmtplib

Python: send multipart message with multiple recievers


I already referred these posts - here, here. Please don't mark it as duplicate

I am trying to send an email using python smtplib

rec_list.append(temp_email_df.iloc[0,4:].to_string(header=False, index=False))
print(rec_list) # this list contains one email id
print(type(rec_list))
message = MIMEMultipart()
message['Subject'] = 'For your review'
message['From'] = 'user1@org.com'
message['To'] = ", ".join(rec_list)

My receiver email address comes from pandas dataframe as shown above.

Later, based on the suggestions from stack overflow, I already use join operator and put them in the list.

My send_message code looks like below

msg_body = message.as_string()
server = SMTP('test.com', 25)
#server.send_message(msg_body,message['From'],message['To']) # doesn't work
server.send_message(message['From'],rec_list,msg_body) # doesn;t work
server.quit() 
rec_list.clear()

I get error message as shown below

---> 71 server.send_message(message['From'],rec_list,msg_body) 72 server.quit() 73 rec_list.clear()

~\Anaconda3\lib\smtplib.py in send_message(self, msg, from_addr, to_addrs, mail_options, rcpt_options) 942 943 self.ehlo_or_helo_if_needed() --> 944 resent = msg.get_all('Resent-Date') 945 if resent is None: 946 header_prefix = ''

AttributeError: 'str' object has no attribute 'get_all'


Solution

  • The problem is that you are using send_message(), when you should be using sendmail(). The send_message method is designed to work with EmailMessage objects, whereas you are using a MIMEMultipart object.

    Here is how to send an email with an attachment:

    First, start a local debug server (just for testing):

    $ python -m smtpd -n -c DebuggingServer localhost:1025
    

    Now send the actual email:

    import smtplib
    from email.mime.application import MIMEApplication
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    
    message = MIMEMultipart()
    message.attach(MIMEText('Test'))
    part = MIMEApplication('Attachment', Name='file.txt')
    part['Content-Disposition'] = 'attachment; filename="file.txt"'
    message.attach(part)
    
    sender = 'myaddress@123.com'
    receivers = ['someone@abc.com', 'someone@xyz.com']
    
    message['Subject'] = 'Test Email'
    message['From'] = sender
    message['To'] = ', '.join(receivers)
    
    with smtplib.SMTP('localhost', 1025) as smtp:
        smtp.sendmail(sender, receivers, message.as_string())
    

    This produces the following output on the debug server:

    ---------- MESSAGE FOLLOWS ----------
    b'Content-Type: multipart/mixed; boundary="===============8897222788102853002=="'
    b'MIME-Version: 1.0'
    b'Subject: Test Email'
    b'From: myaddress@123.com'
    b'To: someone@abc.com, someone@xyz.com'
    b'X-Peer: ::1'
    b''
    b'--===============8897222788102853002=='
    b'Content-Type: text/plain; charset="us-ascii"'
    b'MIME-Version: 1.0'
    b'Content-Transfer-Encoding: 7bit'
    b''
    b'Test'
    b'--===============8897222788102853002=='
    b'Content-Type: application/octet-stream; Name="file.txt"'
    b'MIME-Version: 1.0'
    b'Content-Transfer-Encoding: base64'
    b'Content-Disposition: attachment; filename="file.txt"'
    b''
    b'QXR0YWNobWVudA=='
    b''
    b'--===============8897222788102853002==--'
    ------------ END MESSAGE ------------