Python script for sending out bulk password e-mails

I needed it today and did not find anything like this. The following script combines a template file and a CSV file (see below) and sends the output to an e-mail address specified in the CSV file. I used it to send temporary passwords to ~100 students.
Hope this example helps somebody.


import smtplib
import csv

CSVFILE = "accounts.csv"
TEMPLATE = "mail_template.txt"

SENDER = '"Sender Name" <>'

USE_TLS = 0 # for encrypted connection to SMTP server set to 1
AUTH_REQUIRED = 0 # if you need to use SMTP AUTH set to 1
SMTP_USER = 'sender'  # for SMTP AUTH, set SMTP username here
SMTP_PASS = 'pass'  # for SMTP AUTH, set SMTP password here

# You have to set the following two variables to 0 
# in order to actually send the e-mails to the recipients!
DRY_RUN = 1 # do not actually send e-mails but print what would have happened
SAFE_MODE = 1 # if set, all mails wil be sent to RECIPIENTS instead of the address specified in the csv file.

template = open(TEMPLATE, "r")
csvfile  = open(CSVFILE, "r")

mail_template =
csv_reader = csv.reader(csvfile)

######## Open SMTP session ########
smtpresult = 0  # define it so we do not get an error during DRY_RUN
if not DRY_RUN:
    print "Opening SMTP session"
    session = smtplib.SMTP(SMTP_SERVER)
    if USE_TLS and session.has_extn("STARTTLS"): # not tested!
        session.login(SMTP_USER, SMTP_PASS)

######## Send Mails ########
for row in csv_reader:
    # adapt these fields to your needs
    surname = row[0]
    givenname = row [1]
    email = row[2]
    login = row[6]
    passwd = row[7] 
    # you might want to remove this part:
    if passwd == "":
        print "Skipping " + login + " - account already existed"
        print "Sending mail to " + email
        mssg = mail_template.replace("$NAME$", givenname + " " + surname)
        mssg = mssg.replace("$USERNAME$",login)
        mssg = mssg.replace("$PASSWORD$",passwd)
        if SAFE_MODE:
            recipients = RECIPIENTS
            mssg = mssg + "rnThis message would have been sent to " + email
            recipients = [email]
        if DRY_RUN:
            print "[DRY RUN] Sending mail to " + recipients[0]
            print mssg
            smtpresult = session.sendmail(SENDER, recipients, mssg)

        if smtpresult:
            errstr = ""
            for recip in smtpresult.keys():
                errstr = """Could not deliver mail to: %s

        Server said: %s

        %s""" % (recip, smtpresult[recip][0], smtpresult[recip][1], errstr)
            raise smtplib.SMTPException, errstr

The template file looks like this (in German):

From: "Raphael" <>
Subject: [MT] Accounts

Hallo $NAME$,
Du erhältst mit dieser E-Mail deine Account-Daten für die Windows-Arbeitsplätze.
Beim ersten Login wirst Du aufgefordert, das Passwort zu ändern. 

Benutzername: $USERNAME$
Passwort: $PASSWORD$


The CSV file looked like this:

Next Post
Leave a comment


  1. anonymous

     /  July 16, 2008

    Vasu writes:Excellent. Very helpful script. I was looking for one today and found your site. Thanks for posting it!!

  2. raphman

     /  October 31, 2008

    Hi Enrique,put the following lines in the template (just after the Subject: line):MIME-Version: 1.0Content-Type: text/plain; charset=utf-8Content-Transfer-Encoding: 8bit

  3. anonymous

     /  October 31, 2008

    Enrique writes:Very good! – I have to notify 650 users about their new email passwords, your script is exactly what I was looking for. Just one cuestion: Where can I set encoding for the outgoing mails: I need to use "tildes" ñ, á, ü etc…

  4. anonymous

     /  November 24, 2009

    Nicolas writes:Very usefull for me the comment about how to send ñ, "tildes" and others. thanks raphman

  5. anonymous

     /  February 8, 2011

    vangel writes:hi RaphaelThanks for sharing this script. I want to use this to send HTML email. So if I set the mime type and let the template be there it will work? or what do you recommend. Its plain HTML with nice fonts and colors. no image etc but clickable links.thanks again. appreciate your reply.

  6. raphman

     /  February 8, 2011

    Hi vangel,you should use a multipart mime message that also contains a plaintext version of your text for people who prefer this.The easiest way to do this is to send an HTML e-mail with the content to your own e-mail address and look at its headers + source. This should give you the correctly formatted content for your template.

  7. anonymous

     /  February 9, 2011

    vangel writes:Hi Raphael,Good idea on that. Thank you very muchVangel

  8. anonymous

     /  February 9, 2011

    vangel writes:hey Raphael,your idea worked :Dits great it all works fine and am able to send emails. Except one unique case where sometimes the script hangs when sending email to specific domains like yahoo. I think there is SMTP error or other problem. I am searching docs to see if I can put in a timeout of some sort somewhere.Thank you so much again Python rules. m/


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: