Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.4 error "Unicode-objects must be encoded before hashing"

Tags:

python-3.x

Using oauth2 to get data from Twitter, but getting the error as :

Unicode-objects must be encoded before hashing

Using the code below,

def oauth_req(url, key, secret, http_method="GET", post_body="",http_headers=None):
    consumer = oauth2.Consumer(key=API_KEY, secret=API_SECRET)
    token = oauth2.Token(key=key, secret=secret)
    client = oauth2.Client(consumer, token)
    resp, content = client.request(url, method=http_method, body=post_body, headers=http_headers)
    return content
data = oauth_req(url, TOKEN_KEY, TOKEN_SECRET)

Also tried utf8 encoded values for the variables that I am passing into def.

File "<pyshell#11>", line 1, in <module> 
    data = oauth_req(url, TOKEN_KEY, TOKEN_SECRET) 
File "<pyshell#8>", line 6, in oauth_req
    body=post_body, headers=http_headers) 
File "C:\Python35-32\lib\site-packages\oauth2_init_.py", line 673, in request 
    req.sign_request(self.method, self.consumer, self.token) 
File "C:\Python35-32\lib\site-packages\oauth2_init_.py", line 493, in sign_request 
    self['oauth_body_hash'] = base64.b64encode(sha1(self.body).digest()) 
TypeError: Unicode-objects must be encoded before hashing 
like image 420
Sarang Manjrekar Avatar asked Jun 05 '16 10:06

Sarang Manjrekar


2 Answers

The body argument of client.request should be a bytestring. So first fix the default value

def oauth_req(url, key, secret, http_method="GET", post_body=b"", http_headers=None):

(That should fix the error in the example code)

And then ensure that the data that you pass into this function for the post-body is a bytestring, as its sha hash will be computed. To convert a string to bytes use mybytestring = bytes(mystring, "utf-8") or whatever encoding is correct to use.

Here is the relevant line from the source:

like image 82
James K Avatar answered Oct 28 '22 06:10

James K


@JamesK's answer is right. Full code is here

def oauth_req(url, token, secret, http_method="GET", post_body="", http_headers=None):
    consumer = oauth2.Consumer(key=CONSUMER_KEY, secret=CONSUMER_SECRET)
    token = oauth2.Token(key=token, secret=secret)
    client = oauth2.Client(consumer, token)
    resp, content = client.request( url, method=http_method, body=bytes(post_body, "utf-8"), headers=http_headers )
    return content
like image 20
dohvis Avatar answered Oct 28 '22 05:10

dohvis