Python code to encrypt and email PDF file using PyPDF2
Your code is easy enough to follow.  All of your open() calls are done using with blocks, which is a good habit.

Your variables — such as REP and EmailDict — are unconventionally named.  Use ALL_CAPS for constants, and lower_case for variables.  Ironically, the one variable that should be a constant, path, is defined several times, and not written as a constant.

Speaking of path, you are misusing os.path.join().  The whole point of the function is to ensure that the path delimiter is automatically inserted for you between the components.  So, you should write os.path.join(path, FileDict[ID]) instead.  Also, use raw strings to make your backslashes less cumbersome.



I doubt that there is any value in writing all of those encrypted versions of the files to disk.  You could just create a transient encrypted copy in memory, mail it off, and move on to the next recipient.  To accomplish that, you can write to a StringIO object instead of a file.

The code to encrypt the PDF and compose the mail message feels like it could belong logically together.  I'd define a function for that:

def message_for(unencrypted_pdf_path, rep_id, email, password):
    """
    Creates a MIME message for a rep containing an encrypted version
    of the specified PDF.
    """
    buf = StringIO()
    …
    encrypted_pdf = buf.getvalue()

    text = MIMEText(… % rep_id)

    pdf_attachment = MIMEApplication(encrypted_pdf, _subtype='pdf')
    pdf_attachment.add_header('content-disposition', 'attachment', filename=('MonthlyPaidCommission_%s.pdf' % rep_id))

    msg = MIMEMultipart(_subparts=[text, pdf_attachment])
    msg['SUBJECT'] = 'Commission Report'
    msg['FROM'] = 'me'
    msg['TO'] = rep['EMAIL']
    return msg




Your code would be more expressive if you defined the dictionary entries "all at once" using a dict comprehension.  I would also avoid storing the e-mail and password as a tuple, since it makes you write more cryptic code like EmailDict[ID][1] later.

I think that you would be better off not defining FileDict at all.  Just process each directory entry as you encounter it.  You can even send multiple messages within the same SMTP connection.  Just make sure you keep a log of what was sent, in case something goes wrong.

PATH = r'C:\Apps\CorVu\DATA\Reports\Monthly Commission Reports\Output\pdcom1'

COLS = ['rep_id', 'email', 'password']
with open('commissionrepemaillist.csv', 'r') as infile:
    email_dict = {
        row[0]: dict(zip(COLS, row)) for row in csv.reader(infile)
    }

smtp = smtplib.SMTP('localhost:587')
smtp.starttls()
smtp.login(…)

for filename in os.listdir(PATH):
    rep_id = re.split('[_.]', filename)[1]
    rep = email_dict.get(rep_id)
    if rep is None:
        continue
    msg = message_for(os.path.join(PATH, filename), *rep)
    smtp.sendmail('me', rep['email'], msg.as_string())
    print("Sent %s to %s" % (filename, rep['email']))

smtp.quit()