Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 商业巨蟒_Python_Api_Http_Post_Woocommerce - Fatal编程技术网

Python 商业巨蟒

Python 商业巨蟒,python,api,http,post,woocommerce,Python,Api,Http,Post,Woocommerce,我正在尝试使用一个Python客户端发出POST请求,但是 我得到“提供的签名不匹配” 我使用的客户端来自: 这是我的客户: #!/usr/bin/env python import requests import random import string import time from hashlib import sha1 import hmac import binascii import re import collections from urllib import quote,

我正在尝试使用一个Python客户端发出POST请求,但是 我得到“提供的签名不匹配”

我使用的客户端来自:

这是我的客户:

#!/usr/bin/env python

import requests
import random
import string
import time
from hashlib import sha1
import hmac
import binascii
import re
import collections
from urllib import quote, urlencode


def uksort(dictionary):
    return collections.OrderedDict(sorted(dictionary.items(), cmp = cmp))

class WooCommerce(object):
    def __init__(self, consumer_key, consumer_secret, endpoint):

        self.consumer_key = consumer_key
        self.consumer_secret = consumer_secret
        self.endpoint = endpoint

    def _make_request(self, resource, params, method = "GET"):
        oauth_params = {
            "oauth_consumer_key": self.consumer_key,
            "oauth_nonce": self._gen_nonce(),
            "oauth_timestamp": self._gen_timestamp(),
            "oauth_signature_method": "HMAC-SHA1",
        }

        oauth_params["oauth_signature"] = self._gen_signature(resource, dict(params.items() + oauth_params.items()), method)
        params = dict(params.items() + oauth_params.items())

        if method == "GET":
            print self.endpoint + resource + "?" + urlencode(params)
        elif method == "POST":
            print self.endpoint + resource + "?" + urlencode(params)
            req = urllib.request.Request(self.endpoint + resource + "?" + urlencode(params))
            open = urllib.request.urlopen(req)
            requestContent = open.read()
            #print(open)

    def _gen_nonce(self):

        ran_string = ''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(32)).encode("base64")
        alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", ran_string)
        return alnum_hash

    def _gen_timestamp(self):

        return int(time.time())

    def _gen_signature(self, resource, params, method):

        base_request_uri = quote(self.endpoint + resource, safe = "")
        normalized_params = self._normalize_params(params)
        sorted_params = uksort(normalized_params)
        query_string = "%26".join([key + "%3D" + value for key, value in sorted_params.iteritems()])

        raw_string = method + "&" + base_request_uri + "&" + query_string
        hashed = hmac.new(self.consumer_secret, raw_string, sha1)

        return binascii.b2a_base64(hashed.digest()).rstrip("\n")

    def _normalize_params(self, params):

        normalized = {}

        for key, value in params.iteritems():
            key = quote(str(key), safe = "")
            value = quote(str(value), safe = "")

            normalized[key] = value

        return normalized
我从另一个类中这样使用它:

woo_client = WooCommerce('ck_7bb1951bee7454b2e29bf5eef9205e0e', 'cs_155cd9420201c0a7e140bebd6a9794c7', 'http://dima.bg/wc-api/v2')

data = {
               "product": {
                "title": "testname",
               }
           }    
result = self.woo_client._make_request("/products/", data, 'POST')
你能看到我的URL有问题吗?谢谢你抽出时间


我使用您的代码作为自己解决此问题的起点,并取得了一些成功!以下是我所做的:

import requests
import random
import string
import time
from hashlib import sha1
import hmac
import binascii
import re
from urllib import quote, urlencode
import httplib2
from collections import OrderedDict

def key_compare(a, b):
    return cmp(a[0], b[0])

class Restful_Client(object):
    """docstring for Restful_Client"""
    def __init__(self, endpoint, consumer_key, consumer_secret):
        super(Restful_Client, self).__init__()
        self.consumer_key = consumer_key
        self.consumer_secret = consumer_secret
        self.endpoint = endpoint

    def make_request(self, resource, params, method='GET' ):
        oauth_params = {
            'oauth_consumer_key': self.consumer_key,
            'oauth_nonce': self.gen_nonce(),
            'oauth_timestamp': self.gen_timestamp(),
            'oauth_signature_method': 'HMAC-SHA1',
            # 'oauth_version':'1.0'
        }
        oauth_params['oauth_signature'] = self.gen_signature(
            resource,
            OrderedDict( params.items() + oauth_params.items() ),
            method
        )
        params = OrderedDict( params.items() + oauth_params.items() )
        clean_params = self.sort_params(self.normalize_params(params))

        uri = endpoint + resource
        p_string = urlencode(clean_params)

        print 'p string:'
        print '\n'.join(p_string.split('&'))

        return httplib2.Http().request(uri + '?' + p_string)

    def gen_signature(self, resource, params, method):
        base_request_uri = quote(self.endpoint + resource, safe = "")
        clean_params = self.sort_params(
            self.normalize_params(
                self.normalize_params(
                    params
                )
            )
        )
        query_string = '%26'.join([
            key + '%3D' + value\
            for key, value in clean_params.iteritems()
        ])
        raw_string = '&'.join([method, base_request_uri, query_string]) 
        print "raw string: "
        print '\n'.join(raw_string.split('%26'))
        hashed = hmac.new(self.consumer_secret, raw_string, sha1)
        return binascii.b2a_base64( hashed.digest() )[:-1]

    def normalize_string(self, string):
        return quote(str(string), safe="")

    def normalize_params(self, params):
        return OrderedDict( [
            (self.normalize_string(key), self.normalize_string(value))\
            for key, value \
            in params.iteritems()
        ])

    def sort_params(self, params):
        return OrderedDict(sorted(
            params.iteritems(),
            cmp=key_compare
        ))

    def gen_timestamp(self):
        return int(time.time())
        # return 1429451603

    def gen_nonce(self):
        return hex(self.gen_timestamp())
        #todo: make this more secure

