2017-02-07 19 views
5

Tôi đang cố gắng sử dụng Python để truy cập vào API giao dịch tại poloniex.com, một trao đổi tiền điện tử. Để thực hiện điều này, tôi phải tuân theo toa này:Tôi làm cách nào để ký yêu cầu POST bằng HMAC-SHA512 và thư viện yêu cầu Python?

Tất cả các cuộc gọi đến các API giao dịch được gửi qua HTTP POST để https://poloniex.com/tradingApi và phải có các tiêu đề sau:

Key - chìa khóa API của bạn.
Dấu - Dữ liệu POST của truy vấn được ký bằng "bí mật" của khóa theo phương thức HMAC-SHA512.

Ngoài ra, tất cả truy vấn phải bao gồm thông số POST "nonce". Tham số nonce là một số nguyên phải luôn luôn lớn hơn nonce trước đó được sử dụng.

Đây là những gì tôi có cho đến nay. Vấn đề hiện tại của tôi là tôi không biết làm thế nào để biên dịch các POST URL để nó có thể được ký kết mà không gửi yêu cầu không đầy đủ đầu tiên. Điều này rõ ràng không hoạt động.

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) 

Trả lời

11

Tạo prepared request; bạn có thể thêm tiêu đề cho rằng sau khi cơ thể đã được tạo ra:

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) 

tôi đã thay đổi params luận của bạn để data; đối với yêu cầu POST, thông thường phải gửi các tham số trong nội dung chứ không phải URL.

Đối với nonce, tôi muốn sử dụng một số itertools.count() object, được gieo từ thời điểm hiện tại để khởi động lại không ảnh hưởng đến nó. Theo Poloniex API documentation (mà bạn trích dẫn trong câu hỏi của bạn), nonce là một phần của cơ thể POST, không phải là tiêu đề, do đó đặt nó trong payload từ điển:

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) 

Sử dụng int(time.time()) sẽ tái sử dụng cùng một số nếu bạn đã tạo nhiều yêu cầu mỗi giây. Ví dụ: example code provided by Poloniex sử dụng int(time.time()*1000) để có thể tạo yêu cầu mỗi micro giây, nhưng sử dụng bộ đếm tăng đơn điệu của riêng bạn (được gieo từ time.time()) mạnh hơn rất nhiều.

Bạn cũng có thể đóng gói quy trình ký thông báo trong một số custom authentication object; một đối tượng đó được thông qua trong yêu cầu chuẩn bị như là bước cuối cùng để chuẩn bị:

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 

Sử dụng này với requests cuộc gọi của bạn:

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

Đối số được thông qua năm là bí quyết sử dụng trong HMAC tiêu hóa; bạn cũng có thể truyền vào một tên tiêu đề khác.

+0

Điều đó thật nhanh, Cảm ơn rất nhiều! – Werhli

+0

@MartijnPieters khi tôi chạy điều này tôi nhận được một lỗi nói: 'Yêu cầu' đối tượng không có thuộc tính 'cơ thể'. cho dòng này: signature = hmac.new (bí mật, request.body, digestmod = hashlib.sha512) –

+0

@abcla sửa –

Các vấn đề liên quan