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')