Search code examples
pythonasciinon-ascii-charactersmailer

How to fix Python error "" 'ascii' codec can't decode byte 0xc2 in position 364: ordinal not in range(128)"


i have a mailer on using python and while running the mailer program i get the

error "Traceback (most recent call last):
  File "C:\Users\Education\Documents\DDonnelly\Python\Email\2019_CCS_Renewal\main.py", line 11, in <module>
    mailer()
  File "C:\Users\Education\Documents\DDonnelly\Python\Email\2019_CCS_Renewal\ccs_renewal_mailer.py", line 35, in mailer
    plaintext_body = ccs_plaintext_message.replace('{first_name}', first_name)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 364: ordinal not in range(128)"

I have added the comment "# -- coding: utf-8 --" to the top of the file but i still get this code. i even changed the registry default encoding to utf with the below command in the CMD and no luck

"REG ADD HKCU\Console\%SystemRoot^%_system32_cmd.exe /v CodePage /t REG_DWORD /d 65001"

below is a snippet of the code the error was referencing. I would REALLY appreciate any guidance on how to correct this and get this mailer going

CODE SNIPPET

# -*- coding: utf-8 -*-
import win32com.client as win32
from openpyxl import load_workbook
from ccs_renewal_message import ccs_html_message
from ccs_message_plaintext import ccs_plaintext_message


wb = load_workbook('ccs_renewal_list.xlsx')

Gets the specified excel sheet

sheet = wb.get_sheet_by_name('2019 Pending')

def mailer():

    for row in sheet:

        # Stores each individual's information in the variables below
        first_name = row[2].value
        last_name = row[1].value
        full_name = row[2].value + " " + row[1].value
        renewal_date_value = row[4].value
        renewal_date = renewal_date_value.strftime('%m/%d/%Y')
        email = row[3].value
        ncbfaa_id = str(row[0].value)
        # Opens outlook
        outlook = win32.Dispatch('outlook.application')
        # Gets email ready
        mail = outlook.CreateItem(0)

        mail.To = email
        mail.Subject = 'Renewal'

        #Plain Text Message
        plaintext_body = ccs_plaintext_message.replace('{first_name}', first_name)
        mail.Body = plaintext_body.replace('{renewal_date}', renewal_date)

        #HTML Message
        html_body = ccs_html_message.replace('{first_name}', first_name)
        html_body2 = html_body.replace('{id}', ncbfaa_id)
        mail.HTMLBody = html_body2.replace('{renewal_date}', renewal_date)


C:\Users\Education\Documents\DDonnelly\Python\Email\2019_CCS_Renewal>main.py
Eduardo Lozano's certificate has been created
Traceback (most recent call last):
  File "C:\Users\Education\Documents\DDonnelly\Python\Email\2019_CCS_Renewal\main.py", line 11, in <module>
    mailer()
  File "C:\Users\Education\Documents\DDonnelly\Python\Email\2019_CCS_Renewal\ccs_renewal_mailer.py", line 35, in mailer
    plaintext_body = ccs_plaintext_message.replace('{first_name}', first_name)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 364: ordinal not in range(128)

Solution

  • plaintext_body = ccs_plaintext_message.replace('{first_name}', first_name)
    

    in this line you are using str to convert from unicode to encoded text/bytes. you can solve it by either decoding first_name properly and then passing to replace function.

    plaintext_body = ccs_plaintext_message.replace('{first_name}', first_name.encode('utf-8'))
    

    you should also consider changing ccs_plaintext_message type to unicode from str. you can do that by simply adding u in front of str. example

    ccs_plaintext_message = u'some string '