2017-02-07 1 views
5

Я пытаюсь использовать Python для доступа к торговому API на poloniex.com, cryptocurrency exchange. Для этого я должен следовать этому рецепту:Как подписать запрос POST с использованием HMAC-SHA512 и библиотеки запросов Python?

Все вызовы к торговой API отправляются с помощью HTTP POST для https://poloniex.com/tradingApi и должен содержать следующие заголовки:

Key - Ваш ключ API.
Знак - данные POST запроса, подписанные секретным ключом вашего ключа в соответствии с методом HMAC-SHA512.

Кроме того, все запросы должны включать параметр «nonce» POST. Параметр nonce представляет собой целое число, которое всегда должно быть больше предыдущего неиспользованного.

Вот что у меня есть. Моя текущая проблема заключается в том, что я не знаю, как скомпилировать URL-адрес 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) 

ответ

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) 

Я изменил свой params аргумент data; для запроса POST принято отправлять параметры в теле, а не в URL.

Для nonce, я бы использовал itertools.count() object, засеянный с текущего времени, так что перезапуск не влияет на него. Согласно Poloniex API documentation (который вы цитируемый в вашем вопросе), данный случай является частью тела 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) 

Использование int(time.time()) будет повторно использовать тот же номер если вы создали несколько запросов в секунду. example code provided by Poloniex использует int(time.time()*1000), чтобы создать запрос на каждую микросекунду вместо этого, но использование вашего собственного монотонно увеличивающегося счетчика (затраченное от 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 исправлено –

Смежные вопросы