2017-02-07 5 views
5

私は、暗号化交換であるpoloniex.comの取引APIにアクセスするためにPythonを使用しようとしています。これを行うには、私はこの処方に従わなければならない:HMAC-SHA512とPythonリクエストライブラリを使用してPOSTリクエストに署名するにはどうすればよいですか?

を取引APIへのすべての呼び出しはhttps://poloniex.com/tradingApiにHTTP POSTを介して送信されており、次のヘッダー含まれている必要があります

キー - あなたのAPIキーを。
Sign - HMAC-SHA512メソッドに従って、キーの「秘密」によって署名されたクエリのPOSTデータ。

さらに、すべてのクエリには「nonce」POSTパラメータが含まれている必要があります。 nonceパラメーターは、使用されている以前のnonceよりも常に大きくなければならない整数です。

これまで私がこれまで行ってきたことは次のとおりです。私の現在の問題は、POST URLをコンパイルする方法がわからないので、まず不完全なリクエストを送信せずに署名できるようにすることです。これは明らかに機能しません。

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) 

答えて

11

prepared requestを作成します。体が作成された後、あなたはそれにヘッダを追加することができます。

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) 

を私はdataにごparams引数を変更。 POSTリクエストの場合は、URLではなく本体でパラメータを送信するのが通例です。

ナンスの場合は、itertools.count() objectを使用して、現在の時刻からシードされるので、再起動はそれに影響しません。 (あなたがあなたの質問に引用)Poloniex API documentationによると、ナンスは、POST本体ではなく、ヘッダの一部であり、その​​辞書にそれを置く:

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) 

int(time.time())を使用して再使用するのと同じ数のだろう1秒あたり複数のリクエストを作成した場合example code provided by Poloniexint(time.time()*1000)を使用して、代わりに1マイクロ秒ごとにリクエストを作成できますが、独自の単調増加カウンタ(time.time()からシードされています)を使用すると、はるかに堅牢です。

custom authentication objectにダイジェスト署名プロセスをカプセル化することもできます。このようなオブジェクトは、準備の最後のステップとして準備されたリクエストに渡されます。

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 

使用すると、これはあなたのrequests呼び出しで:

response = requests.post(
    'https://poloniex.com/tradingApi', 
    data=payload, headers=headers, auth=BodyDigestSignature(secret)) 

に渡された引数がHMACダイジェストで使用される秘密です。別のヘッダー名を渡すこともできます。

+0

これはとても速く、ありがとうございました! – Werhli

+0

@MartijnPietersこれを実行すると、「要求」オブジェクトに属性「ボディ」がないというエラーが表示されます。この行のために:signature = hmac.new(secret、request.body、digestmod = hashlib.sha512) –

+0

@abclaが修正されました –

関連する問題