E-Mail

How to send email with BytesIO attachment via SMTP in Python

This example details how to send an email in Python, with an attachment from a io.BytesIO instance instead of reading the attachment from a file on the filesystem:

#!/usr/bin/env python3
__author__ = "Uli Köhler"
__license__ = "CC0 1.0 Universal (public domain)"
__version__ = "1.0"
import smtplib
import mimetypes
from io import BytesIO
from email.message import EmailMessage

# Create message and set text content
msg = EmailMessage()
msg['Subject'] = 'This email contains an attachment'
msg['From'] = '[email protected]'
msg['To'] = '[email protected]'
# Set text content
msg.set_content('Please see attached file')

def attach_bytesio_to_email(email, buf, filename):
    """Attach a file identified by filename, to an email message"""
    # Reset read position & extract data
    buf.seek(0)
    binary_data = buf.read()
    # Guess MIME type or use 'application/octet-stream'
    maintype, _, subtype = (mimetypes.guess_type(filename)[0] or 'application/octet-stream').partition("/")
    # Add as attachment
    email.add_attachment(binary_data, maintype=maintype, subtype=subtype, filename=filename)

# Attach files
buf = BytesIO()
buf.write(b"This is a test text")
attach_bytesio_to_email(msg, buf, "test.txt")

def send_mail_smtp(mail, host, username, password):
    s = smtplib.SMTP(host)
    s.starttls()
    s.login(username, password)
    s.send_message(msg)
    s.quit()

send_mail_smtp(msg, 'smtp.my-domain.com', '[email protected]', 'sae7ooka0S')

The script from above is using the following utility functions:

def attach_bytesio_to_email(email, buf, filename):
    """Attach a file identified by filename, to an email message"""
    # Reset read position & extract data
    buf.seek(0)
    binary_data = buf.read()
    # Guess MIME type or use 'application/octet-stream'
    maintype, _, subtype = (mimetypes.guess_type(filename)[0] or 'application/octet-stream').partition("/")
    # Add as attachment
    email.add_attachment(binary_data, maintype=maintype, subtype=subtype, filename=filename

def send_mail_smtp(mail, host, username, password):
    s = smtplib.SMTP(host)
    s.starttls()
    s.login(username, password)
    s.send_message(msg)
    s.quit()

which you can use in your code directly. The easiest way to initialize the email message is using

# Create message and set text content
msg = EmailMessage()
msg['Subject'] = 'This email contains an attachment'
msg['From'] = '[email protected]'
msg['To'] = '[email protected]'
# Set text content
msg.set_content('Please see attached file')

and then attaching your BytesIO instance (named buf) using

attach_bytesio_to_email(msg, buf, "test.txt")

and once you’re finished with adding attachments, sending the message using

send_mail_smtp(msg, 'smtp.my-domain.com', '[email protected]', 'sae7ooka0S')

 

Posted by Uli Köhler in E-Mail, Python

What does Delivery Status Notification ‘550 5.1.1 User unknown (in reply to RCPT TO command)’ mean?

Problem:

You are trying to send an E-Mail but you receive a Delivery Status notification response like this:

This is the mail system at host techoverflow.net.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

                   The mail system

<[email protected]>: host mail.recpient.com[213.216.0.1] said: 550 5.1.1 User
    unknown (in reply to RCPT TO command)

Solution:

If the response contains a line like this:

<[email protected]>: host mail.recpient.com[213.216.0.1] said: 550 5.1.1 User unknown (in reply to RCPT TO command)

it means that the recipient’s email address (check the start of the line – in this case it’s [email protected]) does not exist. Most likely

  • You used a wrong or mis-spelled email adress (check the address for typos) or
  • the person you sent the mail to doesn’t exist any more at the company you’re trying to send the mail to
  • the domain does not match – e.g. company.com instead of company.net – or copmany.net instead of company.net

Note that if you sent the email to multiple recipients (e.g. using CC), the other recipients will have received the mail if you don’t get a separate status notification or they are listed in that Delivery status notification as well. Note that one Delivery status notification E-Mail might have multiple 550 5.1.1 User unknown lines, so be sure to check the Delivery status notification carefully.

Note that in some cases it will take a couple of minutes until the Delivery status notification arrives in your Inbox, or it might end up in your Spam folder, so be sure to check there as well.

Tip: In case you don’t have another E-Mail address at the company you’re trying to send E-Mails to, try these addresses:

or check the company’s Imprint or Privacy page, which often contains an active E-Mail address.

Posted by Uli Köhler in E-Mail