title: Unable to get OAuth "Request Token" while working with the Tumblr API using Python
body: <p>I've been using libraries to handle OAuth so far, but lately I've been digging deeper trying to understand the underlying OAuth process. Currently, I'm trying to connect to <a href="http://www.tumblr.com/docs/en/api/v2" rel="nofollow noreferrer">Tumblr API v2</a> using OAuth 1.0a with this simple code:</p>
  
  <pre><code>import urllib, urllib2, time, random, hmac, base64, hashlib
  
  def makenonce():
      random_number = ''.join( str( random.randint( 0, 9 ) ) for _ in range( 40 ) )
      m = hashlib.md5( str( time.time() ) + str( random_number ) )
      return m.hexdigest()
  
  def encodeparams(s):
      return urllib.quote( str( s ), safe='~' )
  
  # Actual key and secret from a test app created using a dummy Tumblr account
  consumer_key = '97oAujQhSaQNv4XDXzCjdZlOxwNyhobmDwmueJBCHWsFFsW7Ly'
  consumer_secret = '5q1dpF659SOgSUb0Eo52aAyoud8N8QOuJu6enCG92aDR6WoMlf'
  
  #oauth URLs
  request_tokenURL = 'http://www.tumblr.com/oauth/request_token'
  
  #oauth params
  oauth_parameters = {
              'oauth_consumer_key'     : consumer_key,
              'oauth_nonce'            : makenonce(),
              'oauth_timestamp'        : str(int(time.time())),
              'oauth_signature_method' : "HMAC-SHA1",
              'oauth_version'          : "1.0"
              }
  
  normalized_parameters = encodeparams( '&amp;'.join( ['%s=%s' % ( encodeparams( str( k ) ), encodeparams( str( oauth_parameters[k] ) ) ) for k in sorted( oauth_parameters )] ) )
  # Since I'm focusing only on getting the request token for now, I set this to POST.
  normalized_http_method = 'POST'
  normalized_http_url = encodeparams( request_tokenURL )
  signature_base_string = '&amp;'.join( [normalized_http_method, normalized_http_url, normalized_parameters] )
  oauth_key = consumer_secret + '&amp;'
  hashed = hmac.new( oauth_key, signature_base_string, hashlib.sha1 )
  oauth_parameters['oauth_signature'] = base64.b64encode( hashed.digest() )
  oauth_header = 'Authorization: OAuth realm="http://www.tumblr.com",' + 'oauth_nonce="' + oauth_parameters['oauth_nonce'] + '",' + 'oauth_timestamp="' + oauth_parameters['oauth_timestamp'] + '",' + 'oauth_consumer_key="' + oauth_parameters['oauth_consumer_key'] + '",' + 'oauth_signature_method="HMAC-SHA1",oauth_version="1.0",oauth_signature="' + oauth_parameters['oauth_signature'] +'"'
  
  # sample oauth_header generated by the code above:
  # Authorization: OAuth realm="http://www.tumblr.com",oauth_nonce="c200a0e06f30b84b851ac3e99a71054b",oauth_timestamp="1315231855",oauth_consumer_key="97oAujQhSaQNv4XDXzCjdZlOxwNyhobmDwmueJBCHWsFFsW7Ly",oauth_signature_method="HMAC-SHA1",oauth_version="1.0",oauth_signature="kVAlmwolCX0WJIvTF9MB2UV5rnU="
  
  
  req = urllib2.Request( request_tokenURL )
  req.add_header( 'Authorization', oauth_header )
  # If all goes well, Tumblr should send me the oauth request token.
  print urllib2.urlopen( req ).read()
  </code></pre>
  
  <p>Instead of the OAuth Request token, Tumblr returns <strong>HTTP Error 401: Unauthorized</strong>. </p>
  
  <p>Things I've tried without any success:</p>
  
  <ol>
  <li>Changed <code>oauth_version</code> from "1.0" to "1.0a", and changed it back again.</li>
  <li>A guide on OAuth mandated adding the '&amp;' at the end of <code>consumer_secret</code> to get the <code>oauth_key</code>. I tried removing the '&amp;' later to see if that made any difference.</li>
  <li>Checked if the OAuth parameters were sorted, and they were.</li>
  <li>Did not add the string "Authorization: " to <code>oauth_header</code>, then added it back later. Neither made any difference.</li>
  </ol>
  
  <p>Where have I gone wrong?</p>