Search code examples
pythonemailattachmentmime

MIME Attachments won't send with Subject Line


I'm having trouble with a bit of code sending an email with attachments AND a Subject line.

# Code exerpt from Oli:     http://stackoverflow.com/questions/3362600/how-to-send-email-attachments-with-python
# Emails aren't sending with a subject--need to fix this.
def send_mail(self, send_from, send_to, subject, text, files=None, server="localhost"):
    assert isinstance(send_to, list)

    msg = MIMEMultipart(
        Subject=subject,
        From=send_from,
        To=COMMASPACE.join(send_to),
        Date=formatdate(localtime=True)
    )

    msg.attach(MIMEText(text))

    for f in files or []:
        with open(f, "rb") as fil:
            msg.attach(MIMEApplication(
            fil.read(),
               Content_Disposition='attachment; filename="%s"' % basename(f),
               Name=basename(f)
            ))

    smtp = smtplib.SMTP(server)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()

This code sends an email fine, but it is not deliminating the 'Subject' line and the emails it sends have a subject line of "NO SUBJECT.' Here's what it shows when I print the first part of the MIME msg:

From nobody Thu Oct 29 16:17:38 2015
Content-Type: multipart/mixed; date="Thu, 29 Oct 2015 16:17:38 +0000";
to="me@email.com";
from="someserver@somewhere.com"; subject="TESTING";
boundary="===============0622475305469306134=="
MIME-Version: 1.0

--===============0622475305469306134==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

Here we go, oh! ho! ho!
--===============0622475305469306134==
Content-Type: application/octet-stream; Content-  Disposition="attachment;
filename=\"Log_Mill.py\""; Name="Log_Mill.py"
MIME-Version: 1.0
Content-Transfer-Encoding: base64

I might be able to figure it out if I plug away for hours and hours, but I'm hoping to avoid the extra work for such a trivial fix.

Any help is appreciated!


Solution

  • You are assigning the Subject etc. as attributes of the multipart container, but that's incorrect. The headers you want to specify should be passed to the msg itself as headers instead, like this:

    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = send_from
    msg['To'] = COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    

    The output should look more like

    From nobody Thu Oct 29 16:17:38 2015
    Date: Thu, 29 Oct 2015 16:17:38 +0000
    To: <me@email.com>
    From: <someserver@somewhere.com>
    Subject: TESTING
    Content-Type: multipart/mixed; 
       boundary="===============0622475305469306134=="
    MIME-Version: 1.0
    
    --===============0622475305469306134==
    Content-Type: text/plain; .......