-
Notifications
You must be signed in to change notification settings - Fork 1
/
bitmex_auth.py
63 lines (50 loc) · 2.09 KB
/
bitmex_auth.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from requests.auth import AuthBase
import time
import hashlib
import hmac
from future.builtins import bytes
from future.standard_library import hooks
import config
with hooks(): # Python 2/3 compat
from urllib.parse import urlparse
class APIKeyAuth(AuthBase):
"""Attaches API Key Authentication to the given Request object."""
def __init__(self):
"""Init with Key & Secret."""
self.apiKey = config.apiKey
self.apiSecret = config.apiSecret
def __call__(self, r):
"""Called when forming a request - generates api key headers."""
# modify and return the request
nonce = generate_expires()
r.headers['api-expires'] = str(nonce)
r.headers['api-key'] = self.apiKey
r.headers['api-signature'] = generate_signature(self.apiSecret, r.method, r.url, nonce, r.body or '')
return r
def generate_expires():
return int(time.time() + 3600)
# Generates an API signature.
# A signature is HMAC_SHA256(secret, verb + path + nonce + data), hex encoded.
# Verb must be uppercased, url is relative, nonce must be an increasing 64-bit integer
# and the data, if present, must be JSON without whitespace between keys.
#
# For example, in psuedocode (and in real code below):
#
# verb=POST
# url=/api/v1/order
# nonce=1416993995705
# data={"symbol":"XBTZ14","quantity":1,"price":395.01}
# signature = HEX(HMAC_SHA256(secret, 'POST/api/v1/order1416993995705{"symbol":"XBTZ14","quantity":1,"price":395.01}'))
def generate_signature(secret, verb, url, nonce, data):
"""Generate a request signature compatible with BitMEX."""
# Parse the url so we can remove the base and extract just the path.
parsedURL = urlparse(url)
path = parsedURL.path
if parsedURL.query:
path = path + '?' + parsedURL.query
if isinstance(data, (bytes, bytearray)):
data = data.decode('utf8')
# print "Computing HMAC: %s" % verb + path + str(nonce) + data
message = verb + path + str(nonce) + data
signature = hmac.new(bytes(secret, 'utf8'), bytes(message, 'utf8'), digestmod=hashlib.sha256).hexdigest()
return signature