I'm trying to write a nice auth helper for kraken. I want it to be as automatic as possible, so it needs to:
- add a nonce (
time.time()*1000
) to the POST body - calculate a signature over the POST body
- put the signature into the headers
I wrote the obvious code based on this answer:
class KrakenAuth(AuthBase):
"""a requests-module-compatible auth module for kraken.com"""
def __init__(self, key, secret):
self.api_key = key
self.secret_key = secret
def __call__(self, request):
#print("Auth got a %r" % type(request))
nonce = int(1000*time.time())
request.data = getattr(request, 'data', {})
request.data['nonce'] = nonce
request.prepare()
message = request.path_url + hashlib.sha256(str(nonce) + request.body).digest()
hmac_key = base64.b64decode(self.secret_key)
signature = hmac.new(hmac_key, message, hashlib.sha512).digest()
signature = base64.b64encode(signature)
request.headers.update({
'API-Key': self.api_key,
'API-Sign': signature
})
return request
and them I'm calling it (from a wrapper method on another object) like:
def _request(self, method, url, **kwargs):
if not self._auth:
self._auth = KrakenAuth(key, secret)
if 'auth' not in kwargs:
kwargs['auth'] = self._auth
return self._session.request(method, URL + url, **kwargs)
...but it doesn't work. The commented-out print()
statement shows that it's getting a PreparedRequest
object not a Request
object, and thus the call to request.prepare()
is a call to PreparedRequest.prepare
does nothing useful because there's no request.data
because it's already been converted into a body
attribute.