Kyuubi
Kyuubi

Reputation: 1240

Twitter Search API using urllib2

I am beginner to API calls using python (or even just API calls). I am trying a basic call with the Twitter API.

My Code for generating oauth_signature is as follows :

def getSignature(query):
    key_dict['q'] = urllib.quote(query, '')
    finKey = ""
    for key in sorted(key_dict.keys()):
        finKey += key + "="+key_dict[key]+"&"
    finKey =  finKey[:-1]
    finKey = HTTP_METHOD + "&" + urllib.quote(BASE_URL, '') + "&" + urllib.quote(finKey, '')
    key = urllib.quote(CONSUMER_SECRET_KEY, '')+"&"+urllib.quote(ACCESS_TOKEN_SECRET, '')
    hashed = hmac.new(key, finKey, sha1)
    finKey = binascii.b2a_base64(hashed.digest())
    key_dict['oauth_signature'] = urllib.quote(finKey, '')

where key_dict stores all the keys :

key_dict = dict()
key_dict['oauth_consumer_key'] = urllib.quote(CONSUMER_KEY, '')
key_dict['oauth_nonce'] = urllib.quote("9ab59691142584g739134971f75aa986", '')
key_dict['oauth_signature_method'] = urllib.quote("HMAC-SHA1", '')
key_dict['oauth_timestamp'] = urllib.quote(str(int(time.time())), '')
key_dict['oauth_token'] = urllib.quote(ACCESS_TOKEN, '')
key_dict['oauth_version'] = urllib.quote(OAUTH_VERSION, '')
BASE_URL = "https://api.twitter.com/1.1/search/tweets.json?" + urllib.quote("q=delhi+elections", '')

I generate the Base Header String using the following :

def getHeaderString():
    ret = "OAuth "
    key_list =['oauth_consumer_key', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method', 'oauth_timestamp', 'oauth_token', 'oauth_version']
    for key in key_list:
        ret = ret+key+"=\""+key_dict[key]+"\", "
    ret = ret[:-2]
    return ret

Although when I am making the call, I get :

urllib2.HTTPError: HTTP Error 401: Unauthorized

OR

urllib2.URLError: <urlopen error [Errno 60] Operation timed out>

My final request is made using the following :

getSignature("delhi+elections")
headers = { 'Authorization' : getHeaderString()}
req = urllib2.Request(BASE_URL, headers= headers)
response = urllib2.urlopen(req)

Where am I going wrong ?

Upvotes: 0

Views: 689

Answers (2)

Kyuubi
Kyuubi

Reputation: 1240

Few Points that should have been mentioned somewhere :

  1. The method : binascii.b2a_base64(hashed.digest()) appends a new line feed at the end of the string. This cause the oauth_signature to fail Authenticate.
  2. The delhi+elections is actually supposed to be delhi elections. This mismatch again made the Hash Value match in sha1 to fail.

Removing both of them solved the problem. The final Code :

key_dict = dict()
key_dict['oauth_consumer_key'] = urllib.quote(CONSUMER_KEY, '')
key_dict['oauth_nonce'] = urllib.quote("9aa39691142584s7df134971375aa986", '')
key_dict['oauth_signature_method'] = urllib.quote("HMAC-SHA1", '')
key_dict['oauth_timestamp'] = urllib.quote(str(int(time.time())), '')
key_dict['oauth_token'] = urllib.quote(ACCESS_TOKEN, '')
key_dict['oauth_version'] = urllib.quote(OAUTH_VERSION, '')
BASE_URL = "https://api.twitter.com/1.1/search/tweets.json"
def getSignature(query):
    key_dict['q'] = urllib.quote(query, '')
    finKey = ""
    for key in sorted(key_dict.keys()):
        finKey += key + "="+key_dict[key]+"&"
    finKey =  finKey[:-1]
    finKey = HTTP_METHOD + "&" + urllib.quote(BASE_URL, '') + "&" + urllib.quote(finKey, '')
    key = urllib.quote(CONSUMER_SECRET_KEY, '')+"&"+urllib.quote(ACCESS_TOKEN_SECRET, '')
    hashed = hmac.new(key, finKey, sha1)
    finKey = binascii.b2a_base64(hashed.digest())[:-1]
    key_dict['oauth_signature'] = urllib.quote(finKey, '')

def getHeaderString():
    ret = "OAuth "
    key_list =['oauth_consumer_key', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method', 'oauth_timestamp', 'oauth_token', 'oauth_version']
    for key in key_list:
        ret = ret+key+"=\""+key_dict[key]+"\", "
    ret = ret[:-2]
    return ret

url = BASE_URL
getSignature("delhi elections")
headers = { 'Authorization' : getHeaderString()}
values = {'q':'delhi elections'}
data = urllib.urlencode(values)
req = urllib2.Request(url+"?"+data, headers= headers)
response = urllib2.urlopen(req)
the_page = response.read()
print the_page

Upvotes: 1

jiboutin
jiboutin

Reputation: 66

Instead of coding your own client, have you tried using tweepy? For a reference implementation using this library, you can check twitCheck client.

Upvotes: 0

Related Questions