Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gmail API Error from Code Sample - a bytes-like object is required, not 'str'

Tags:

python

gmail

api

I'm incorporating the Gmail API into a program that I'm making, and I'm getting an error that I haven't been able to resolve/that I haven't been able to find an answer to online. The relevant code is below, as well as the error:

from apiclient import discovery from httplib2 import Http from oauth2client import file, client, tools import base64 from email.mime.audio import MIMEAudio from email.mime.base import MIMEBase from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import mimetypes import os  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_message(service, user_id, message):      message = (service.users().messages().send(userId=user_id, body=message).execute())     print('Message Id: %s' % message['id'])     return message  def send_email(orders):     SCOPES = 'https://mail.google.com/'     store = file.Storage('gmail.json')     creds = store.get()     if not creds or creds.invalid:         flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)         creds = tools.run_flow(flow, store)     service = discovery.build('gmail','v1',http=creds.authorize(Http()))      message_text = orders[0]      created_message = create_message('from','to','subject', message_text)     send_message(service, 'from', created_message) send_email(['TEST'])   Traceback (most recent call last):   File "test_email.py", line 50, in <module>     schoolPing(['TEST'])   File "test_email.py", line 47, in schoolPing     created_message = create_message('from','to','subject', message_text)   File "test_email.py", line 27, in create_message     return {'raw': base64.urlsafe_b64encode(message.as_string())}   File "/Users/Andre/anaconda/lib/python3.5/base64.py", line 119, in urlsafe_b64encode     return b64encode(s).translate(_urlsafe_encode_translation)   File "/Users/Andre/anaconda/lib/python3.5/base64.py", line 59, in b64encode     encoded = binascii.b2a_base64(s)[:-1] TypeError: a bytes-like object is required, not 'str' 
like image 566
A. Monteiro Avatar asked Apr 11 '17 17:04

A. Monteiro


People also ask

How do you fix a bytes-like an object is required not str?

To solve the Python "TypeError: a bytes-like object is required, not 'str'", encode the str to bytes, e.g. my_str. encode('utf-8') . The str. encode method returns an encoded version of the string as a bytes object.

Is a string a bytes-like object?

Byte objects are sequence of Bytes, whereas Strings are sequence of characters. Byte objects are in machine readable form internally, Strings are only in human readable form.

What are bytes-like object?

Bytes-like object in python In Python, a string object is a series of characters that make a string. In the same manner, a byte object is a sequence of bits/bytes that represent data. Strings are human-readable while bytes are computer-readable. Data is converted into byte form before it is stored on a computer.


1 Answers

Found a solution, replace this line:

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

with:

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

Notice added .encode() and .decode() method calls.

First, str object is encoded to bytes object - base64.urlsafe_b64encode requires it in Python 3 (compared to str object in Python 2).

Then, the base64 encoded bytes object must be decoded back to str. This is needed as googleapiclient library will attempt to json serialize it later in code and that is not possible for bytes objects.

like image 83
James Cooper Avatar answered Sep 29 '22 22:09

James Cooper