title: WooCommerce API OAuth in python
body: <p>I'm trying to do a basic implementation of the WooCommerce API OAuth client in python following what the documentation says: <a href="http://docs.woocommercev2.apiary.io/introduction/authentication/over-http" rel="nofollow">http://docs.woocommercev2.apiary.io/introduction/authentication/over-http</a>. This is what I have so far:</p>
  
  <pre><code>import requests
  import random
  import string
  import time
  from hashlib import sha1
  import hmac
  import binascii
  import re
  from urllib import quote, urlencode
  
  def uksort(d, func):
  
      s = {}
      for k in sorted(d.keys(), cmp = func):
          s[k] = d[k]
      return s
  
  class WooCommerce(object):
      def __init__(self, consumer_key, consumer_secret, endpoint):
  
          self.consumer_key = consumer_key
          self.consumer_secret = consumer_secret
          self.endpoint = endpoint
  
      def _make_request(self, resource, params, method = "GET"):
          oauth_params = {
              "oauth_consumer_key": self.consumer_key,
              "oauth_nonce": self._gen_nonce(),
              "oauth_timestamp": self._gen_timestamp(),
              "oauth_signature_method": "HMAC-SHA1",
          }
  
          oauth_params["oauth_signature"] = self._gen_signature(resource, dict(params.items() + oauth_params.items()), method)
          params = dict(params.items() + oauth_params.items())
  
          if method == "GET":
              print self.endpoint + resource + "?" + urlencode(params)
  
      def _gen_nonce(self):
  
          ran_string = ''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(32)).encode("base64")
          alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", ran_string)
          return alnum_hash
  
      def _gen_timestamp(self):
  
          return int(time.time())
  
      def _gen_signature(self, resource, params, method):
  
          base_request_uri = quote(self.endpoint + resource, safe = "")
          normalized_params = self._normalize_params(params)
          sorted_params = uksort(normalized_params, cmp)
          query_string = "%26".join([key + "%3D" + value for key, value in sorted_params.iteritems()])
  
          raw_string = method + "&amp;" + base_request_uri + "&amp;" + query_string
          hashed = hmac.new(self.consumer_secret, raw_string, sha1)
  
          return binascii.b2a_base64(hashed.digest()).rstrip("\n")
  
      def _normalize_params(self, params):
  
          normalized = {}
  
          for key, value in params.iteritems():
              key = quote(str(key), safe = "")
              value = quote(str(value), safe = "")
  
              normalized[key] = value
  
          return normalized
  
  if __name__ == "__main__":
  
      wc = WooCommerce("CONSUMER KEY HERE", "CONSUMER SECRET HERE", "YOUR ENDPOINT")
      wc._make_request("/orders", {})
  </code></pre>
  
  <p>Which when ran, should produce a url similar to this: </p>
  
  <pre><code>http://www.example.com/wc-api/v2/orders?oauth_signature=0NqB%2BDDtJN2tf2XNkSmXLk2aHro%3D&amp;oauth_consumer_key=CONSUMERKEYHERE40&amp;oauth_signature_method=HMAC-SHA1&amp;oauth_nonce=UzlURlhUTkZaQkM5SEFVNTJWWU5IQ0s3RFZENkZDSFY&amp;oauth_timestamp=1412780008
  </code></pre>
  
  <p>But when the URL is opened, I always get this error:</p>
  
  <pre><code>{"errors":[{"code":"woocommerce_api_authentication_error","message":"Invalid Signature - provided signature does not match"}]}
  </code></pre>
  
  <p>Can anybody help me out with this?</p>