Reputation: 31
Want to run Yahoo 2019 Weather API on Raspberry Pi in Python 3.5.3.
Verified Yahoo access codes by successfully running Yahoo sample code for 2.7.10.
All the sample code is from: https://gist.github.com/VerizonMediaOwner/e6be950f74c5a8071329f1d9a50e3158#file-weather_ydn_sample-py
Ran 2to3 conversion and received the following script TypeError indicated:
#Weather API Python sample code**
#Copyright 2019 Oath Inc. Licensed under the terms of the zLib license see
#https://opensource.org/licenses/Zlib for terms.**
#$ python --version**
#Python 2.7.10 - AFTER 2TO 3 CONVERSION**
import time, uuid, urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse
import hmac, hashlib
from base64 import b64encode
#Basic info
url = 'https://weather-ydn-yql.media.yahoo.com/forecastrss'
method = 'GET'
app_id = 'XXX'
consumer_key = 'XXX'
consumer_secret = 'XXX'
concat = '&'
query = {'location': 'sunnyvale,ca', 'format': 'json'}
oauth = {
'oauth_consumer_key': consumer_key,
'oauth_nonce': uuid.uuid4().hex,
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': str(int(time.time())),
'oauth_version': '1.0'
}
#Prepare signature string (merge all params and SORT them)
merged_params = query.copy()
merged_params.update(oauth)
sorted_params = [k + '=' + urllib.parse.quote(merged_params[k], safe='') for k in sorted(merged_params.keys())]
signature_base_str = method + concat + urllib.parse.quote(url, safe='') + concat + urllib.parse.quote(concat.join(sorted_params), safe='')
#Generate signature
composite_key = urllib.parse.quote(consumer_secret, safe='') + concat
oauth_signature = b64encode(hmac.new(composite_key, signature_base_str, hashlib.sha1).digest())
#Prepare Authorization header
oauth['oauth_signature'] = oauth_signature
auth_header = 'OAuth ' + ', '.join(['{}="{}"'.format(k,v) for k,v in oauth.items()])
#Send request
url = url + '?' + urllib.parse.urlencode(query)
request = urllib.request.Request(url)
request.add_header('Authorization', auth_header)
request.add_header('X-Yahoo-App-Id', app_id)
response = urllib.request.urlopen(request).read()
print(response)
ERROR:
pi@raspberrypi:~/Weather $ python3 yahoo2TO3.py
Traceback (most recent call last):
File "yahoo2.py", line 41, in <module>
oauth_signature = b64encode(hmac.new(composite_key, signature_base_str, hashlib.sha1).digest())
File "/usr/lib/python3.5/hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.5/hmac.py", line 42, in __init__
raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'
Tried the 3.7 code sample and received AttributeError:
#Weather API Python sample code
#Copyright 2019 Oath Inc. Licensed under the terms of the zLib license see #https://opensource.org/licenses/Zlib for terms.
#$ python --version
#Python 3.7.x
import time, uuid, urllib, json
import hmac, hashlib
from base64 import b64encode
#Basic info
app_id = 'XXX'
consumer_key = 'XXX'
consumer_secret = 'XXX'
query = {'location': 'macau,mo', 'format': 'json', 'u': 'c'}
url = 'https://weather-ydn-yql.media.yahoo.com/forecastrss'
method = 'GET'
concat = '&'
oauth = {
'oauth_consumer_key': consumer_key,
'oauth_nonce': uuid.uuid4().hex,
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': str(int(time.time())),
'oauth_version': '1.0'
}
#Prepare signature string (merge all params and SORT them)
merged_params = query.copy()
merged_params.update(oauth)
sorted_params = [k + '=' + urllib.parse.quote(merged_params[k], safe='') for k in sorted(merged_params.keys())]
signature_base_str = method + concat + urllib.parse.quote(url, safe='') + concat + urllib.parse.quote(concat.join(sorted_params), safe='')
#Generate signature
composite_key = urllib.parse.quote(consumer_secret, safe='') + concat
oauth_signature = b64encode(hmac.new(composite_key.encode('utf-8'), signature_base_str.encode('utf-8'), hashlib.sha1).digest())
#Prepare Authorization header
oauth['oauth_signature'] = oauth_signature.decode('utf-8')
auth_header = 'OAuth ' + ', '.join(['{}="{}"'.format(k,v) for k,v in oauth.items()])
#Send request
url = url + '?' + urllib.parse.urlencode(query)
request = urllib.request.Request(url)
request.headers['Authorization'] = auth_header
request.headers['X-Yahoo-App-Id']= app_id
response = urllib.request.urlopen(request).read()
print(response)
ERROR:
pi@raspberrypi:~/Weather3 $ python3 yahoo3.py
Traceback (most recent call last):
File "yahoo3.py", line 34, in <module>
sorted_params = [k + '=' + urllib.parse.quote(merged_params[k], safe='') for k in sorted(merged_params.keys())]
File "yahoo3.py", line 34, in <listcomp>
sorted_params = [k + '=' + urllib.parse.quote(merged_params[k], safe='') for k in sorted(merged_params.keys())]
AttributeError: module 'urllib' has no attribute 'parse'
Request assistance to run one or the other in 3.5.
Upvotes: 1
Views: 496
Reputation: 31
RESOLVED:
In the sample code for Python 3.7 change the header import urllib
to import urllib.request
. After this change it works just fine using Raspberry Pi Python 3.5.3.
Upvotes: 2