使用Python 3.3中的请求和请求oauthlib验证API调用

时间:2014-03-19 16:21:23

标签: python api oauth python-requests

我试图使用requests和requests-oauthlib库在Python 3中编写自己的Cryptsy API包装器。我是API调用和Python的新手。就目前而言,我收到了这个错误:

{'error': 'Unable to Authorize Request - Check Your Post Data', 'success': '0'}

这并不奇怪,因为我很难找到使用这些库调用/签署经过身份验证的API请求的文档。我不太确定从哪里开始。

这是我的代码片段:

import time
import requests
from requests-oauthlib import OAuth1Session

class Cryptsy:

    def __init__(self, APIKey, Secret):
        self.APIKey = APIKey
        self.Secret = Secret
        self.privateBaseURL = 'https://api.cryptsy.com/api'

    def private_api_query(self, method, payload={}):
        url = self.privateBaseURL
        session = OAuth1Session(self.APIKey, client_secret=self.Secret)
        payload['method'] = method
        payload['nonce'] = int(time.time())
        response = session.post(url, data=payload)
        js = response.json()
        return js

    def getMarkets(self):
        return self.private_api_query('getmarkets')

正如您所看到的,我隐约知道nonce,但我不确定在使用这些库时它是否甚至是必要的。我知道请求需要签名,但不知道如何让这些库以我需要的方式完成。

当然,我总是可以尝试使用urllib,但是自从切换到Python 3后我就遇到了麻烦,我喜欢请求库的(假设)直截了当。

有关Cryptsy API的更多信息,请访问:https://www.cryptsy.com/pages/api

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

Cryptsy并没有使用OAuth(至少他们的文档并没有声称他们这样做)。相反,他们推出自己的身份验证。暂且不谈这种方法的安全性,让我们来看看你需要什么。

他们的文件不是很好,但是从我的阅读中你需要:

  • 两个额外标题:(包含您的公共API密钥)和签名(包含正文的HMAC-SHA512签名)
  • 内容类型为application/x-www-form-urlencoded的请求正文,其中包含方法名称,方法参数和随机数。

在请求中使这项工作比平常简单一点,但最简单的方法是编写自己的自定义Authentication handler。这是一个例子:

from requests.auth import AuthBase
import hmac
import hashlib
import time

class CryptsyAuth(AuthBase):
    """Authenticates a given HTTP request using the Cryptsy Auth scheme"""
    def __init__(self, api_key, api_secret):
        self.key = api_key
        self.secret = api_secret

    def __call__(self, r):
        r.body += '&nonce=%d' % int(time.time())
        h = hmac.new(self.secret, r.body, hashlib.sha512).hexdigest()

        r.headers['Key'] = self.key
        r.headers['Sign'] = h
        return r

请注意,如果您没有提供请求正文,则此auth处理程序将会失效,但这是正常的,因为Cryptsy要求您这样做。以下是您如何使用它:

class Cryptsy:

    def __init__(self, APIKey, Secret):
        self.APIKey = APIKey
        self.Secret = Secret
        self.privateBaseURL = 'https://api.cryptsy.com/api'
        self.session = requests.Session()

    def private_api_query(self, method, payload={}):
        url = self.privateBaseURL
        payload['method'] = method
        response = self.session.post(url, data=payload, auth=CryptsyAuth(self.APIKey, self.Secret))
        js = response.json()
        return js

    def getMarkets(self):
        return self.private_api_query('getmarkets')