Dirk
Dirk

Reputation: 3221

Python Google OAuth2 gives "TypeError: a bytes-like object is required, not 'str'"

The code Google provides to send email using OAuth2 is in Python 2, and I am trying to send email using Python 3. The message body is causing an error.

The basic process to send an email is:
Create an f string for the message body. Call create message which executes message = MIMEText(message_text)
This function then calls return {'raw': base64.urlsafe_b64encode(message.as_string())}

... which generates the message TypeError: a bytes-like object is required, not 'str'

Why? How do I get this to not throw this error? .

Here's the code (mostly taken from the Google Gmail example linked above):

def create_message(sender, to, subject, message_text):
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    return {'raw': base64.urlsafe_b64encode(message.as_string())}

def send_reset_email(user):
    token = user.get_reset_token()
    msg = create_message(sender='[email protected]', to=user.email,
             subject = 'Password Reset Request',
    message_text = f'''To reset your password visit the following link:
    {url_for('reset_token', token=token, _external=True)}
    ''')
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('gmail', 'v1', http=http)
    send_message()

And here's the trace:

  File "C:\home\app\routes.py", line 187, in send_reset_email)
  File "C:\home\app\routes.py", line 169, in create_message
     return {'raw': base64.urlsafe_b64encode(message.as_string())}
  File "C:\home\b\base64.py", line 118, in urlsafe_b64encode
     return b64encode(s).translate(_urlsafe_encode_translation)
  File "C:\home\b\base64.py", line 58, in b64encode
    hencoded = binascii.b2a_base64(s, newline=False)

Upvotes: 0

Views: 470

Answers (2)

Tarun Gupta - NOIDA
Tarun Gupta - NOIDA

Reputation: 26

From your code whats i can see is

return {'raw': base64.urlsafe_b64encode(message.as_string())}

which should be changed to

return {'raw': base64.urlsafe_b64encode(message.as_bytes())}

Its good to use google code but sometimes it doesn't work as intended.

While if you are sending email with attachment you need to change the last line to just an extra information that may help you.

return {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()}

Upvotes: 1

Austin Efnor
Austin Efnor

Reputation: 166

Try something like this, I think strings are handled differently. This has some information about potential string issues from Py2 to Py3, similarities might help you resolve some issues: http://python3porting.com/problems.html

message_body = "some message"
# now message_text needs this encoded string
message_text = message_body.encode('utf-8')

Upvotes: 1

Related Questions