淘宝api Python 接口升级 3.0 版本 主要解决图片上传问题

因为自学 python  工作中会经常用到淘宝Api调用数据    一直以来后台下载的淘宝Api 都是2.7版本

还是12年 lihao同学编写,一直没有升级

用Python 自带的2to3脚本工具升级后 大部分接口 调用正常

但是上传图片接口 一直提示错误 

由于是初学  只能网上找资料了 找了很多资料 都没解决 

最后通过国外友人的一篇博客 找到了解决方法 

在这里分享一下 希望能帮助其他人  只要替换 base.py 代码就可以 初步测试调用接口 都能成功

# -*- coding: utf-8 -*-
'''
Created on 2012-7-3

@author: lihao
'''

try: import httplib
except ImportError:
    import http.client as httplib
import urllib
import time
import hashlib
import json
import top
import itertools
import mimetypes
import requests
'''
定义一些系统变量
'''

SYSTEM_GENERATE_VERSION = "taobao-sdk-python-20191017"

P_APPKEY = "app_key"
P_API = "method"
P_SESSION = "session"
P_ACCESS_TOKEN = "access_token"
P_VERSION = "v"
P_FORMAT = "format"
P_TIMESTAMP = "timestamp"
P_SIGN = "sign"
P_SIGN_METHOD = "sign_method"
P_PARTNER_ID = "partner_id"

P_CODE = 'code'
P_SUB_CODE = 'sub_code'
P_MSG = 'msg'
P_SUB_MSG = 'sub_msg'


N_REST = '/router/rest'

def sign(secret, parameters):
    #===========================================================================
    # '''签名方法
    # @param secret: 签名需要的密钥
    # @param parameters: 支持字典和string两种
    # '''
    #===========================================================================
    # 如果parameters 是字典类的话
    if hasattr(parameters, "items"):
        parameters = "%s%s%s" % (secret,
            str().join('%s%s' % (key, parameters[key]) for key in sorted(parameters)),
            secret)
        print(parameters)
    m = hashlib.md5()

    m.update(parameters.encode("utf-8"))
    sign = m.hexdigest().upper()
    print(sign)
    return sign


    
class FileItem(object):
    def __init__(self,filename=None,content=None):
        self.filename = filename
        self.content = content

class MultiPartForm(object):
    """Accumulate the data to be used when posting a form."""

    def __init__(self):
        self.form_fields = {}
        self.files = {}
        self.boundary = "PYTHON_SDK_BOUNDARY"
        return
    
    def get_content_type(self):
        return 'multipart/form-data; boundary=%s' % self.boundary

    def add_field(self, name, value):
        """Add a simple field to the form data."""
        self.form_fields[name]=value
        return

    def add_file(self, fieldname, filename, fileHandle, mimetype=None):
        """Add a file to be uploaded."""
        self.files[fieldname]=(filename, fileHandle)
        return
    
    def __str__(self):
        """Return a string representing the form data, including attached files."""
        # Build a list of lists, each containing "lines" of the
        # request.  Each part is separated by a boundary string.
        # Once the list is built, return a string where each
        # line is separated by '\r\n'.  
        parts = []
        part_boundary = '--' + self.boundary
        
        # Add the form fields
        parts.extend(
            [ part_boundary,
              'Content-Disposition: form-data; name="%s"' % name,
              'Content-Type: text/plain; charset=UTF-8',
              '',
              value,
            ]
            for name, value in self.form_fields
            )
        
        # Add the files to upload
        parts.extend(
            [ part_boundary,
              'Content-Disposition: file; name="%s"; filename="%s"' % \
                 (field_name, filename),
              'Content-Type: %s' % content_type,
              'Content-Transfer-Encoding: binary',
              '',
              body,
            ]
            for field_name, filename, content_type, body in self.files
            )
        
        # Flatten the list and add closing boundary marker,
        # then return CR+LF separated data
        flattened = list(itertools.chain(*parts))
        flattened.append('--' + self.boundary + '--')
        flattened.append('')
        return '\r\n'.join(flattened)

class TopException(Exception):
    #===========================================================================
    # 业务异常类
    #===========================================================================
    def __init__(self):
        self.errorcode = None
        self.message = None
        self.subcode = None
        self.submsg = None
        self.application_host = None
        self.service_host = None

    def __str__(self, *args, **kwargs):
        sb = "errorcode=" + self.errorcode +\
            " message=" + self.message +\
            " subcode=" + self.subcode +\
            " submsg=" +self.submsg +\
            " application_host=" +self.application_host +\
            " service_host=" +self.service_host
        return sb
       
