Wer*_*hli 11 python hmac python-requests
我正在尝试使用Python来访问poloniex.com上的交易API,这是一种加密货币交换.要做到这一点,我必须遵循这个处方:
所有对交易API的调用都通过HTTP POST发送到https://poloniex.com/tradingApi,并且必须包含以下标题:
密钥 - 您的API密钥.
Sign - 根据HMAC-SHA512方法,由密钥的"秘密"签名的查询的POST数据.此外,所有查询都必须包含"nonce"POST参数.nonce参数是一个整数,必须始终大于之前使用的nonce.
这是我到目前为止所拥有的.我目前的问题是我不知道如何编译POST网址,以便可以在不先发送未完成请求的情况下对其进行签名.这显然不起作用.
import requests
import hmac
import hashlib
import time
headers = { 'nonce': '',
'Key' : 'myKey',
'Sign': '',}
payload = { 'command': 'returnCompleteBalances',
'account': 'all'}
secret = 'mySecret'
headers['nonce'] = int(time.time())
response = requests.post( 'https://poloniex.com/tradingApi', params= payload, headers= headers )
headers['Sign'] = hmac.new( secret, response.url, hashlib.sha512)
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 21
创建准备好的请求 ; 您可以在创建正文后为其添加标题:
import requests
import hmac
import hashlib
request = requests.Request(
'POST', 'https://poloniex.com/tradingApi',
data=payload, headers=headers)
prepped = request.prepare()
signature = hmac.new(secret, prepped.body, digestmod=hashlib.sha512)
prepped.headers['Sign'] = signature.hexdigest()
with requests.Session() as session:
response = session.send(prepped)
Run Code Online (Sandbox Code Playgroud)
我改变了你的params论点data; 对于POST请求,通常在主体中发送参数,而不是URL.
对于nonce,我会使用一个从当前时间播种的itertools.count()对象,因此重启不会影响它.根据Poloniex API文档(您在问题中引用),nonce是POST主体的一部分,而不是标题,因此将其放在payload字典中:
from itertools import count
import time
# store as a global variable
NONCE_COUNTER = count(int(time.time() * 1000))
# then every time you create a request
payload['nonce'] = next(NONCE_COUNTER)
Run Code Online (Sandbox Code Playgroud)
int(time.time())如果您每秒创建多个请求,则使用将重复使用相同的数字.在由Poloniex提供的示例代码使用int(time.time()*1000),以使其能够创建请求每微秒,而不是,而是用自己的单调递增计数器(从种子time.time())是稳健得多.
您还可以将摘要签名过程封装在自定义身份验证对象中 ; 这样的对象在准备好的请求中作为准备的最后一步传递:
import hmac
import hashlib
class BodyDigestSignature(object):
def __init__(self, secret, header='Sign', algorithm=hashlib.sha512):
self.secret = secret
self.header = header
self.algorithm = algorithm
def __call__(self, request):
body = request.body
if not isinstance(body, bytes): # Python 3
body = body.encode('latin1') # standard encoding for HTTP
signature = hmac.new(self.secret, body, digestmod=self.algorithm)
request.headers[self.header] = signature.hexdigest()
return request
Run Code Online (Sandbox Code Playgroud)
与您的requests通话一起使用:
response = requests.post(
'https://poloniex.com/tradingApi',
data=payload, headers=headers, auth=BodyDigestSignature(secret))
Run Code Online (Sandbox Code Playgroud)
传入的论点是HMAC摘要中使用的秘密; 您还可以传入不同的标题名称.