Sending Emails With CSV Attachment Using Python

2 min read

In this tutorial, we will learn how to send emails with CSV attachments using Python.


I am assuming you already have an SMTP server setup if not you can use the Gmail SMTP or Maligun or anything similar to that.

Sending Emails With CSV Attachment Using Python

from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
import smtplib

def send_mail():
    # Create a multipart message
    msg = MIMEMultipart()
    body_part = MIMEText(MESSAGE_BODY, 'plain')
    msg['Subject'] = EMAIL_SUBJECT
    msg['From'] = EMAIL_FROM
    msg['To'] = EMAIL_TO
    # Add body to email
    # open and read the CSV file in binary
    with open(PATH_TO_CSV_FILE,'rb') as file:
    # Attach the file with filename to the email
        msg.attach(MIMEApplication(, Name=FILE_NAME))

    # Create SMTP object
    smtp_obj = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
    # Login to the server
    smtp_obj.login(SMTP_USERNAME, SMTP_PASSWORD)

    # Convert the message to a string and send it
    smtp_obj.sendmail(msg['From'], msg['To'], msg.as_string())


  • EMAIL_SUBJECT = Subject of the email
  • EMAIL_FROM =Receiver’s email address
  • EMAIL_TO = Senders email address
  • MESSAGE_BODY = Email body
  • PATH_TO_CSV_FILE = Path to the zip file
  • FILE_NAME = Filename for the email attachment
  • SMTP_SERVER = SMTP server
  • SMTP_PORT = SMTP port
  • SMTP_USERNAME = Username for SMTP
  • SMTP_PASSWORD = SMTP password

Since these variables include sensitive data I always recommend feeding them from environment variables however you can also pass them as arguments to the send_mail function.


First, we are importing all the necessary modules for the function then inside the function, we are creating a multipart message using MIMEMultipartobject. Since the multipart object takes arguments in key-value pairs therefore we are providing all the necessary arguments such as message body, sender's address, receiver address in the same manner.

Next, we are opening the CSV file in binary form and attaching the binary stream to the email using MIMEApplication method.

Then we are using Python's built-in SMTP module and creating an SMTP session object by providing the login credentials and finally sending the mail.

Note that in case you want to send multiple CSV files in the same mail you can create a list of files and loop over them and attach it to the email like this.

# create file list
csv_files = ['path_to_csv_1','path_to_csv_2']
# loop over files
for file in csv_files:
    with open(file,'rb') as file:
    # Attach the file with filename to the email
        msg.attach(MIMEApplication(, Name=FILE_NAME))


Latest Articles

Latest from djangocentral

Django 4.1 adds async-compatible interface to QuerySet

The much-awaited pull request for an async-compatible interface to Queryset just got merged into the main branch of Django.Pull Request - The Django core team has been progressively adding async suppor…
Read more →

3 min read

Making Django Admin Jazzy With django-jazzmin

Django admin is undoubtedly one of the most useful apps of Django. Over the years there has been very little change in the admin app as far as the UX is concerned and it's not a bad thing at all. Django admin was designed to provide a simple and minimali…
Read more →

4 min read