Search code examples
pythonpython-2.7gmailsendmail

Unable to send mail using python with multiple attachment and multiple recipients [to,cc,bcc]


Below is my code. It is unable to send mail somewhere at parsing level. Not able to understand the actual issue. OS is Ubuntu 14.04 Server provided by AWS. It has to send email with two attachments.

import smtplib
import sys
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders

fromaddr = "[email protected]"
toaddr = str(sys.argv[1]).split(",")
ccaddr = str(sys.argv[2]).split(",")
bccaddr = str(sys.argv[3]).split(",")

subject = None
body = None

print sys.argv

with open("subject.txt") as f1:
    subject = f1.read()

with open("body.txt") as f2:
    body = f2.read()

msg = MIMEMultipart()

msg['From'] = fromaddr
msg['To'] = toaddr
msg['Cc'] = ccaddr
msg['Bcc'] = bccaddr
msg['Subject'] = subject.replace("DD",str(sys.argv[4])[6:2]).replace("MM",str(sys.argv[4])[4:2]).replace("YYYY",str(sys.argv[4])[0:4])

body = body.replace("DD",str(sys.argv[4])[6:2]).replace("MM",str(sys.argv[4])[4:2]).replace("YYYY",str(sys.argv[4])[0:4])

msg.attach(MIMEText(body, 'plain'))

for filename in str(sys.argv[5]).split(";"):
    attachment = open(filename, "rb")
    part = MIMEBase('application', 'octet-stream')
    part.set_payload((attachment).read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
    msg.attach(part)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.ehlo()
server.login(fromaddr, "password")
server.sendmail(fromaddr, toaddr, msg.as_string())
server.quit()

Here is the error:

  File "send_mail.py", line 49, in <module>
    server.sendmail(fromaddr, toaddr, msg.as_string())
  File "/usr/lib/python2.7/email/message.py", line 137, in as_string
    g.flatten(self, unixfrom=unixfrom)
  File "/usr/lib/python2.7/email/generator.py", line 83, in flatten
    self._write(msg)
  File "/usr/lib/python2.7/email/generator.py", line 115, in _write
    self._write_headers(msg)
  File "/usr/lib/python2.7/email/generator.py", line 164, in _write_headers
    v, maxlinelen=self._maxheaderlen, header_name=h).encode()
  File "/usr/lib/python2.7/email/header.py", line 410, in encode
    value = self._encode_chunks(newchunks, maxlinelen)
  File "/usr/lib/python2.7/email/header.py", line 370, in _encode_chunks
    _max_append(chunks, s, maxlinelen, extra)
  File "/usr/lib/python2.7/email/quoprimime.py", line 97, in _max_append
    L.append(s.lstrip())
AttributeError: 'list' object has no attribute 'lstrip'

Solution

  • Try it with yagmail. Disclaimer: I'm the developer of yagmail.

    import yagmail
    yag = yagmail.SMTP("[email protected]", "password")
    yag.send(toaddrs, subject, body, str(sys.argv[5]).split(";"), ccaddrs, bccaddrs)
    #        ^ to     ^subject  ^ body      ^  attachments         ^ cc     ^ bcc
    

    It's pretty much "Do What I Want", you can provide lists of strings or a single string, even omit any arguments, and it will be sensible. Another cool thing is that the attachments here is a list of strings; where each will be tried to be loaded as file (with correct mimetype).

    Use pip install yagmail to install