sp_api_client.py 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244
  1. import clickhouse_connect
  2. import time
  3. import warnings
  4. warnings.filterwarnings('ignore')
  5. import numpy as np
  6. from pymysql import Timestamp
  7. from sp_api.util import throttle_retry, load_all_pages
  8. from sp_api.api import Orders,ListingsItems,Inventories,Reports,CatalogItems
  9. from sp_api.base import Marketplaces,ReportType,ProcessingStatus
  10. import pandas as pd
  11. import gzip
  12. from io import BytesIO,StringIO
  13. from datetime import datetime, timedelta,timezone
  14. import pytz
  15. import time
  16. from dateutil.parser import parse
  17. import pymysql
  18. from typing import List, Literal
  19. from random import shuffle
  20. from retry import retry
  21. try:
  22. from ..settings import MYSQL_AUTH_CONF, MYSQL_DATA_CONF
  23. except:
  24. from sync_amz_data.sync_amz_data.settings import MYSQL_AUTH_CONF, MYSQL_DATA_CONF
  25. class SpApiRequest:
  26. def __init__(self, credentials,marketplace):
  27. self.credentials = credentials
  28. self.marketplace = marketplace
  29. @classmethod
  30. @retry(tries=3, delay=5, backoff=2, )
  31. def Token_auth(cls): # AUTH - mysql_connect_auth
  32. conn = pymysql.connect(**MYSQL_AUTH_CONF)
  33. return conn
  34. @classmethod
  35. @retry(tries=3, delay=5, backoff=2, )
  36. def Data_auth(cls): # DATA - mysql_connect_auth_lst
  37. conn = pymysql.connect(**MYSQL_DATA_CONF)
  38. return conn
  39. @classmethod
  40. @retry(tries=3, delay=5, backoff=2, )
  41. def LocalHost_Auth(cls): # local database-
  42. conn = pymysql.connect(user="huangyifan",
  43. password="123456",
  44. host="127.0.0.1",
  45. database="amz_sp_api",
  46. port=3306)
  47. return conn
  48. @staticmethod
  49. @retry(tries=3, delay=5, backoff=2, )
  50. def auth_info(): # get Auth-data from all of shops - 此连接获取refreshtoken供账户授权使用
  51. auth_conn = SpApiRequest.Token_auth()
  52. cursor = auth_conn.cursor()
  53. cursor.execute("select * from amazon_sp_report.amazon_sp_auth_info;")
  54. columns_name = [i[0] for i in cursor.description]
  55. rel = cursor.fetchall()
  56. df = pd.DataFrame(rel, columns=columns_name)
  57. return df
  58. @classmethod
  59. @retry(tries=3, delay=5, backoff=2, )
  60. def get_refreshtoken(cls): # accroding to differnt shop get diffrent refreshtoken - 获取授权后拿到refreshtoken
  61. df = cls.auth_info()
  62. refreshtoken_list = (df['refresh_token'].to_numpy().tolist())
  63. return refreshtoken_list
  64. @classmethod
  65. def get_catelog(cls,account_name,country=Marketplaces.US,asin=None): # active - 可以使用但未进行使用
  66. if country in [Marketplaces.US, Marketplaces.BR, Marketplaces.CA,Marketplaces.MX]:
  67. region = 'NA'
  68. elif country in [Marketplaces.DE,Marketplaces.AE, Marketplaces.BE, Marketplaces.PL,
  69. Marketplaces.EG,Marketplaces.ES, Marketplaces.GB, Marketplaces.IN, Marketplaces.IT,
  70. Marketplaces.NL, Marketplaces.SA, Marketplaces.SE, Marketplaces.TR,Marketplaces.UK,Marketplaces.FR,
  71. ]:
  72. region = 'EU'
  73. else:
  74. region = str(country)[-2:]
  75. df = cls.auth_info()
  76. try:
  77. refresh_token = df.query("account_name==@account_name and region==@region")['refresh_token'].values[0]
  78. except:
  79. print("请输入正确的account name与Marketplace")
  80. return '获取失败'
  81. cred = {
  82. 'refresh_token': refresh_token,
  83. 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  84. 'lwa_client_secret': 'amzn1.oa2-cs.v1.3af0f5649f5b8e151cd5bd25c10f2bf3113172485cd6ffc52ccc6a5e8512b490',
  85. 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  86. 'aws_secret_key': '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',
  87. 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  88. }
  89. # cate_item = CatalogItems(credentials=cred, marketplace=country)
  90. # images_info = cate_item.get_catalog_item(asin=asin,**{"includedData":['images']})
  91. # print(images_info)
  92. # images = images_info.images[0].get('images')[0]['link']
  93. # title_info = cate_item.get_catalog_item(asin=asin)
  94. # print(title_info)
  95. # title = title_info.payload['summaries'][0]['itemName']
  96. cate_item = CatalogItems(credentials=cred, marketplace=country,version='2022-04-01')
  97. test_bundle = cate_item.get_catalog_item(asin=asin,**{"includedData":['salesRanks']})
  98. print(test_bundle)
  99. # return {'images':images,'title':title}
  100. @retry(tries=3, delay=5, backoff=2,)
  101. def create_report(self,**kwargs): # Main-CreateReport-Function - 创建报告请求
  102. reportType = kwargs['reportType']
  103. reportOptions =kwargs.get("reportOptions")
  104. dataStartTime = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") if kwargs.get("dataStartTime") is None else kwargs.get("dataStartTime")+"T00:00:00"
  105. dataEndTime = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") if kwargs.get("dataEndTime") is None else kwargs.get("dataEndTime")+"T23:59:59"
  106. report = Reports(credentials=self.credentials, marketplace=self.marketplace)
  107. rel = report.create_report(
  108. reportType=reportType,marketplaceIds=[kwargs['marketpalceids'] if kwargs.get('marketpalceids') is not None else self.marketplace.marketplace_id],
  109. reportOptions=reportOptions,dataStartTime=dataStartTime,dataEndTime=dataEndTime
  110. )
  111. reportId = rel.payload.get("reportId")
  112. # print(reportId)
  113. return reportId
  114. # @retry(tries=2, delay=3, backoff=2,)
  115. def decompression(self,reportId): # After-CreateReportFunc-simpleDeal - 根据获取到的报告id进行解压获取
  116. report = Reports(credentials=self.credentials, marketplace=self.marketplace)
  117. while True:
  118. reportId_info = report.get_report(reportId=reportId)
  119. # print(reportId_info.payload)
  120. print("please wait...")
  121. if reportId_info.payload.get("processingStatus")==ProcessingStatus.DONE:
  122. reportDocumentId = reportId_info.payload.get("reportDocumentId")
  123. rp_table = report.get_report_document(reportDocumentId=reportDocumentId,download=False)
  124. print(rp_table)
  125. if rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:#
  126. df = pd.read_table(filepath_or_buffer=rp_table.payload['url'],compression={"method":'gzip'},encoding='iso-8859-1')
  127. return df
  128. elif rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  129. df = pd.read_table(filepath_or_buffer=rp_table.payload['url'], compression={"method": 'gzip'},
  130. encoding='Shift-JIS')
  131. # df.columns =
  132. return df
  133. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:
  134. df = pd.read_table(rp_table.payload.get("url"),encoding='iso-8859-1')
  135. return df
  136. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  137. df = pd.read_table(rp_table.payload.get("url"),encoding='Shift-JIS')
  138. return df
  139. elif reportId_info.payload.get("processingStatus") in [ProcessingStatus.CANCELLED,ProcessingStatus.FATAL]:
  140. print(reportId_info)
  141. print("取消或失败")
  142. return pd.DataFrame()
  143. time.sleep(15)
  144. print("please wait...")
  145. # def GET_MERCHANT_LISTINGS_ALL_DATA(self,limit=None): # Not be used
  146. # start = time.time()
  147. # para = {"reportType":ReportType.GET_MERCHANT_LISTINGS_ALL_DATA}
  148. # reportid = self.create_report(**para)
  149. # decom_df = self.decompression(reportid)
  150. # print("连接数据库")
  151. # conn = self.LocalHost_Auth()
  152. # print("连接成功")
  153. # cursor = conn.cursor()
  154. # timezone = "UTC" #pytz.timezone(self.timezone)
  155. # bondary_date = (datetime.now()).strftime("%Y-%m-%d") #+ timedelta(days=-28)
  156. # cursor.execute(f"""select * from amz_sp_api.productInfo where (mainImageUrl is not null and mainImageUrl not in ('', ' ')) and
  157. # (`seller-sku` not in ('',' ') and `seller-sku` is not null) and
  158. # `updateTime`>='{bondary_date}'""") #`seller-sku`,`updateTime`,`mainImageUrl`
  159. # col = [i[0] for i in cursor.description]
  160. # query_rel = cursor.fetchall()
  161. #
  162. # if len(query_rel)!=0:
  163. # print(query_rel[0])
  164. # df = pd.DataFrame(query_rel,columns=col)
  165. # listingid = df['listing-id'].to_numpy().tolist()
  166. # decom_df = decom_df.query("`listing-id` not in @listingid")
  167. # print("数据条数: ",len(decom_df))
  168. # # print(f"delete * from amz_sp_api.productInfo where `listing-id` not in {tuple(listingid)}")
  169. #
  170. # # conn.commit()
  171. #
  172. # if len(decom_df)==0:
  173. # return "Done"
  174. #
  175. # if limit != None:
  176. # decom_df = decom_df.iloc[:limit,:]
  177. # print("getting mainImageInfo...")
  178. # rowcount = 0
  179. # while rowcount < len(decom_df):
  180. # df_insert = decom_df.copy()
  181. # df_insert = df_insert.iloc[rowcount:rowcount + 200, :]
  182. #
  183. # df_insert = self.data_deal(df_insert)
  184. # list_df = df_insert.to_numpy().tolist()
  185. #
  186. # # print(list(conn.query("select * from amz_sp_api.orderReport")))
  187. # sql = f"""
  188. # insert into amz_sp_api.productInfo
  189. # values (%s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s,%s)
  190. # """ #ok
  191. # # print(sql)
  192. # conn = self.LocalHost_Auth()
  193. # cursor = conn.cursor()
  194. # try:
  195. # conn.begin()
  196. # cursor.executemany(sql, list_df)
  197. # conn.commit()
  198. # print("插入中...")
  199. # insert_listingid = df_insert['listing-id'].to_numpy().tolist()
  200. # cursor.execute(f"delete from amz_sp_api.productInfo where `listing-id` not in {tuple(insert_listingid)} and `updateTime`<'{bondary_date}'")
  201. # conn.commit()
  202. # rowcount += 200
  203. # except Exception as e:
  204. # conn.rollback()
  205. # print(e)
  206. # try:
  207. # conn = self.LocalHost_Auth()
  208. # cursor = conn.cursor()
  209. # conn.begin()
  210. # cursor.executemany(sql, list_df)
  211. # conn.commit()
  212. # insert_listingid = df_insert['listing-id'].to_numpy().tolist()
  213. # cursor.execute(f"delete from amz_sp_api.productInfo where `listing-id` not in {tuple(insert_listingid)} and `updateTime`<'{bondary_date}'")
  214. # conn.commit()
  215. # except Exception as e:
  216. # conn.rollback()
  217. # print(e)
  218. # break
  219. # # break
  220. # conn.close()
  221. # print("全部完成")
  222. # end =time.time()
  223. # print("duration:",end-start)
  224. # return decom_df
  225. # def data_deal(self, decom_df, seller_id): # desprecated
  226. # decom_df['mainImageUrl'] = decom_df['seller-sku'].map(lambda x: self.get_mainImage_url(x))
  227. # url_columns = [i for i in decom_df.columns if "url" in i.lower()]
  228. # if len(url_columns) > 0:
  229. # decom_df[url_columns] = decom_df[url_columns].astype("string")
  230. # asin_columns = [i for i in decom_df.columns if 'asin' in i.lower()]
  231. # if len(asin_columns) > 0:
  232. # decom_df[asin_columns] = decom_df[asin_columns].astype("string")
  233. # if 'pending-quantity' in decom_df.columns:
  234. # decom_df['pending-quantity'] = decom_df['pending-quantity'].map(
  235. # lambda x: 0 if pd.isna(x) or np.isinf(x) else x).astype("int32")
  236. # deletecolumns = [i for i in decom_df.columns if 'zshop' in i.lower()]
  237. # decom_df.drop(columns=deletecolumns, inplace=True)
  238. # if 'quantity' in decom_df.columns:
  239. # decom_df['quantity'] = decom_df['quantity'].map(lambda x: 0 if pd.isna(x) or np.isinf(x) else x).astype(
  240. # "int32")
  241. # decom_df['opendate_date'] = decom_df['open-date'].map(lambda x: self.datetime_deal(x))
  242. # if 'add-delete' in decom_df.columns:
  243. # decom_df['add-delete'] = decom_df['add-delete'].astype('string', errors='ignore')
  244. # if 'will-ship-internationally' in decom_df.columns:
  245. # decom_df['will-ship-internationally'] = decom_df['will-ship-internationally'].astype('string',
  246. # errors='ignore')
  247. # if 'expedited-shipping' in decom_df.columns:
  248. # decom_df['expedited-shipping'] = decom_df['expedited-shipping'].astype('string', errors='ignore')
  249. # decom_df['updateTime'] = datetime.now()
  250. # decom_df['timezone'] = "UTC"
  251. # decom_df['seller_id'] = seller_id
  252. # #
  253. # decom_df['item-description'] = decom_df['item-description'].str.slice(0, 500)
  254. # decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].fillna(0.0)
  255. # decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].fillna(0)
  256. # decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[decom_df.select_dtypes(datetime).columns].astype(
  257. # 'string')
  258. # decom_df.fillna('', inplace=True)
  259. # # print(decom_df.info())
  260. # return decom_df
  261. def fba_inventorySQL(self,conn,seller_id):
  262. cursor = conn.cursor()
  263. # 执行语句
  264. cursor.execute(f""" select asin,sku,seller_id,marketplace_id,country_code,quantity,fulfillment_channel
  265. from
  266. (select asin,sku,seller_id,marketplace_id,country_code,quantity,fulfillment_channel,
  267. ROW_NUMBER() over(partition by asin,sku,seller_id,marketplace_id,country_code order by update_datetime desc) as row_
  268. from asj_ads.seller_listings) as t
  269. where row_=1 and seller_id='{seller_id}' and marketplace_id='{self.marketplace.marketplace_id}'
  270. and fulfillment_channel='FBA'
  271. """)#,quantity
  272. query_ = cursor.fetchall()
  273. col_name = [i[0] for i in cursor.description]
  274. df_datatable = pd.DataFrame(query_, columns=col_name)
  275. df_datatable.columns = ['asin_', 'sku_', 'seller_id_', 'marketplace_id_', 'country_code_',
  276. 'afn-fulfillable-quantity']
  277. return df_datatable
  278. def get_fba_neccessary_segment(self,conn,seller_id):
  279. para = {"reportType": ReportType.GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA}
  280. reportid = self.create_report(**para)
  281. df = self.decompression(reportid)
  282. if len(df) == 0:
  283. return self.fba_inventorySQL(conn, seller_id)
  284. # pd.DataFrame()
  285. df['seller_id'] = seller_id
  286. df['marketplace_id'] = self.marketplace.marketplace_id
  287. df['country_code'] = str(self.marketplace)[-2:]
  288. df_rel = df.query("condition=='New'")
  289. df_rel = df_rel.groupby(['asin', 'sku', 'seller_id', 'marketplace_id', 'country_code']).agg(
  290. {'afn-fulfillable-quantity': sum}).reset_index()
  291. df_rel.columns = ['asin_', 'sku_', 'seller_id_', 'marketplace_id_', 'country_code_', 'afn-fulfillable-quantity']
  292. print(f"{seller_id}_{str(self.marketplace)[-2:]}_FBA_Inventory_OK")
  293. return df_rel
  294. def GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA(self,refresh_token,conn=None,seller_id=None,days=-1,**kwargs): # FBA库存信息
  295. try:
  296. return self.get_fba_neccessary_segment(conn,seller_id)
  297. except Exception as e:
  298. print(e)
  299. try:
  300. time.sleep(15)
  301. return self.get_fba_neccessary_segment(conn, seller_id)
  302. except Exception as e:
  303. print(e)
  304. df_rel = pd.DataFrame(columns=['asin_', 'sku_', 'seller_id_', 'marketplace_id_', 'country_code_','afn-fulfillable-quantity'])
  305. return df_rel
  306. def GET_FLAT_FILE_OPEN_LISTINGS_DATA(self,refresh_token,conn=None,seller_id=None,days=-1): # To datatable asj_ads.seller_listings- listing信息,包括fbm库存
  307. para = {"reportType": ReportType.GET_MERCHANT_LISTINGS_ALL_DATA}
  308. reportid = self.create_report(**para)
  309. df = self.decompression(reportid)
  310. if len(df)>0:
  311. if self.marketplace.marketplace_id =='A1VC38T7YXB528': # 该站点的数据列有所不同
  312. df.columns = ['item-name','listing-id','seller-sku','price','quantity','open-date','product-id-type','item-description',
  313. 'item-condition','overseas shipping','fast shipping','asin1','stock_number','fulfillment-channel','merchant-shipping-group','status']
  314. df['seller_id'] = seller_id
  315. df['marketplace_id'] = self.marketplace.marketplace_id
  316. df['country_code'] = str(self.marketplace)[-2:]
  317. if 'fulfilment-channel' in df.columns: # 判断是否存在’fulfilment‘字段(1个film),如果存在则添加一个’fulfillment‘字段(两个fillm)
  318. df['fulfillment-channel'] = df['fulfilment-channel'].copy()
  319. # 如果是amazon,则字段改为FBA
  320. df['fulfillment_channel'] = df['fulfillment-channel'].map(lambda x:"FBA" if not pd.isna(x) and len(x)>0 and str(x)[1:4] in "AMAZON" else x)
  321. # 如果是DEFAULT,则字段该为FBM
  322. df['fulfillment_channel'] = df['fulfillment_channel'].map(lambda x: "FBM" if not pd.isna(x) and len(x)>0 and str(x)[1:4] in "DEFAULT" else x)
  323. if 'asin1' not in df.columns: # 如果不存在asin1,则添加asin1字段
  324. df['asin1'] = ''
  325. if 'product-id' not in df.columns: # 如果不存在product-id,则添加product-id字段
  326. df['product-id'] = ''
  327. # 空值处理
  328. # df['quantity'] = df['quantity'].fillna(0).astype('int64',errors='ignore')
  329. df['quantity'] = df['quantity'].map(lambda x:0 if pd.isna(x)==True else int(x))
  330. #库存数量格式处理
  331. df['quantity'] = df['quantity'].astype('int64')
  332. # 填充NA值
  333. df[['listing-id','seller_id','asin1','seller-sku','country_code','marketplace_id','fulfillment_channel','status','product-id']] = df[['listing-id','seller_id','asin1','seller-sku','country_code','marketplace_id','fulfillment_channel','status','product-id']].fillna('').astype('string',errors='ignore')
  334. # 为NA的价格填充0
  335. df['price'] = df['price'].fillna(0.0).astype('float64',errors='ignore')
  336. df.fillna('',inplace=True)
  337. # 时间处理
  338. df['opendate'] = df['open-date'].map(lambda x: self.datetime_deal(x))
  339. df['update_datetime'] = datetime.now(pytz.UTC).date()
  340. # 保留列
  341. origin_columns = ['listing-id','seller_id',
  342. 'asin1','seller-sku','title','image_link','country_code',
  343. 'marketplace_id','quantity','fulfillment_channel',
  344. 'price','opendate','status','update_datetime','product-id','product-id-type','modifier'
  345. ]
  346. # 连接数据库
  347. conn = SpApiRequest.Data_auth()
  348. cursor = conn.cursor()
  349. # 执行语句,筛选出asin不为空并且product_id不为空的两列唯一数据。
  350. cursor.execute("""select product_id,asin from (select * from asj_ads.seller_listings where asin is not null
  351. and asin<>'' and product_id is not null and product_id <>'') t1 group by product_id,asin""")
  352. query_ = cursor.fetchall()
  353. col_name = [i[0] for i in cursor.description]
  354. df_datatable = pd.DataFrame(query_, columns=col_name)
  355. # 合并数据,左表为新下载的数据,右表为数据库查询的数据
  356. merged_df = df.merge(df_datatable[['product_id','asin']],how='left',left_on='product-id',right_on='product_id')
  357. # 功能函数,提取asin
  358. def func_(asin,asin1,product_id,cred,market_p,seller_id,sku):
  359. if 'B0' in str(product_id)[:3]:
  360. return str(product_id)
  361. if (pd.isna(asin1) or asin1=='') and (pd.isna(asin)==False and asin !=''):
  362. if 'B0' in asin[:3]:
  363. return asin
  364. elif (pd.isna(asin1)==False and asin1!=''):
  365. if 'B0' in asin1[:3]:
  366. return asin1
  367. listingClient = ListingsItems(credentials=cred, marketplace=market_p)
  368. try:
  369. r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  370. print(r1.payload)
  371. asin = r1.payload.get("summaries")[0].get("asin")
  372. return asin
  373. except Exception as e:
  374. print("获取图片url过程错误重试, 错误message: ", e)
  375. time.sleep(3)
  376. r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  377. print(r1.payload)
  378. asin = r1.payload.get("summaries")[0].get("asin")
  379. return asin
  380. # 应用处理函数,返回asin
  381. merged_df['asin1'] = merged_df.apply(lambda x:func_(x['asin'],x['asin1'],x['product-id'],self.credentials,self.marketplace,seller_id,x['seller-sku']),axis=1) #x['asin'] if pd.isna(x['asin1']) or x['asin1']=='' else x['asin1']
  382. merged_df['image_link'] = ''
  383. # 暂时将refresh_token添加在title列,后面获取asin详细数据时需要用到
  384. merged_df['title'] = refresh_token
  385. merged_df['modifier'] = ''
  386. # 填充NA值
  387. merged_df.fillna('',inplace=True)
  388. df1 = merged_df.copy()
  389. # df1.to_csv("第一次合并处理后.csv")
  390. #获取FBA库存数据
  391. df_fbaInventory = self.GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA(refresh_token, conn, seller_id, days)
  392. # 合并fba库存数据
  393. if len(df_fbaInventory)>0:
  394. df1 = df1.merge(df_fbaInventory,how='left',left_on=['asin1','seller-sku','seller_id','marketplace_id','country_code'],right_on=['asin_','sku_','seller_id_','marketplace_id_','country_code_'])
  395. df1['quantity'] = df1.apply(lambda x:x['afn-fulfillable-quantity'] if x['fulfillment_channel']=='FBA' or pd.isna(['afn-fulfillable-quantity'])==False else x['quantity'],axis=1)
  396. df1['quantity'] = df1['quantity'].map(lambda x:0 if pd.isna(x) else int(x))
  397. df1['quantity'] = df1['quantity'].fillna(0)
  398. # df1.to_csv("第二次合并处理后的数据.csv")
  399. # 判断更新数据
  400. update_df = self.update_data(df1,seller_id,str(self.marketplace)[-2:],conn)
  401. if len(update_df)==0:
  402. return '无更新数据插入'
  403. # update_df['country_code'] = update_df['country_code'].map({"GB":"UK"})
  404. conn = SpApiRequest.Data_auth()
  405. cursor = conn.cursor()
  406. # 插入更新的数据
  407. try:
  408. insertsql = """insert into
  409. asj_ads.seller_listings(listing_id,seller_id,asin,sku,title,image_link,country_code,marketplace_id,quantity,
  410. fulfillment_channel,price,launch_datetime,status,update_datetime,product_id,product_id_type,modifier)
  411. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  412. conn.begin()
  413. cursor.executemany(insertsql,tuple(update_df[origin_columns].to_numpy().tolist()))
  414. conn.commit()
  415. print("插入完成")
  416. delete_sql = f"""delete from asj_ads.seller_listings where update_datetime<'{(datetime.today()+timedelta(days=-3)).date().isoformat()}'"""
  417. cursor.execute(delete_sql)
  418. conn.commit()
  419. return '插入完成'
  420. except Exception as e:
  421. print("插入错误:",e)
  422. conn.rollback()
  423. return '出错回滚'
  424. return ''
  425. # def get_listing_info(self, sku,seller_id): # desprecated
  426. # listingClient = ListingsItems(credentials=self.credentials, marketplace=self.marketplace)
  427. # try:
  428. # r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  429. # # print(r1.payload)
  430. # json_content = r1.payload.get("summaries")[0]
  431. # item_name = json_content.get("itemName")
  432. # item_name ='###' if item_name==None else item_name
  433. # img = json_content.get("mainImage")
  434. # img_url = '###' if img is None else img.get("link")
  435. # return str(img_url)+"-----"+ str(item_name)
  436. # except Exception as e:
  437. # try:
  438. # print("获取图片url过程错误重试, 错误message: ",e)
  439. # time.sleep(3)
  440. # r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  441. # print(r1.payload)
  442. # json_content = r1.payload.get("summaries")[0]
  443. #
  444. # item_name = json_content.get("itemName")
  445. # item_name = '###' if item_name == None else item_name
  446. # img = json_content.get("mainImage")
  447. # img_url = '###' if img is None else img.get("link")
  448. # return str(img_url)+"-----"+ str(item_name)
  449. # except Exception as e:
  450. # print(e)
  451. # return "###-----###"
  452. def datetime_deal(self,timestring): # used in GET_FLAT_FILE_OPEN_LISTINGS_DATA, time deal -时间处理函数
  453. timezone_ = {"AEST":"Australia/Sydney","AEDT":"Australia/Sydney","PST":"America/Los_Angeles",
  454. "PDT":"America/Los_Angeles","CST":"America/Chicago","CDT":"America/Chicago",
  455. "MET":"MET","MEST":"MET","BST":"Europe/London","GMT":"GMT","CET":"CET",
  456. "CEST":"CET","JST":"Asia/Tokyo","BRT":"America/Sao_Paulo"}
  457. date_list = str.split(timestring,sep = ' ')
  458. if len(date_list)<3:
  459. try:
  460. return datetime.strptime(date_list[0],"%Y-%m-%d")
  461. except:
  462. try:
  463. return datetime.strptime(date_list[0], "%Y/%m/%d")
  464. except:
  465. try:
  466. return datetime.strptime(date_list[0], "%d/%m/%Y")
  467. except Exception as e:
  468. print(e)
  469. return datetime(1999, 12, 31, 0, 0, 0)
  470. try:
  471. time_date = datetime.strptime(date_list[0]+date_list[1],"%Y-%m-%d%H:%M:%S")
  472. timezone = pytz.timezone(timezone_[date_list[2]])
  473. time_ = timezone.localize(time_date)
  474. return time_.astimezone(pytz.UTC)
  475. except:
  476. try:
  477. time_date = datetime.strptime(date_list[0] + date_list[1], "%d/%m/%Y%H:%M:%S")
  478. timezone = pytz.timezone(timezone_[date_list[2]])
  479. time_ = timezone.localize(time_date)
  480. return time_.astimezone(pytz.UTC)
  481. except :
  482. try:
  483. time_date = datetime.strptime(date_list[0] + date_list[1], "%Y/%m/%d%H:%M:%S")
  484. timezone = pytz.timezone(timezone_[date_list[2]])
  485. time_ = timezone.localize(time_date)
  486. return time_.astimezone(pytz.UTC)
  487. except Exception as e1:
  488. print(e1)
  489. return datetime(1999,12,31,0,0,0)
  490. def update_data(self,df,seller_id,country_code,conn): # used in GET_FLAT_FILE_OPEN_LISTINGS_DATA, data compare
  491. conn = SpApiRequest.Data_auth()
  492. cursor = conn.cursor()
  493. columns = ['listing-id', 'seller_id',
  494. 'asin1', 'seller-sku', 'title', 'image_link', 'country_code',
  495. 'marketplace_id', 'quantity', 'fulfillment_channel',
  496. 'price', 'opendate', 'status', 'update_datetime', 'product-id', 'product-id-type','modifier'
  497. ]
  498. if country_code=='GB':
  499. country_code="UK"
  500. df['country_code'] = "UK"
  501. df_data = pd.DataFrame(columns=columns)
  502. delete_list = []
  503. marketplace_id = self.marketplace.marketplace_id
  504. try:
  505. cursor.execute(f"""select * from
  506. asj_ads.seller_listings where seller_id='{seller_id}' and marketplace_id='{marketplace_id}'""")
  507. col = [i[0] for i in cursor.description]
  508. query_rel = cursor.fetchall()
  509. df_rel = pd.DataFrame(query_rel, columns=col)
  510. # df_rel.to_csv("数据库数据.csv")
  511. #数据库数据
  512. df_rel['quantity'] = df_rel['quantity'].fillna(0).astype('int64')
  513. df_rel['price'] = df_rel['price'].fillna(0.0).astype('float64')
  514. df_rel['product_id_type'] = df_rel['product_id_type'].astype('int64')
  515. # 新数据
  516. df['update_datetime'] =df['update_datetime'].astype('datetime64[ns]')
  517. df['quantity'] = df['quantity'].fillna(0).astype('int64')
  518. df['price']= df['price'].fillna(0.0).astype('float64')
  519. row = 0
  520. while row < len(df):
  521. temp_df = df.iloc[row, :]
  522. temp_d = df.iloc[row:row+1, :]
  523. listing_id = temp_df['listing-id']
  524. asin = temp_df['asin1']
  525. sku = temp_df['seller-sku']
  526. quantity = temp_df['quantity']
  527. fulfillment_channel = temp_df['fulfillment_channel']
  528. price = temp_df['price']
  529. product_id = temp_df['product-id']
  530. title = temp_df['title']
  531. imageurl = temp_df['image_link']
  532. modifier = temp_df['modifier']
  533. temp = df_rel.query("""listing_id==@listing_id and asin==@asin and sku==@sku and quantity==@quantity and fulfillment_channel==@fulfillment_channel and price==@price and product_id==@product_id and country_code==@country_code and seller_id==@seller_id and title==@title and image_link==@imageurl and modifier==@modifier""")
  534. # print("需要关注数据(是否异常):",len(temp),temp.to_numpy().tolist()) if len(temp)>1 else 1
  535. if len(temp)>1:
  536. # temp = temp.head(1).to_numpy().tolist()
  537. df_data = pd.concat((df_data,temp_d),ignore_index=True) #df_data.append(temp_df, ignore_index=True)
  538. delete_list.append((seller_id, marketplace_id, sku, listing_id, product_id))
  539. # print(len(temp))
  540. elif len(temp)==0:
  541. df_data = pd.concat((df_data,temp_d),ignore_index=True)
  542. delete_list.append((seller_id,marketplace_id,sku,listing_id,product_id))
  543. row += 1
  544. print("判断不同数据条数",len(delete_list))
  545. print("预计更新数据条数",len(df_data))
  546. try:
  547. # print(tuple(delete_list))
  548. if len(delete_list)>0:
  549. query = f"""delete from asj_ads.seller_listings
  550. where (seller_id,marketplace_id,sku,listing_id,product_id) in %s""" #where (seller_id,country_code) in %s"""
  551. cursor.execute(query,(delete_list,))
  552. conn.commit()
  553. # print(delete_list)
  554. print("进行中...")
  555. except Exception as e:
  556. print(e)
  557. conn.rollback()
  558. return df_data
  559. except Exception as e:
  560. print("错误:", e)
  561. return df
  562. def GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE(self,seller_id,days=-2): # not be used,退货报告,空数据
  563. shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  564. # print(shopReportday)
  565. para = {"reportType": ReportType.GET_SELLER_FEEDBACK_DATA,
  566. "dataStartTime": shopReportday, "dataEndTime": shopReportday,
  567. }
  568. reportid = self.create_report(**para) # {"ShowSalesChannel":"true"}
  569. decom_df = self.decompression(reportid)
  570. print(decom_df)
  571. # print(decom_df.columns)
  572. def GET_SALES_AND_TRAFFIC_REPORT(self, refresh_token,seller_id,days=-2,**kwargs): # To datatable asj_ads.SalesAndTrafficByAsin,销售流量表
  573. # ,level:Literal["PARENT","CHILD","SKU"]="PARENT")
  574. level = "PARENT" if len(kwargs.get("level"))==0 else kwargs.get("level")
  575. countryCode = None if kwargs.get("countryCode")==None else kwargs.get("countryCode")
  576. # print(level)
  577. shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  578. print(shopReportday,countryCode,seller_id)
  579. try:
  580. conn = self.Data_auth()
  581. cursor = conn.cursor()
  582. except:
  583. time.sleep(5)
  584. conn = self.Data_auth()
  585. cursor = conn.cursor()
  586. if level == 'SKU':
  587. query_judge = f"""select count(*) from asj_ads.SalesAndTrafficByAsin where seller_id='{seller_id}' and data_date='{shopReportday}' and countryCode='{countryCode}' and childAsin is not Null and sku is not Null"""
  588. elif level == 'CHILD':
  589. query_judge = f"""select count(*) from asj_ads.SalesAndTrafficByAsin where seller_id='{seller_id}' and data_date='{shopReportday}' and countryCode='{countryCode}' and sku is null and childAsin is not null"""
  590. elif level == 'PARENT':
  591. query_judge = f"""select count(*) from asj_ads.SalesAndTrafficByAsin where seller_id='{seller_id}' and data_date='{shopReportday}' and countryCode='{countryCode}' and sku is null and childAsin is null"""
  592. else:
  593. return ''
  594. print(query_judge)
  595. cursor.execute(query_judge)
  596. rel = cursor.fetchall()
  597. # print()
  598. if rel[0][0]!=0:
  599. return '已存在'
  600. # print(shopReportday)
  601. para = {"reportType": ReportType.GET_SALES_AND_TRAFFIC_REPORT,
  602. "dataStartTime": shopReportday, "dataEndTime": shopReportday,
  603. "reportOptions":{"dateGranularity":"DAY","asinGranularity":level}
  604. }
  605. reportid = self.create_report(**para) # {"ShowSalesChannel":"true"}
  606. decom_df = self.decompression(reportid)
  607. # print(decom_df.columns[0])
  608. data_rel = self.sales_traffic_datadeal(decom_df.columns[0],seller_id,countryCode)
  609. try:
  610. conn = self.Data_auth()
  611. cursor = conn.cursor()
  612. except:
  613. time.sleep(5)
  614. conn = self.Data_auth()
  615. cursor = conn.cursor()
  616. # print(list(conn.query("select * from amz_sp_api.orderReport")))
  617. sql = f"""
  618. insert into asj_ads.SalesAndTrafficByAsin(data_date,data_marketpalceId,parent_asin,
  619. childAsin,sku,sBA_unitsOrdered,sBA_unitsOrderedB2B,sBA_amount,
  620. currencyCode,totalOrderItems,totalOrderItemsB2B,tBA_browserSessions,
  621. tBA_browserSessionsB2B,tBA_mobileAppSessions,tBA_mobileAppSessionsB2B,
  622. tBA_sessions,tBA_sessionsB2B,tBA_browserSessionPercentage,
  623. tBA_browserSessionPercentageB2B,tBA_mobileAppSessionPercentage,
  624. tBA_mobileAppSessionPercentageB2B,tBA_sessionPercentage,
  625. tBA_sessionPercentageB2B,tBA_browserPageViews,tBA_browserPageViewsB2B,
  626. tBA_mobileAppPageViews,tBA_mobileAppPageViewsB2B,tBA_pageViews,
  627. tBA_pageViewsB2B,tBA_browserPageViewsPercentage,tBA_browserPageViewsPercentageB2B,
  628. tBA_mobileAppPageViewsPercentage,tBA_mobileAppPageViewsPercentageB2B,
  629. tBA_pageViewsPercentage,tBA_pageViewsPercentageB2B,tBA_buyBoxPercentage,
  630. tBA_buyBoxPercentageB2B,tBA_unitSessionPercentage,tBA_unitSessionPercentageB2B,seller_id,countryCode)
  631. values (%s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s)
  632. """ # ok
  633. try:
  634. # TODO
  635. conn.begin()
  636. cursor.executemany(sql, data_rel)
  637. conn.commit()
  638. print("插入完成")
  639. conn.close()
  640. time.sleep(1)
  641. except Exception as e:
  642. conn.rollback()
  643. print(e)
  644. def sales_traffic_datadeal(self,data,seller_id,countryCode): # used in GET_SALES_AND_TRAFFIC_REPORT
  645. data = eval(data)
  646. if len(data['salesAndTrafficByAsin'])==0:
  647. return []
  648. data_list = []
  649. data_date = data["reportSpecification"]["dataEndTime"]
  650. data_marketpalceId = data["reportSpecification"]["marketplaceIds"][0]
  651. # print(data_marketpalceId)
  652. for single_item in data["salesAndTrafficByAsin"]:
  653. # print(single_item)
  654. parent_asin = single_item.get("parentAsin")
  655. childAsin = single_item.get("childAsin")
  656. sku = single_item.get("sku")
  657. salesByAsin = single_item.get("salesByAsin")
  658. # if salesByAsin is not None:
  659. sBA_unitsOrdered = salesByAsin.get("unitsOrdered") if salesByAsin is not None else ''
  660. sBA_unitsOrderedB2B = salesByAsin.get("unitsOrderedB2B") if salesByAsin is not None else ''
  661. orderedProductSales = salesByAsin.get("orderedProductSales")
  662. sBA_amount = orderedProductSales.get("amount") if orderedProductSales is not None else ''
  663. currencyCode = orderedProductSales.get("currencyCode") if orderedProductSales is not None else ''
  664. orderedProductSalesB2B = salesByAsin.get("orderedProductSalesB2B") if salesByAsin is not None else None
  665. # if orderedProductSalesB2B is not None:
  666. oPS_amount = orderedProductSalesB2B.get("amount") if orderedProductSalesB2B is not None else ''
  667. totalOrderItems = salesByAsin.get("totalOrderItems") if salesByAsin is not None else ''
  668. totalOrderItemsB2B = salesByAsin.get("totalOrderItemsB2B") if salesByAsin is not None else ''
  669. trafficByAsin = single_item.get("trafficByAsin")
  670. # if trafficByAsin is not None:
  671. tBA_browserSessions = trafficByAsin.get("browserSessions") if trafficByAsin is not None else ''
  672. tBA_browserSessionsB2B = trafficByAsin.get("browserSessionsB2B") if trafficByAsin is not None else ''
  673. tBA_mobileAppSessions = trafficByAsin.get("mobileAppSessions") if trafficByAsin is not None else ''
  674. tBA_mobileAppSessionsB2B = trafficByAsin.get("mobileAppSessionsB2B") if trafficByAsin is not None else ''
  675. tBA_sessions = trafficByAsin.get("sessions") if trafficByAsin is not None else ''
  676. tBA_sessionsB2B = trafficByAsin.get("sessionsB2B") if trafficByAsin is not None else ''
  677. tBA_browserSessionPercentage = trafficByAsin.get("browserSessionPercentage") if trafficByAsin is not None else ''
  678. tBA_browserSessionPercentageB2B = trafficByAsin.get("browserSessionPercentageB2B") if trafficByAsin is not None else ''
  679. tBA_mobileAppSessionPercentage = trafficByAsin.get("mobileAppSessionPercentage") if trafficByAsin is not None else ''
  680. tBA_mobileAppSessionPercentageB2B = trafficByAsin.get("mobileAppSessionPercentageB2B") if trafficByAsin is not None else ''
  681. tBA_sessionPercentage = trafficByAsin.get("sessionPercentage") if trafficByAsin is not None else ''
  682. tBA_sessionPercentageB2B = trafficByAsin.get("sessionPercentageB2B") if trafficByAsin is not None else ''
  683. tBA_browserPageViews = trafficByAsin.get("browserPageViews") if trafficByAsin is not None else ''
  684. tBA_browserPageViewsB2B = trafficByAsin.get("browserPageViewsB2B") if trafficByAsin is not None else ''
  685. tBA_mobileAppPageViews = trafficByAsin.get("mobileAppPageViews") if trafficByAsin is not None else ''
  686. tBA_mobileAppPageViewsB2B = trafficByAsin.get("mobileAppPageViewsB2B") if trafficByAsin is not None else ''
  687. tBA_pageViews = trafficByAsin.get("pageViews") if trafficByAsin is not None else ''
  688. tBA_pageViewsB2B = trafficByAsin.get("pageViewsB2B") if trafficByAsin is not None else ''
  689. tBA_browserPageViewsPercentage = trafficByAsin.get("browserPageViewsPercentage") if trafficByAsin is not None else ''
  690. tBA_browserPageViewsPercentageB2B = trafficByAsin.get("browserPageViewsPercentageB2B") if trafficByAsin is not None else ''
  691. tBA_mobileAppPageViewsPercentage = trafficByAsin.get("mobileAppPageViewsPercentage") if trafficByAsin is not None else ''
  692. tBA_mobileAppPageViewsPercentageB2B = trafficByAsin.get("mobileAppPageViewsPercentageB2B") if trafficByAsin is not None else ''
  693. tBA_pageViewsPercentage = trafficByAsin.get("pageViewsPercentage") if trafficByAsin is not None else ''
  694. tBA_pageViewsPercentageB2B = trafficByAsin.get("pageViewsPercentageB2B") if trafficByAsin is not None else ''
  695. tBA_buyBoxPercentage = trafficByAsin.get("buyBoxPercentage") if trafficByAsin is not None else ''
  696. tBA_buyBoxPercentageB2B = trafficByAsin.get("buyBoxPercentageB2B") if trafficByAsin is not None else ''
  697. tBA_unitSessionPercentage = trafficByAsin.get("unitSessionPercentage") if trafficByAsin is not None else ''
  698. tBA_unitSessionPercentageB2B = trafficByAsin.get("unitSessionPercentageB2B") if trafficByAsin is not None else ''
  699. data_list.append([data_date,data_marketpalceId,parent_asin,
  700. childAsin,sku,sBA_unitsOrdered,sBA_unitsOrderedB2B,sBA_amount,
  701. currencyCode,totalOrderItems,totalOrderItemsB2B,tBA_browserSessions,
  702. tBA_browserSessionsB2B,tBA_mobileAppSessions,tBA_mobileAppSessionsB2B,
  703. tBA_sessions,tBA_sessionsB2B,tBA_browserSessionPercentage,
  704. tBA_browserSessionPercentageB2B,tBA_mobileAppSessionPercentage,
  705. tBA_mobileAppSessionPercentageB2B,tBA_sessionPercentage,
  706. tBA_sessionPercentageB2B,tBA_browserPageViews,tBA_browserPageViewsB2B,
  707. tBA_mobileAppPageViews,tBA_mobileAppPageViewsB2B,tBA_pageViews,
  708. tBA_pageViewsB2B,tBA_browserPageViewsPercentage,tBA_browserPageViewsPercentageB2B,
  709. tBA_mobileAppPageViewsPercentage,tBA_mobileAppPageViewsPercentageB2B,
  710. tBA_pageViewsPercentage,tBA_pageViewsPercentageB2B,tBA_buyBoxPercentage,
  711. tBA_buyBoxPercentageB2B,tBA_unitSessionPercentage,tBA_unitSessionPercentageB2B,seller_id,countryCode
  712. ])
  713. # print(data_list)
  714. return data_list
  715. def GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL(self, refresh_token,seller_id,days=-1,**kwargs): # To datatable asj_ads.orderReport_ - 获取订单报告
  716. countryCode = None if kwargs.get("countryCode")==None else kwargs.get("countryCode")
  717. shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  718. print(shopReportday)
  719. try:
  720. conn = self.Data_auth()
  721. cursor = conn.cursor()
  722. except:
  723. time.sleep(5)
  724. conn = self.Data_auth()
  725. cursor = conn.cursor()
  726. query_judge = f"""select count(*) from asj_ads.orderReport_ where ReportDate='{shopReportday}' and country_code='{countryCode}'"""
  727. print(query_judge)
  728. cursor.execute(query_judge)
  729. rel = cursor.fetchall()
  730. # print()
  731. if rel[0][0]!=0:
  732. print("已存在")
  733. return '已存在'
  734. para = {"reportType": ReportType.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL,
  735. "dataStartTime": shopReportday, "dataEndTime": shopReportday,
  736. "reportOptions": {"ShowSalesChannel": "true"}}
  737. reportid = self.create_report(**para) # {"ShowSalesChannel":"true"}
  738. decom_df = self.decompression(reportid)
  739. decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].fillna(0.0)
  740. decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].fillna(0)
  741. decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[decom_df.select_dtypes(datetime).columns].astype(
  742. 'string')
  743. if "purchase-order-number" in decom_df.columns:
  744. decom_df['purchase-order-number'] = decom_df['purchase-order-number'].astype("string")
  745. decom_df.fillna('', inplace=True)
  746. # decom_df.to_csv('order.csv')
  747. decom_df["ReportDate"] = parse(shopReportday)
  748. # decom_df['timezone'] = decom_df["purchase-date"].map(lambda x: parse(x).tzname()).fillna(method='bfill')
  749. decom_df['timezone'] = "UTC"
  750. print("==========================================================")
  751. decom_df[["purchase-date", "last-updated-date"]] = decom_df[["purchase-date", "last-updated-date"]].applymap(
  752. lambda x: self.timeDeal(x) if pd.isna(x) == False or x != None else x)
  753. if 'is-business-order' not in decom_df.columns:
  754. decom_df['is-business-order'] = None
  755. if 'purchase-order-number' not in decom_df.columns:
  756. decom_df['purchase-order-number'] = '-'
  757. if 'price-designation' not in decom_df.columns:
  758. decom_df['price-designation'] = '-'
  759. decom_df['seller_id'] = seller_id
  760. country_code = str(self.marketplace)[-2:]
  761. if country_code == 'GB':
  762. country_code = "UK"
  763. # decom_df['country_code'] = "UK"
  764. decom_df['country_code'] = country_code
  765. decom_df['insert_time'] = datetime.now()
  766. # print(decom_df[])
  767. reserve_columns = ["amazon-order-id", "merchant-order-id", "purchase-date", "last-updated-date", "order-status",
  768. "fulfillment-channel", "sales-channel", "order-channel", "ship-service-level",
  769. "product-name",
  770. "sku", "asin", "item-status", "quantity", "currency", "item-price", "item-tax",
  771. "shipping-price",
  772. "shipping-tax", "gift-wrap-price", "gift-wrap-tax", "item-promotion-discount",
  773. "ship-promotion-discount", "ship-city", "ship-state", "ship-postal-code", "ship-country",
  774. "promotion-ids", "is-business-order", "purchase-order-number", "price-designation",
  775. "ReportDate",
  776. "timezone", "seller_id", "country_code",'insert_time'
  777. ]
  778. list_df = decom_df[reserve_columns].to_numpy().tolist()
  779. try:
  780. conn = self.Data_auth()
  781. cursor = conn.cursor()
  782. except:
  783. time.sleep(5)
  784. conn = self.Data_auth()
  785. cursor = conn.cursor()
  786. # print(list(conn.query("select * from amz_sp_api.orderReport")))
  787. sql = f"""
  788. insert into asj_ads.orderReport_(`amazon_order_id`, `merchant_order_id`, `purchase_date`, `last_updated_date`, `order_status`,
  789. `fulfillment_channel`, `sales_channel`, `order_channel`, `ship_service_level`,
  790. `product_name`,
  791. `sku`, `asin`, `item_status`, `quantity`, `currency`, `item_price`, `item_tax`,
  792. `shipping_price`,
  793. `shipping_tax`, `gift_wrap_price`, `gift_wrap_tax`, `item_promotion_discount`,
  794. `ship_promotion_discount`, `ship_city`, `ship_state`, `ship_postal_code`, `ship_country`,
  795. `promotion_ids`, `is_business_order`, `purchase_order_number`, `price_designation`,
  796. `ReportDate`,
  797. `timezone`, `seller_id`, `country_code`,`insert_time`)
  798. values (%s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s, %s,%s,%s,%s,%s,%s,%s,%s)
  799. """ # ok
  800. try:
  801. conn.begin()
  802. cursor.executemany(sql, list_df)
  803. conn.commit()
  804. print("插入完成")
  805. conn.close()
  806. time.sleep(1)
  807. except Exception as e:
  808. conn.rollback()
  809. print(e)
  810. def timeDeal(self, orgTime): # time-deal
  811. orgTime = parse(orgTime)
  812. timezone = pytz.timezone("UTC")
  813. shopTime = orgTime.astimezone(timezone)
  814. shopTime_datetime = datetime(shopTime.year, shopTime.month, shopTime.day, shopTime.hour, shopTime.minute,
  815. shopTime.second)
  816. return shopTime_datetime
  817. @classmethod
  818. def listing_infoTable(cls): # To datatable asj_ads.Goods - Goods表,包括排名,图片,父子关系
  819. conn = SpApiRequest.Data_auth()
  820. cursor = conn.cursor()
  821. #
  822. cursor.execute(f"""select seller_id,country_code,asin,title from asj_ads.seller_listings where title is not null and title <>'' and (seller_id,country_code,asin) not in (select seller_id,countryCode,asin from asj_ads.Goods where update_time>='{datetime.today().date()}') group by seller_id,title,country_code,asin order by country_code desc""")
  823. query_ = cursor.fetchall()
  824. # print(query_)
  825. col_name = [i[0] for i in cursor.description]
  826. df_datatable = pd.DataFrame(query_, columns=col_name)
  827. count=0
  828. distance = 50
  829. print(len(df_datatable))
  830. while count<len(df_datatable):
  831. print(f"进度:{round(count / len(df_datatable) * 100, 2)}%")
  832. df = df_datatable.iloc[count:count+distance,:]
  833. count = count+distance
  834. df['detail_info'] = df.apply(lambda x: cls.get_listing_info01(x['title'],x['country_code'],x['asin'],x['seller_id']),axis=1)
  835. detail_info_k = df['detail_info'].map(lambda x: list(x.keys())).to_numpy().tolist()
  836. detail_info = df['detail_info'].to_numpy().tolist() #df['detail_info'].map(lambda x: list(x.values())).to_numpy().tolist()
  837. conn = SpApiRequest.Data_auth()
  838. print(count)
  839. SpApiRequest.Goods_insert(conn,detail_info,detail_info_k)
  840. if count%distance==0:
  841. cursor = conn.cursor()
  842. cursor.execute(
  843. f"""select seller_id,countryCode,asin from asj_ads.Goods where update_time>='{datetime.today().date()}'""")
  844. query_d = cursor.fetchall()
  845. # print(query_d)
  846. try:
  847. # print(tuple(delete_list))
  848. query = f"""delete from asj_ads.Goods where update_time<'{datetime.today().date()}'
  849. and (seller_id,countryCode,asin) in {query_d}
  850. """ #where (seller_id,country_code) in %s"""
  851. cursor.execute(query)
  852. conn.commit()
  853. # print(delete_list)
  854. # print("进行中...")
  855. except Exception as e:
  856. print(e)
  857. conn.rollback()
  858. print("Success")
  859. conn.close()
  860. @staticmethod
  861. def get_listing_info01(refresh_token, countryCode, asin, seller_id): # used in listing_infoTable
  862. # print(refresh_token)
  863. aws_credentials = {
  864. 'refresh_token': refresh_token,
  865. 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  866. 'lwa_client_secret': 'amzn1.oa2-cs.v1.3af0f5649f5b8e151cd5bd25c10f2bf3113172485cd6ffc52ccc6a5e8512b490',
  867. 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  868. 'aws_secret_key': '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',
  869. 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  870. }
  871. mak = {'AE': Marketplaces.AE, 'BE': Marketplaces.BE, 'DE': Marketplaces.DE,
  872. 'PL': Marketplaces.PL, 'EG': Marketplaces.EG, 'ES': Marketplaces.ES,
  873. 'FR': Marketplaces.FR, 'GB': Marketplaces.GB, 'IN': Marketplaces.IN,
  874. 'IT': Marketplaces.IT, 'NL': Marketplaces.NL, 'SA': Marketplaces.SA,
  875. 'SE': Marketplaces.SE, 'TR': Marketplaces.TR, 'UK': Marketplaces.UK,
  876. 'AU': Marketplaces.AU, 'JP': Marketplaces.JP, 'SG': Marketplaces.SG,
  877. 'US': Marketplaces.US,
  878. 'BR': Marketplaces.BR, 'CA': Marketplaces.CA, 'MX': Marketplaces.MX
  879. }
  880. cate_item = CatalogItems(credentials=aws_credentials, marketplace=mak[countryCode],version='2022-04-01')
  881. try:
  882. variations_info = SpApiRequest.variations_judge(cate_item, asin)
  883. except:
  884. time.sleep(2.5)
  885. variations_info = SpApiRequest.variations_judge(cate_item, asin)
  886. try:
  887. cate_item = CatalogItems(credentials=aws_credentials, marketplace=mak[countryCode], version='2020-12-01')
  888. detail_info = SpApiRequest.get_detail_cat(cate_item, asin, mak, countryCode)
  889. except:
  890. time.sleep(2.5)
  891. cate_item = CatalogItems(credentials=aws_credentials, marketplace=mak[countryCode], version='2020-12-01')
  892. detail_info = SpApiRequest.get_detail_cat(cate_item, asin, mak, countryCode)
  893. detail_info.update(variations_info)
  894. detail_info['asin'] = asin
  895. detail_info['countryCode'] = countryCode
  896. detail_info['marketplace_id'] = mak[countryCode].marketplace_id
  897. detail_info['seller_id'] = seller_id
  898. detail_info['update_time'] = datetime.now()
  899. return detail_info
  900. @staticmethod
  901. def variations_judge(cate_item, asin): # used in listing_infoTable, 判断是否有父子关系
  902. def temp_func(cate_item, asin):
  903. variations = cate_item.get_catalog_item(asin=asin, **{"includedData": ['relationships']}) # 'variations',
  904. var_info = variations.payload
  905. # print(variations)
  906. IsParent = 'Y'
  907. parent_asin = ''
  908. try:
  909. relationships = var_info.get("relationships")[0]['relationships']
  910. except:
  911. relationships = []
  912. if len(relationships) > 0:
  913. variationType = relationships[0]['type']
  914. if relationships[0].get('parentAsins') is not None:
  915. parent_asin = relationships[0]['parentAsins'][0]
  916. IsParent = 'N'
  917. elif relationships[0].get('childAsins') is not None:
  918. IsParent = 'Y'
  919. parent_asin = asin
  920. else:
  921. parent_asin = 'Erro_01'
  922. else:
  923. IsParent = 'SG'
  924. parent_asin = asin
  925. print(IsParent, '父asin:', parent_asin, '子asin', asin)
  926. return {"IsParent": IsParent, "parent_asin": parent_asin}
  927. try:
  928. return temp_func(cate_item, asin)
  929. except:
  930. try:
  931. time.sleep(12)
  932. return temp_func(cate_item, asin)
  933. except Exception as e:
  934. print("判断是否为父子asin时出错:", e)
  935. return {"IsParent": 'Erro', "parent_asin": 'Erro'}
  936. @staticmethod
  937. def Goods_insert(conn,detail_info,detail_info_k): # To datatable asj.Goods
  938. # print(detail_info)
  939. df = pd.DataFrame(detail_info)
  940. # print(df.columns)
  941. try:
  942. cursor = conn.cursor()
  943. except:
  944. time.sleep(2.5)
  945. conn = SpApiRequest.Data_auth()
  946. cursor = conn.cursor()
  947. query_sql = "select * from asj_ads.Goods"
  948. cursor.execute(query_sql)
  949. col = [i[0] for i in cursor.description]
  950. query_rel = cursor.fetchall()
  951. df_query = pd.DataFrame(query_rel, columns=col)
  952. merge_df = df.merge(df_query,how='left',on=['asin', 'countryCode', 'marketplace_id', 'seller_id'],suffixes=['','_right'])
  953. merge_df['IsParent'] = merge_df.apply(lambda x:x['IsParent_right'] if x['IsParent']=='Erro' else x['IsParent'],axis=1)
  954. merge_df['parent_asin'] = merge_df.apply(lambda x: x['parent_asin_right'] if x['parent_asin'] == 'Erro' else x['parent_asin'], axis=1)
  955. detail_info_value = merge_df[['main_image', 'productTypes', 'BigCat_rank', 'BigCat_title', 'SmallCat_rank',
  956. 'SmallCat_title', 'brandName', 'browseNode', 'itemName', 'IsParent', 'parent_asin',
  957. 'asin', 'countryCode', 'marketplace_id', 'seller_id', 'update_time']].to_numpy().tolist()
  958. try:
  959. insertsql = """insert into
  960. asj_ads.Goods(main_image, productTypes, BigCat_rank, BigCat_title, SmallCat_rank, SmallCat_title, brandName, browseNode, itemName, IsParent, parent_asin, asin, countryCode, marketplace_id, seller_id, update_time)
  961. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  962. conn.begin()
  963. cursor.executemany(insertsql, tuple(detail_info_value))
  964. conn.commit()
  965. print("插入完成Goods")
  966. except Exception as e:
  967. print("插入错误Goods:", e)
  968. conn.rollback()
  969. sales_rankData = []
  970. for i in detail_info_value:
  971. tmp_list = []
  972. for j in [2,3,4,5,6,8,11,12,13,14]:
  973. tmp_list.extend([i[j]])
  974. tmp_list.extend([datetime.now(),datetime.utcnow()])
  975. sales_rankData.append(tmp_list)
  976. # print(sales_rankData,len(sales_rankData))
  977. try:
  978. insertsql = """insert into
  979. asj_ads.ProductRank(BigCat_rank, BigCat_title, SmallCat_rank, SmallCat_title, brandName, itemName, asin, countryCode, marketplace_id, seller_id, update_time,time_UTC)
  980. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  981. conn.begin()
  982. cursor.executemany(insertsql, tuple(sales_rankData))
  983. conn.commit()
  984. print("插入完成rank")
  985. # return '插入完成'
  986. except Exception as e:
  987. print("插入错误rank:", e)
  988. conn.rollback()
  989. @staticmethod
  990. def get_detail_cat(cate_item, asin, mak, countryCode): # used in listing_infoTable, category sp-api - 获取listing的信息数据
  991. try:
  992. detail_info = cate_item.get_catalog_item(asin=asin, **{
  993. "includedData": ["images,productTypes,salesRanks,summaries"],
  994. "marketplaceIds": [str(mak[countryCode].marketplace_id)]})
  995. payload = detail_info.payload
  996. # print(payload)
  997. try:
  998. main_image = payload['images'][0]['images'][0]['link'] if len(payload['images']) > 0 else "#"
  999. except:
  1000. main_image = '#-'
  1001. try:
  1002. productTypes = payload['productTypes'][0]['productType'] if len(payload['productTypes'][0]) > 0 else "#"
  1003. except:
  1004. productTypes = '#-'
  1005. try:
  1006. # print(payload['ranks'][0])
  1007. if len(payload['ranks'][0]) > 0:
  1008. BigCat_rank = payload['ranks'][0]['ranks'][0]['rank']
  1009. BigCat_title = payload['ranks'][0]['ranks'][0]['title']
  1010. SmallCat_rank = payload['ranks'][0]['ranks'][1]['rank']
  1011. SmallCat_title = payload['ranks'][0]['ranks'][1]['title']
  1012. else:
  1013. BigCat_rank, BigCat_title, SmallCat_rank, SmallCat_title = 0, '#', 0, '#'
  1014. except:
  1015. BigCat_rank, BigCat_title, SmallCat_rank, SmallCat_title = 0, '#-', 0, '#-'
  1016. try:
  1017. if len(payload['summaries'][0]) > 0:
  1018. brandName = payload['summaries'][0]['brandName']
  1019. browseNode = payload['summaries'][0]['browseNode']
  1020. itemName = payload['summaries'][0]['itemName']
  1021. else:
  1022. brandName, browseNode, itemName = '#', '#', '#'
  1023. except:
  1024. brandName, browseNode, itemName = '#-', '#-', '#-'
  1025. return {'main_image': main_image, 'productTypes': productTypes, 'BigCat_rank': BigCat_rank,
  1026. 'BigCat_title': BigCat_title, 'SmallCat_rank': SmallCat_rank, 'SmallCat_title': SmallCat_title,
  1027. 'brandName': brandName, 'browseNode': browseNode, 'itemName': itemName}
  1028. except:
  1029. return {'main_image': '', 'productTypes': '', 'BigCat_rank': 0,
  1030. 'BigCat_title': '', 'SmallCat_rank': 0, 'SmallCat_title': '',
  1031. 'brandName': '', 'browseNode': '', 'itemName': ''}
  1032. @staticmethod
  1033. def data_judge_secondTry(refresh_token,sp_api,data_type,seller_id,auth_conn,days=-1,**kwargs): # Main-retry, 重试函数,重试次数2次
  1034. a_kw = kwargs
  1035. try:
  1036. SpApiRequest.data_judge(refresh_token,sp_api, data_type, seller_id, auth_conn,days=days,**a_kw)
  1037. except Exception as e:
  1038. try:
  1039. if e.args[0][0]['code']=='InvalidInput':
  1040. return ''
  1041. print('first time to try...')
  1042. time.sleep(15)
  1043. SpApiRequest.data_judge(refresh_token,sp_api, data_type, seller_id, auth_conn,days=days,**a_kw)
  1044. except Exception as e:
  1045. print(e)
  1046. print('twice time to try...')
  1047. time.sleep(20)
  1048. SpApiRequest.data_judge(refresh_token, sp_api, data_type, seller_id, auth_conn, days=days, **a_kw)
  1049. @staticmethod
  1050. def data_judge(refresh_token,sp_api,data_type,seller_id,auth_conn,days=-1,**kwargs): # select Report type - 报告获取类型判断
  1051. a_kw = kwargs
  1052. if data_type == "GET_FLAT_FILE_OPEN_LISTINGS_DATA":
  1053. return sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(refresh_token,auth_conn,seller_id,days)
  1054. elif data_type =="GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL":
  1055. # for day_ in range(31,1):
  1056. # sp_api.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL(seller_id,days=day_*-1)
  1057. return sp_api.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL(refresh_token,seller_id,days,**a_kw)
  1058. elif data_type =="GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE":
  1059. return sp_api.GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE(refresh_token,seller_id,days)
  1060. elif data_type =="GET_SALES_AND_TRAFFIC_REPORT":
  1061. return sp_api.GET_SALES_AND_TRAFFIC_REPORT(refresh_token,seller_id,days,**a_kw)
  1062. elif data_type == "GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA":
  1063. return sp_api.GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA(refresh_token,auth_conn,seller_id,days,**a_kw)
  1064. else:
  1065. return ""
  1066. @classmethod
  1067. def get_allShops(cls,data_type=Literal["GET_FLAT_FILE_OPEN_LISTINGS_DATA","GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL"],days=-1,**kwargs): # Main-AllCountries-AuthAndPost, 所有店铺数据报告获取的主要函数
  1068. df = cls.auth_info()
  1069. zosi = df.query("account_name=='AM-ZOSI-US'")['refresh_token'].to_numpy().tolist()
  1070. # print(zosi)
  1071. refreshtoken_list = df.query("account_name!='AM-ZOSI-US'")['refresh_token'].to_numpy().tolist()
  1072. zosi.extend(refreshtoken_list)
  1073. refreshtoken_list = zosi.copy()
  1074. print(len(refreshtoken_list))
  1075. # refreshtoken_list = refreshtoken_list+refreshtoken_li
  1076. a_kw = kwargs
  1077. for refresh_token in refreshtoken_list:
  1078. aws_credentials = {
  1079. 'refresh_token': refresh_token,
  1080. 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  1081. 'lwa_client_secret': 'amzn1.oa2-cs.v1.3af0f5649f5b8e151cd5bd25c10f2bf3113172485cd6ffc52ccc6a5e8512b490',
  1082. 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  1083. 'aws_secret_key': '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',
  1084. 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  1085. }
  1086. single_info = df.query("refresh_token==@refresh_token")
  1087. region_circle = single_info['region'].values[0]
  1088. seller_id = single_info['selling_partner_id'].values[0]
  1089. account_name = single_info['account_name'].values[0]
  1090. if region_circle == 'NA':
  1091. pass
  1092. for marketplace in [Marketplaces.US, Marketplaces.BR, Marketplaces.CA,Marketplaces.MX]:
  1093. sp_api = SpApiRequest(aws_credentials, marketplace)
  1094. a_kw['countryCode'] = str(marketplace)[-2:]
  1095. # print(a_kw)
  1096. try:
  1097. print("refresh_token:",refresh_token,'data_type:',data_type,'seller_id:',seller_id,'marketplace:',marketplace.marketplace_id,'country_code:',a_kw['countryCode'],sep='\n')
  1098. auth_conn = SpApiRequest.Token_auth()
  1099. # print(a_kw)
  1100. cls.data_judge_secondTry(refresh_token,sp_api, data_type, seller_id, auth_conn,days,**a_kw)
  1101. ## sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  1102. except Exception as e:
  1103. print(e)
  1104. time.sleep(3.5)
  1105. elif region_circle == 'EU':
  1106. pass
  1107. for marketplace in [Marketplaces.DE,Marketplaces.AE, Marketplaces.BE, Marketplaces.PL,
  1108. Marketplaces.EG,Marketplaces.ES, Marketplaces.GB, Marketplaces.IN, Marketplaces.IT,
  1109. Marketplaces.NL, Marketplaces.SA, Marketplaces.SE, Marketplaces.TR,Marketplaces.UK,Marketplaces.FR,
  1110. ]:
  1111. sp_api = SpApiRequest(aws_credentials, marketplace)
  1112. a_kw['countryCode'] = str(marketplace)[-2:]
  1113. try:
  1114. auth_conn = SpApiRequest.Token_auth()
  1115. cls.data_judge_secondTry(refresh_token,sp_api, data_type, seller_id, auth_conn,days,**a_kw)
  1116. ## sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  1117. except Exception as e:
  1118. print(e)
  1119. time.sleep(3.5)
  1120. else:
  1121. # if region_circle not in ['NA','EU']:
  1122. auth_conn = SpApiRequest.Token_auth()
  1123. print(region_circle)
  1124. marketplace = eval(f'Marketplaces.{region_circle}')
  1125. sp_api = SpApiRequest(aws_credentials, marketplace)
  1126. a_kw['countryCode'] = str(marketplace)[-2:]
  1127. cls.data_judge_secondTry(refresh_token,sp_api, data_type, seller_id, auth_conn,days,**a_kw)
  1128. ## sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  1129. if __name__ == '__main__':
  1130. # for days in range(35,45):
  1131. # SpApiRequest.get_allShops("GET_SALES_AND_TRAFFIC_REPORT",days=-days,**{"level":"SKU"})
  1132. # SpApiRequest.listing_infoTable()
  1133. # rel = SpApiRequest.get_catelog(account_name='AM-ZOSI-US',country=Marketplaces.US,asin='B0B8CPHSL4')
  1134. # print(rel)
  1135. # SpApiRequest.get_allShops("GET_FLAT_FILE_OPEN_LISTINGS_DATA")
  1136. # pass
  1137. SpApiRequest.listing_infoTable()