适应python3的淘宝API核心base类

简介: # -*- coding: utf-8 -*-'''Created on 2012-7-3@author: lihao'''try: import httplibexcept ImportError: import http.
# -*- 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
目录
相关文章
|
28天前
|
缓存 监控 API
淘宝 API 接口使用的技术要点与注意事项
在数字化商业环境中,淘宝API为开发者提供了强大的工具,用于与淘宝平台交互,获取商品信息及处理交易等。本文总结了正确使用API的关键技术要点:注册认证、理解接口文档、遵守调用限制、确保参数准确性、保护数据安全、处理异常、性能优化、版本兼容、合规性及日志监控,帮助开发者实现高效、安全的程序开发。
|
4天前
|
前端开发 Python
Python编程的面向对象(二)—类的多态
Python编程的面向对象(二)—类的多态
12 7
|
3天前
|
IDE Java 开发工具
Python类与面向对象
Python类与面向对象
|
3天前
|
XML JSON API
淘宝商品详情API接口:获取商品信息的指南
淘宝详情API接口是淘宝开放平台提供的一种API接口,它允许开发者通过编程方式获取淘宝商品的详细信息。这些信息包括商品的基本属性、价格、库存状态、销售策略、卖家信息等,对于电商分析、市场研究或者商品信息管理等场景非常有用。
14 1
|
7天前
|
关系型数据库 MySQL Python
mysql之python客户端封装类
mysql之python客户端封装类
|
8天前
|
Python
python 类中的内置方法
python 类中的内置方法
|
20天前
|
JSON 安全 API
淘宝 API 接口:解锁商品详情的强大工具
淘宝API接口在电商领域扮演着关键角色,为商家和开发者提供强大的数据支持和服务能力。它不仅帮助商家获取商品信息、管理订单和物流,还支持数据分析、价格调整等功能,助力商家在竞争激烈的市场中取得成功。此外,通过注册认证、搭建开发环境等步骤,开发者可快速上手并利用丰富的技术文档和社区支持进行高效开发。
|
27天前
|
Java API 开发者
【Java字节码操控新篇章】JDK 22类文件API预览:解锁Java底层的无限可能!
【9月更文挑战第6天】JDK 22的类文件API为Java开发者们打开了一扇通往Java底层世界的大门。通过这个API,我们可以更加深入地理解Java程序的工作原理,实现更加灵活和强大的功能。虽然目前它还处于预览版阶段,但我们已经可以预见其在未来Java开发中的重要地位。让我们共同期待Java字节码操控新篇章的到来!
|
25天前
|
Java API 开发者
【Java字节码的掌控者】JDK 22类文件API:解锁Java深层次的奥秘,赋能开发者无限可能!
【9月更文挑战第8天】JDK 22类文件API的引入,为Java开发者们打开了一扇通往Java字节码操控新世界的大门。通过这个API,我们可以更加深入地理解Java程序的底层行为,实现更加高效、可靠和创新的Java应用。虽然目前它还处于预览版阶段,但我们已经可以预见其在未来Java开发中的重要地位。让我们共同期待Java字节码操控新篇章的到来,并积极探索类文件API带来的无限可能!
|
1月前
|
XML JSON API
淘宝京东商品详情数据解析,API接口系列
淘宝商品详情数据包括多个方面,如商品标题、价格、图片、描述、属性、SKU(库存量单位)库存、视频等。这些数据对于买家了解商品详情以及卖家管理商品都至关重要。
下一篇
无影云桌面