Sending Emails with Attachments and Inline Images in Python
Sending emails often involves more than plain text.
You might need to:
-
Attach files (documents, PDFs, images)
-
Include images inline within an HTML message
Emails use the Multipurpose Internet Mail Extensions (MIME) standard to encode different content types (text, HTML, images, etc.) in a single message.
Python’s email package supports building these MIME-multipart emails.
Attachments
To attach a file:
-
Read it in binary mode
-
Add it to the email message with the correct MIME type
-
Using the high-level
EmailMessageclass, you can call.add_attachment()-
Automatically handles encoding
-
Sets headers like
Content-TypeandContent-Disposition(marks it as an attachment)
-
Example – Attaching a PDF file
from email.message import EmailMessage
msg = EmailMessage()
msg['Subject'] = "Monthly Report"
msg['From'] = sender_email
msg['To'] = receiver_email
msg.set_content("Please find the monthly report attached.")
# Read file in binary mode and attach
with open("Report.pdf", "rb") as f:
file_data = f.read()
file_name = "Report.pdf"
msg.add_attachment(file_data, maintype="application", subtype="pdf", filename=file_name)
-
maintype="application"andsubtype="pdf"tell the email client it’s a PDF. -
filenamesets the suggested name in the email. -
Python will Base64-encode as needed and add the correct headers.
Example – Attaching an Image
with open("chart.png", "rb") as img:
img_data = img.read()
msg.add_attachment(img_data, maintype="image", subtype="png", filename="chart.png")
Inline Images in HTML Emails
Inline images:
-
Appear embedded in the email body
-
Require:
-
Attaching the image
-
Adding a Content-ID header to the image MIME part
-
Referencing it in HTML using
<img src="cid:...">
-
-
Email must be
multipart/related(HTML and images are related content)
Example – HTML Email with Inline Image
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart('related')
msg['Subject'] = "Product Catalog"
msg['From'] = sender_email
msg['To'] = receiver_email
# HTML content with an image reference
html_content = """
<html>
<body>
<h1>New Product Launch</h1>
<p>Check out our latest product:</p>
<img src="cid:prod_image">
</body>
</html>"""
html_part = MIMEText(html_content, 'html')
msg.attach(html_part)
# Attach the image
with open("product.jpg", "rb") as img:
img_data = img.read()
image_part = MIMEImage(img_data, _subtype="jpg")
image_part.add_header('Content-ID', '<prod_image>')
msg.attach(image_part)
-
Content-ID:
<prod_image> -
HTML references it as:
cid:prod_image -
Email clients load the image inline
Sending
After constructing the email (with attachments or inline images), send it the same way as before:
smtp.send_message(msg)
Exercise
-
Send yourself an email with:
-
A text file
-
A picture as attachments
-
-
Verify that both arrive intact
-
Modify the script to:
-
Send an HTML email
-
Include an inline image
-
-
Check your email client to ensure the inline image is displayed.