class RequestException(Exception):
    #===========================================================================
    # 请求连接异常类
    #===========================================================================
    pass

class RestApi(object):
    #===========================================================================
    # Rest api的基类
    #===========================================================================
    
    def __init__(self, domain='gw.api.taobao.com', port = 80):
        #=======================================================================
        # 初始化基类
        # Args @param domain: 请求的域名或者ip
        #      @param port: 请求的端口
        #=======================================================================
        self.__domain = domain
        print(domain)
        self.__port = port
        self.__httpmethod = "POST"
        if(top.getDefaultAppInfo()):
            self.__app_key = top.getDefaultAppInfo().appkey
            self.__secret = top.getDefaultAppInfo().secret
        
    def get_request_header(self):
        return {
                 'Content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
                 "Cache-Control": "no-cache",
                 "Connection": "Keep-Alive",
        }
        
    def set_app_info(self, appinfo):
        #=======================================================================
        # 设置请求的app信息
        # @param appinfo: import top
        #                 appinfo top.appinfo(appkey,secret)
        #=======================================================================
        self.__app_key = appinfo.appkey
        self.__secret = appinfo.secret
        
    def getapiname(self):
        return ""
    
    def getMultipartParas(self):
        return [];

    def getTranslateParas(self):
        return {};
    
    def _check_requst(self):
        pass
    
    def getResponse(self, authrize=None, timeout=30):
        if 'http://' not in self.__domain:
            self.__domain = 'http://' + self.__domain
        #=======================================================================
        # 获取response结果
        #=======================================================================
        sys_parameters = {
            P_FORMAT: 'json',
            P_APPKEY: self.__app_key,
            P_SIGN_METHOD: "md5",
            P_VERSION: '2.0',
            P_TIMESTAMP: str(int(time.time()) * 1000),
            P_PARTNER_ID: SYSTEM_GENERATE_VERSION,
            P_API: self.getapiname(),
        }
        if authrize is not None:
            sys_parameters[P_SESSION] = authrize
        application_parameter = self.getApplicationParameters()
        sign_parameter = sys_parameters.copy()
        sign_parameter.update(application_parameter)
        sys_parameters[P_SIGN] = sign(self.__secret, sign_parameter)
        url = self.__domain + N_REST + "?" + urllib.parse.urlencode(sys_parameters)
        header = self.get_request_header();
        if(self.getMultipartParas()):
            form = MultiPartForm()
            for key, value in application_parameter.items():
                form.add_field(key, value)
            for key in self.getMultipartParas():
                fileitem = getattr(self,key)
                if(fileitem and isinstance(fileitem,FileItem)):
                    form.add_file(key,fileitem.filename,fileitem.content)
            header['Content-type'] = form.get_content_type()
            response = requests.post(url, data=form.form_fields, files=form.files)
        else:
            response = requests.post(url, data=application_parameter,headers=header)
        print(response.status_code)
        if response.status_code is not 200:
            raise RequestException('invalid http status ' + str(response.status) + ',detail body:' + response.read())
        result = response.text
        print(result)
        jsonobj = json.loads(result)
        if jsonobj.get("error_response"):
            error = TopException()
            if jsonobj["error_response"].get(P_CODE) :
                error.errorcode = jsonobj["error_response"][P_CODE]
            if jsonobj["error_response"].get(P_MSG) :
                error.message = jsonobj["error_response"][P_MSG]
            if jsonobj["error_response"].get(P_SUB_CODE) :
                error.subcode = jsonobj["error_response"][P_SUB_CODE]
            if jsonobj["error_response"].get(P_SUB_MSG) :
                error.submsg = jsonobj["error_response"][P_SUB_MSG]
            print(response.headers)
            error.application_host = response.headers.get("Application-Host", "")
            error.service_host = response.headers.get("Location-Host", "")
            raise error
        return jsonobj
    def getApplicationParameters(self):
        application_parameter = {}
        for key, value in self.__dict__.items():
            if not key.startswith("__") and not key in self.getMultipartParas() and not key.startswith("_RestApi__") and value is not None :
                if(key.startswith("_")):
                    application_parameter[key[1:]] = value
                else:
                    application_parameter[key] = value
        #查询翻译字典来规避一些关键字属性
        translate_parameter = self.getTranslateParas()
        for key, value in application_parameter.items():
            if key in translate_parameter:
                application_parameter[translate_parameter[key]] = application_parameter[key]
                del application_parameter[key]
        return application_parameter

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值