Package: doudian
抖店 Python SDK介绍抖店 Python SDK。欢迎抖店相关开发者扫码进 QQ 群(群号：799137292)讨论：适用对象抖店 Python SDK同时支持自用型应用和工具型应用，具体说明详见官网。特性自动维护 access_token 的更新；支持本地缓存 access_token；业务参数自动排序，无需预处理；消息推送自动验证，自动解析；支持沙箱环境测试店铺。源码githubgitee安装$ pip install doudian使用方法准备参考抖店官方文档准备好 app key、app secret、shop id 等，具体见官方开发文档。一个最小的后端examples.py演示了一个带有会员订单列表查询接口和消息推送处理接口的后端。
首先，修改examplys.py里以下几项配置参数：# App类型，SELF=自用型应用, TOOL=工具型应用APP_TYPE=AppType.SELF# 应用key，长度19位数字字符串APP_KEY='3409409348479354011'# 应用密钥 字符串APP_SECRET='2ad2355c-01d0-11f8-91dc-05a8cd1054b1'# 店铺ID，自用型应用必传。SHOP_ID='323423'# token缓存文件TOKEN_FILE='./323423.token'# 日志记录器，记录web请求和回调细节logging.basicConfig(filename=os.path.join(os.getcwd(),'demo.log'),level=logging.DEBUG,filemode='a',format='%(asctime)s-%(process)s-%(levelname)s:%(message)s')LOGGER=logging.getLogger("demo")# 代理设置，None或者{"https": "http://10.10.1.10:1080"}，详细格式参见https://docs.python-requests.org/zh_CN/latest/user/advanced.htmlPROXY=None# 沙箱模式测试店铺TEST_MODE=False接下来初始化 DouDian 实例并配置一个合适的接口：# 初始化doudian=DouDian(app_key=APP_KEY,app_secret=APP_SECRET,app_type=APP_TYPE,shop_id=SHOP_ID,token_file=TOKEN_FILE,logger=LOGGER,proxy=PROXY,test_mode=TEST_MODE)app=Flask(__name__)@app.route('/brandList')defbrand_list():# 以获取店铺的已授权品牌列表为例，参照官方文档，将path和params拼凑好传入request接口，调用成功后即可获取店铺的已授权品牌列表数据。# https://op.jinritemai.com/docs/api-docs/13/54path='/shop/brandList'params={}result=doudian.request(path=path,params=params)returnjsonify({'result':resultifresultelse''})检查一下参数无误，现在就可以用 python 解释器来运行：$pythonexamples.py*ServingFlaskapp"examples"(lazyloading)*Environment:productionWARNING:Thisisadevelopmentserver.Donotuseitinaproductiondeployment.UseaproductionWSGIserverinstead.*Debugmode:off*Runningonhttp://127.0.0.1:5000/(PressCTRL+Ctoquit)现在访问http://127.0.0.1:5000/orderList，如果一切正常，你会看到类似下面一串 json 字符串：{"result":{"code":10000,"data":[],"err_no":0,"log_id":"20211203091350010194059098259B567F","message":"success","msg":"success","sub_code":"","sub_msg":""}}到这一步一个最小化的后端就完成了。以上步骤如果不能正确执行，务必仔细检查各项初始化参数，必要的情况下，登录抖店后台，将所有参数重置。下面配置一个消息推送接口，以便接收处理抖店提供的消息推送服务。@app.route('/notify',methods=['POST'])defnotify():result=doudian.callback(request.headers,request.data)ifresult:tag=result.get('tag')iftag=='0':# 抖店推送服务验证消息，需立即返回successreturnjsonify({'code':0,'msg':'success'})iftag=='100':# 订单创建消息，更多消息类型查阅官方文档。# TODO: 根据推送的消息参数进行必要的业务处理，5秒内返回successreturnjsonify({'code':0,'msg':'success'})returnjsonify({'code':0,'msg':'success'})else:returnjsonify({'code':40041,'message':'解析推送数据失败'})消息推送接口上线后，将 url 地址配置到抖店后台，抖店服务器将自动推送一条 tag 值为'0'的验证消息，验证通过后方能启用消息推送服务。通用接口request(path: str, params: dict)所有抖店的 API 调用都通过**doudian.request()**接口进行。此接口需要传入 path 和 params 两个参数。
参数值参照官方文档组织，形式类似下面的代码，其中 params 只需要传入请求参数或业务参数，公共参数无需传入，SDK 内部会自行处理：path='/member/searchList'params={}params.update({'app_id':1})params.update({'start_time':'2021/10/12 00:00:00'})params.update({'end_time':'2021/10/12 00:00:00'})params.update({'page':1})params.update({'size':50})result=doudian.request(path=path,params=params)init_token(code: str)用于初始化或重置 access token，通常情况下无需手工调用，仅当以下场景时才需要：工具型（AppType.TOOL）应用初始化 DouDian 的时候未传入 code，可在获取到 code 时调用；工具型（AppType.TOOL）或自用型（AppType.SELF）应用需要强制重置 access token 时调用;捕获到 TokenError 异常时调用。callback(headers: dict, body: bytes)抖店消息推送解析验证接口，将收到的推送 headers 和 body 原样传入，接口内自动解析并验证。result=doudian.callback(request.headers,request.data)build_auth_url(service_id: str, state: str)工具型应用授权 url 构造接口，生成的授权 url 发送给商户完成授权验证以获取 code。获取到的 code 可以调用 init_token(code)接口进行 access token 的初始化或重置。service_id='demo service id'state='demo state'result=doudian.build_auth_url(service_id=service_id,state=state)以上接口的调用示例可以参考examples.py。接口函数参数参数类型对照参考下表：抖店 API 官方文档声明doudian python sdkStringstrInt64, Numberintobject, Json, Structdict: {}List, JsonArraylist: []Boolbool: True, False接口函数返回值每个接口均返回 None 或 json。常见问题消息推送解析失败处理开发者遇到的难点之一就是消息推送解析失败的问题，由于众多的 python web 框架对回调消息的处理不完全一致，如果出现回调验证失败，请务必确认传入的 headers 和 body 的值和类型。
通常框架传过来的 headers 类型是 dict，而 body 类型是 bytes。使用以下方法可直接获取到解密后的实际内容。flask 框架直接传入 request.headers 和 request.data 即可。result=doudian.callback(headers=request.headers,body=request.data)django 框架由于 django 框架特殊性，会将 headers 做一定的预处理，可以参考以下方式调用。headers={}headers.update({'app-id':request.META.get('HTTP_APP_ID')})headers.update({'event-sign':request.META.get('HTTP_EVENT_SIGN')})result=doudian.callback(headers=headers,body=request.body)tornado 框架直接传入 request.headers 和 request.body 即可。result=doudian.callback(headers=request.headers,body=request.body)其他框架参考以上处理方法，大原则就是保证传给 callback 的参数值和收到的值一致，不要转换为 dict，也不要转换为 string。