if __name__ == "__main__":
    store_url = '<STORE URL HERE>'
    api_base = 'wc-api'
    api_ver = 'v2'
    endpoint = "%s/%s/%s/" % (store_url, api_base, api_ver)

    consumer_key = '<CK HERE>'
    consumer_secret = '<CS HERE>'

    resource = 'customers'
    parameters = {
        # 'fields':'id,first_name'
    }

    rc = Restful_Client(endpoint, consumer_key, consumer_secret)
    r, c = rc.make_request(resource, parameters, 'GET')
    print r
    print c
导入请求
随机输入
导入字符串
导入时间
从hashlib导入sha1
进口hmac
导入binascii
进口稀土
从urllib导入报价,urlencode
导入httplib2
从集合导入订单
def键比较(a、b):
返回cmp(a[0],b[0])
类Restful_客户端(对象):
“”“Restful\u客户端的docstring”“”
定义初始化(自我、端点、使用者密钥、使用者密钥):
super(Restful\u客户机,self)。\u初始化
self.consumer\u key=consumer\u key
self.consumer\u secret=consumer\u secret
self.endpoint=端点
def make_请求(self、resource、params、method='GET'):
oauth_参数={
'oauth_consumer_key':self.consumer_key,
'oauth\u nonce':self.gen\u nonce(),
'oauth_timestamp':self.gen_timestamp(),
“oauth_签名_方法”:“HMAC-SHA1”,
#“oauth_版本”:“1.0”
}
oauth_参数['oauth_签名']=self.gen_签名(
资源
OrderedDict(params.items()+oauth_params.items()),
方法
)
params=OrderedDict(params.items()+oauth_params.items())
clean_params=self.sort_params(self.normalize_params(params))
uri=端点+资源
p_字符串=urlencode(清除参数)
打印“p字符串:”
打印'\n'.join(p_string.split('&'))
返回httplib2.Http()
def gen_签名(自身、资源、参数、方法):
base_request_uri=quote(self.endpoint+resource,safe=”“)
clean_参数=self.sort_参数(
self.normalize_参数(
self.normalize_参数(
params
)
)
)
查询字符串='%26'。加入([
键+“%3D”+值\
对于键,使用clean_params.iteritems()中的值
])
原始字符串='&'.join([method,base\u request\u uri,query\u string])
打印“原始字符串:”
打印'\n'.join(原始字符串.split('%26'))
hashed=hmac.new(self.consumer\u secret,原始字符串,sha1)
返回binascii.b2a_base64(hashed.digest())[:-1]
def规格化_字符串(self,string):
返回引号(str(string),safe=“”)
def规格化参数(自身,参数):
退货订单信息技术([
(self.normalize_字符串(键)、self.normalize_字符串(值))\
对于键,值\
在params.iteritems()中
])
def排序参数(自身,参数):
退货订单DICT(已排序)(
params.iteritems(),
cmp=键\u比较
))
def gen_时间戳(自身):
返回int(time.time())
#返回1429451603
def发电机(自身):
返回十六进制(self.gen\u timestamp())
#todo:让它更安全
如果名称=“\uuuuu main\uuuuuuuu”:
存储url=“”
api_base='wc api'
api_ver='v2'
endpoint=“%s/%s/%s/”%(存储url、api基础、api版本)
消费者密钥=“”
消费者机密=“”
资源='客户'
参数={
#“字段”:“id,名字”
}
rc=Restful\u客户端(端点、使用者密钥、使用者密钥)
r、 c=rc.make_请求(资源、参数“GET”)
印刷机
打印c
我的建议是确保参数的编码次数正确,我发现参数需要“双重编码”才能工作。在这种情况下,您的参数(键和值字符串)似乎不是API文档中建议的“双重编码”

您可以通过尝试一个简单的GET请求来验证这个假设,而不需要像我的代码中那样的任何参数。如果这样做有效,那可能是你的问题。祝你好运