Python how do i send multiple files in the email. I can send 1 file but how to send more than 1
Stefan Bogdanescu
Founder & Senior Architect
Python: How to Send Multiple Files in an Email – A Developer's Guide
Sending emails is a fundamental task in almost every application, and while sending a single text or HTML report is straightforward, handling multiple file attachments requires understanding the underlying structure of email protocols. As developers, we often deal with complex data serialization; the principle remains the same—we need to correctly package our data into a format the recipient system understands.
If you are familiar with using Python's built-in smtplib, you know that sending an email is essentially handing off a message structure over an SMTP server. The challenge when adding files is moving beyond simple text (MIMEText) to constructing a multipart MIME message that correctly encodes the binary file data alongside the textual content.
This guide will walk you through the correct, practical way to attach multiple files to an email in Python, building upon your existing knowledge of sending a single HTML report.
Understanding Email Attachments: The Role of MIME
Email messages are structured using the MIME (Multipurpose Internet Mail Extensions) standard. When you send an email with attachments, you are creating a "multipart" message—a container that holds different parts (the body text, headers, and the files themselves).
When sending files via SMTP, you don't just send plain text; you must encode the file content as binary data and attach it using specific MIME headers. In Python, this is handled by reading the file in binary mode ('rb') and attaching that stream to the message object correctly.
Implementing Multiple File Attachments in Python
To successfully send multiple files, we need to modify our approach from simply creating MIMEText to properly constructing a combined message where each file is treated as a separate attachment part. We will use the email package—specifically classes like MIMEMultipart and MIMEBase—to handle this complexity gracefully.
In the example below, we will read three separate HTML files and attach them to the email.
import smtplib
from email import msg, Message
from email import policy
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
import os
# --- Configuration (Replace with your actual settings) ---
SMTP_SERVER = "smtp.example.com" # e.g., smtp.gmail.com
SMTP_PORT = 587
SENDER = "system@company.com"
RECIPIENT = "4_server_dev@company.com"
# Define the files to send
files_to_send = [
r"G:\test_runners\selenium_regression_test_5_1_1\TestReport\SeleniumTestReport_part1.html",
r"G:\test_runners\selenium_regression_test_5_1_1\TestReport\SeleniumTestReport_part2.html",
r"G:\test_runners\selenium_regression_test_5_1_1\TestReport\SeleniumTestReport_part3.html"
]
def send_multiple_reports():
# 1. Create the main container message
msg = MIMEMultipart()
msg['From'] = SENDER
msg['To'] = RECIPIENT
msg['Subject'] = "Selenium ClearCore_Regression_Test_Report_Results"
# 2. Attach the text body (optional, but good practice)
body = "Please find the attached Selenium test reports for review."
msg.attach(MIMEText(body, "plain"))
# 3. Attach each file individually
for file_path in files_to_send:
try:
# Open the file in binary read mode ('rb')
with open(file_path, "rb") as f:
# Use MIMEBase to create a MIME attachment object
part = MIMEBase('application', 'octet-stream')
part.set_payload(f.read())
# Encode the file content to base64 for safe transmission
with open(file_path, "rb") as f:
encoded_file = f.read()
part.add_header('Content-Disposition', f'attachment; filename="{os.path.basename(file_path)}"')
# Attach the file part to the main message
msg.attach(part)
print(f"Successfully attached: {os.path.basename(file_path)}")
except FileNotFoundError:
print(f"Error: File not found at {file_path}")
except Exception as e:
print(f"An error occurred while processing {file_path}: {e}")
# 4. Send the email via SMTP
try:
print("\nConnecting to server...")
s = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
s.starttls() # Secure the connection
# NOTE: You would typically log in here if authentication is required (s.login(user, password))
s.sendmail(SENDER, RECIPIENT, msg.as_string())
s.quit()
print("\nEmail sent successfully!")
except Exception as e:
print(f"\nFailed to send email. Error: {e}")
if __name__ == "__main__":
send_multiple_reports()
Best Practices for Robust File Sending
When dealing with file attachments, robustness is key. Here are a few best practices derived from experience in building reliable systems:
- Binary Mode is Non-Negotiable: Always open files in binary read mode (
'rb') when reading content intended for MIME attachment. Attempting to read binary data as text will corrupt the file integrity. - Use
MIMEBase: Instead of trying to manually build complex headers, leveraging classes likeMIMEBaseallows Python’semaillibrary to handle the complex Base64 encoding and header formatting automatically. This is crucial for ensuring compliance with email standards. - Error Handling: As demonstrated above, wrap file operations and network communication in comprehensive
try...exceptblocks. If one file fails to attach or the SMTP connection drops, you need to know exactly which step failed so you can debug the issue without losing the entire process. - Consider Alternatives for Large Files: For extremely large files (many megabytes), sending them directly via email attachments is often inefficient and unreliable. A better architectural pattern, especially when building larger enterprise systems that might interact with services like those offered by Laravel Company, is to upload the files to a cloud storage service (like S3) and send the recipient a single email containing links to those files instead of embedding the large payloads directly in the email body.
Conclusion
Sending multiple files in Python requires shifting your focus from simple text formatting to mastering the MIME structure. By utilizing the email package—specifically MIMEMultipart and MIMEBase—you can correctly serialize binary file data into a format that SMTP servers understand, allowing you to attach reports, documents, or any other files reliably. Mastering this is a step toward building robust applications where data transmission is handled with precision and integrity.
Note: Blog content is currently available in English.