sp_api_client.py 91 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685
  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,Products
  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. import requests
  22. from urllib import request
  23. import json
  24. from clickhouse_connect import get_client
  25. try:
  26. from ..settings import MYSQL_AUTH_CONF, MYSQL_DATA_CONF
  27. except:
  28. from sync_amz_data.sync_amz_data.settings import MYSQL_AUTH_CONF, MYSQL_DATA_CONF
  29. class SpApiRequest:
  30. def __init__(self, credentials,marketplace):
  31. self.credentials = credentials
  32. self.marketplace = marketplace
  33. @classmethod
  34. @retry(tries=3, delay=5, backoff=2, )
  35. def Token_auth(cls): # AUTH - mysql_connect_auth
  36. conn = pymysql.connect(**MYSQL_AUTH_CONF)
  37. return conn
  38. @classmethod
  39. @retry(tries=3, delay=5, backoff=2, )
  40. def Data_auth(cls): # DATA - mysql_connect_auth_lst
  41. conn = pymysql.connect(**MYSQL_DATA_CONF)
  42. return conn
  43. @classmethod
  44. @retry(tries=3, delay=5, backoff=2, )
  45. def LocalHost_Auth(cls): # local database-
  46. conn = pymysql.connect(user="huangyifan",
  47. password="123456",
  48. host="127.0.0.1",
  49. database="amz_sp_api",
  50. port=3306)
  51. return conn
  52. @staticmethod
  53. @retry(tries=3, delay=5, backoff=2, )
  54. def auth_info(): # get Auth-data from all of shops - 此连接获取refreshtoken供账户授权使用
  55. auth_conn = SpApiRequest.Token_auth()
  56. cursor = auth_conn.cursor()
  57. cursor.execute("select * from amazon_sp_report.amazon_sp_auth_info;")
  58. columns_name = [i[0] for i in cursor.description]
  59. rel = cursor.fetchall()
  60. df = pd.DataFrame(rel, columns=columns_name)
  61. return df
  62. @classmethod
  63. @retry(tries=3, delay=5, backoff=2, )
  64. def get_refreshtoken(cls): # accroding to differnt shop get diffrent refreshtoken - 获取授权后拿到refreshtoken
  65. df = cls.auth_info()
  66. refreshtoken_list = (df['refresh_token'].to_numpy().tolist())
  67. return refreshtoken_list
  68. @classmethod
  69. def get_catelog(cls,account_name,country=Marketplaces.US,asin=None): # active - 可以使用但未进行使用
  70. if country in [Marketplaces.US, Marketplaces.BR, Marketplaces.CA,Marketplaces.MX]:
  71. region = 'NA'
  72. elif country in [Marketplaces.DE,Marketplaces.AE, Marketplaces.BE, Marketplaces.PL,
  73. Marketplaces.EG,Marketplaces.ES, Marketplaces.GB, Marketplaces.IN, Marketplaces.IT,
  74. Marketplaces.NL, Marketplaces.SA, Marketplaces.SE, Marketplaces.TR,Marketplaces.UK,Marketplaces.FR,
  75. ]:
  76. region = 'EU'
  77. else:
  78. region = str(country)[-2:]
  79. df = cls.auth_info()
  80. try:
  81. refresh_token = df.query("account_name==@account_name and region==@region")['refresh_token'].values[0]
  82. except:
  83. print("请输入正确的account name与Marketplace")
  84. return '获取失败'
  85. cred = {
  86. 'refresh_token': refresh_token,
  87. 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  88. 'lwa_client_secret': 'amzn1.oa2-cs.v1.3af0f5649f5b8e151cd5bd25c10f2bf3113172485cd6ffc52ccc6a5e8512b490',
  89. 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  90. 'aws_secret_key': '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',
  91. 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  92. }
  93. # cate_item = CatalogItems(credentials=cred, marketplace=country)
  94. # images_info = cate_item.get_catalog_item(asin=asin,**{"includedData":['images']})
  95. # print(images_info)
  96. # images = images_info.images[0].get('images')[0]['link']
  97. # title_info = cate_item.get_catalog_item(asin=asin)
  98. # print(title_info)
  99. # title = title_info.payload['summaries'][0]['itemName']
  100. cate_item = CatalogItems(credentials=cred, marketplace=country,version='2022-04-01')
  101. test_bundle = cate_item.get_catalog_item(asin=asin,**{"includedData":['salesRanks']})
  102. print(test_bundle)
  103. # return {'images':images,'title':title}
  104. @retry(tries=3, delay=5, backoff=2,)
  105. def create_report(self,**kwargs): # Main-CreateReport-Function - 创建报告请求
  106. reportType = kwargs['reportType']
  107. reportOptions =kwargs.get("reportOptions")
  108. dataStartTime = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") if kwargs.get("dataStartTime") is None else kwargs.get("dataStartTime")+"T00:00:00"
  109. dataEndTime = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") if kwargs.get("dataEndTime") is None else kwargs.get("dataEndTime")+"T23:59:59"
  110. report = Reports(credentials=self.credentials, marketplace=self.marketplace)
  111. rel = report.create_report(
  112. reportType=reportType,marketplaceIds=[kwargs['marketpalceids'] if kwargs.get('marketpalceids') is not None else self.marketplace.marketplace_id],
  113. reportOptions=reportOptions,dataStartTime=dataStartTime,dataEndTime=dataEndTime
  114. )
  115. reportId = rel.payload.get("reportId")
  116. # print(reportId)
  117. return reportId
  118. # @retry(tries=2, delay=3, backoff=2,)
  119. def decompression(self,reportId): # After-CreateReportFunc-simpleDeal - 根据获取到的报告id进行解压获取
  120. report = Reports(credentials=self.credentials, marketplace=self.marketplace)
  121. while True:
  122. reportId_info = report.get_report(reportId=reportId)
  123. # print(reportId_info.payload)
  124. print("please wait...")
  125. if reportId_info.payload.get("processingStatus")==ProcessingStatus.DONE:
  126. reportDocumentId = reportId_info.payload.get("reportDocumentId")
  127. rp_table = report.get_report_document(reportDocumentId=reportDocumentId,download=False)
  128. print(rp_table,rp_table.payload.get("url"))
  129. if rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:#
  130. try:
  131. df = pd.read_table(filepath_or_buffer=rp_table.payload['url'],compression={"method":'gzip'},encoding='iso-8859-1')
  132. except:
  133. df = pd.read_csv(filepath_or_buffer=rp_table.payload['url'], compression={"method": 'gzip'},
  134. encoding='iso-8859-1')
  135. return df
  136. elif rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  137. df = pd.read_table(filepath_or_buffer=rp_table.payload['url'], compression={"method": 'gzip'},
  138. encoding='Shift-JIS')
  139. # df.columns =
  140. return df
  141. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:
  142. df = pd.read_table(rp_table.payload.get("url"),encoding='iso-8859-1')
  143. print(df.columns)
  144. return df
  145. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  146. try:
  147. df = pd.read_table(rp_table.payload.get("url"),encoding='Shift-JIS')
  148. print(df.columns)
  149. return df
  150. except:
  151. print("==========!!!!!!!!")
  152. try:
  153. df = pd.read_table(rp_table.payload.get("url"),encoding='iso-8859-1')
  154. print(df.columns)
  155. return df
  156. except:
  157. print("!!!!!!!!!!!!!!!!!==========")
  158. try:
  159. df = pd.read_table(rp_table.payload.get("url"),encoding='utf-8')
  160. return df
  161. except:
  162. print("失败")
  163. return pd.DataFrame()
  164. elif reportId_info.payload.get("processingStatus") in [ProcessingStatus.CANCELLED,ProcessingStatus.FATAL]:
  165. try:
  166. print(reportId_info)
  167. reportDocumentId = reportId_info.payload.get("reportDocumentId")
  168. rp_table = report.get_report_document(reportDocumentId=reportDocumentId, download=True)
  169. print("取消或失败",rp_table)
  170. return pd.DataFrame()
  171. except Exception as e:
  172. print(e)
  173. return pd.DataFrame()
  174. time.sleep(15)
  175. print("please wait...")
  176. def decompression2(self,reportId): # After-CreateReportFunc-simpleDeal - 根据获取到的报告id进行解压获取
  177. report = Reports(credentials=self.credentials, marketplace=self.marketplace)
  178. while True:
  179. reportId_info = report.get_report(reportId=reportId)
  180. # print(reportId_info.payload)
  181. print("please wait...")
  182. if reportId_info.payload.get("processingStatus")==ProcessingStatus.DONE:
  183. reportDocumentId = reportId_info.payload.get("reportDocumentId")
  184. rp_table = report.get_report_document(reportDocumentId=reportDocumentId,download=False)
  185. print(rp_table)
  186. if rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:#
  187. # df = pd.read_json(path_or_buf=rp_table.payload['url'],compression={"method":'gzip'},encoding='iso-8859-1')
  188. response = request.urlopen(rp_table.payload['url'])
  189. response.encoding='iso-8859-1'
  190. df = json.loads(response.read().decode())
  191. # pd.json_normalize()
  192. return df
  193. elif rp_table.payload.get('compressionAlgorithm') is not None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  194. df = pd.read_json(path_or_buf=rp_table.payload['url'], compression={"method": 'gzip'},
  195. encoding='Shift-JIS')
  196. # df.columns =
  197. return df
  198. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id not in ['A1VC38T7YXB528']:
  199. df = pd.read_json(path_or_buf=rp_table.payload.get("url"),encoding='iso-8859-1')
  200. return df
  201. elif rp_table.payload.get('compressionAlgorithm') is None and self.marketplace.marketplace_id in ['A1VC38T7YXB528']:
  202. df = pd.read_json(path_or_buf=rp_table.payload.get("url"),encoding='Shift-JIS')
  203. return df
  204. elif reportId_info.payload.get("processingStatus") in [ProcessingStatus.CANCELLED,ProcessingStatus.FATAL]:
  205. print(reportId_info)
  206. reportDocumentId = reportId_info.payload.get("reportDocumentId")
  207. rp_table = report.get_report_document(reportDocumentId=reportDocumentId, download=True)
  208. print("取消或失败",rp_table)
  209. return pd.DataFrame()
  210. time.sleep(15)
  211. print("please wait...")
  212. # def GET_MERCHANT_LISTINGS_ALL_DATA(self,limit=None): # Not be used
  213. # start = time.time()
  214. # para = {"reportType":ReportType.GET_MERCHANT_LISTINGS_ALL_DATA}
  215. # reportid = self.create_report(**para)
  216. # decom_df = self.decompression(reportid)
  217. # print("连接数据库")
  218. # conn = self.LocalHost_Auth()
  219. # print("连接成功")
  220. # cursor = conn.cursor()
  221. # timezone = "UTC" #pytz.timezone(self.timezone)
  222. # bondary_date = (datetime.now()).strftime("%Y-%m-%d") #+ timedelta(days=-28)
  223. # cursor.execute(f"""select * from amz_sp_api.productInfo where (mainImageUrl is not null and mainImageUrl not in ('', ' ')) and
  224. # (`seller-sku` not in ('',' ') and `seller-sku` is not null) and
  225. # `updateTime`>='{bondary_date}'""") #`seller-sku`,`updateTime`,`mainImageUrl`
  226. # col = [i[0] for i in cursor.description]
  227. # query_rel = cursor.fetchall()
  228. #
  229. # if len(query_rel)!=0:
  230. # print(query_rel[0])
  231. # df = pd.DataFrame(query_rel,columns=col)
  232. # listingid = df['listing-id'].to_numpy().tolist()
  233. # decom_df = decom_df.query("`listing-id` not in @listingid")
  234. # print("数据条数: ",len(decom_df))
  235. # # print(f"delete * from amz_sp_api.productInfo where `listing-id` not in {tuple(listingid)}")
  236. #
  237. # # conn.commit()
  238. #
  239. # if len(decom_df)==0:
  240. # return "Done"
  241. #
  242. # if limit != None:
  243. # decom_df = decom_df.iloc[:limit,:]
  244. # print("getting mainImageInfo...")
  245. # rowcount = 0
  246. # while rowcount < len(decom_df):
  247. # df_insert = decom_df.copy()
  248. # df_insert = df_insert.iloc[rowcount:rowcount + 200, :]
  249. #
  250. # df_insert = self.data_deal(df_insert)
  251. # list_df = df_insert.to_numpy().tolist()
  252. #
  253. # # print(list(conn.query("select * from amz_sp_api.orderReport")))
  254. # sql = f"""
  255. # insert into amz_sp_api.productInfo
  256. # 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)
  257. # """ #ok
  258. # # print(sql)
  259. # conn = self.LocalHost_Auth()
  260. # cursor = conn.cursor()
  261. # try:
  262. # conn.begin()
  263. # cursor.executemany(sql, list_df)
  264. # conn.commit()
  265. # print("插入中...")
  266. # insert_listingid = df_insert['listing-id'].to_numpy().tolist()
  267. # cursor.execute(f"delete from amz_sp_api.productInfo where `listing-id` not in {tuple(insert_listingid)} and `updateTime`<'{bondary_date}'")
  268. # conn.commit()
  269. # rowcount += 200
  270. # except Exception as e:
  271. # conn.rollback()
  272. # print(e)
  273. # try:
  274. # conn = self.LocalHost_Auth()
  275. # cursor = conn.cursor()
  276. # conn.begin()
  277. # cursor.executemany(sql, list_df)
  278. # conn.commit()
  279. # insert_listingid = df_insert['listing-id'].to_numpy().tolist()
  280. # cursor.execute(f"delete from amz_sp_api.productInfo where `listing-id` not in {tuple(insert_listingid)} and `updateTime`<'{bondary_date}'")
  281. # conn.commit()
  282. # except Exception as e:
  283. # conn.rollback()
  284. # print(e)
  285. # break
  286. # # break
  287. # conn.close()
  288. # print("全部完成")
  289. # end =time.time()
  290. # print("duration:",end-start)
  291. # return decom_df
  292. # def data_deal(self, decom_df, seller_id): # desprecated
  293. # decom_df['mainImageUrl'] = decom_df['seller-sku'].map(lambda x: self.get_mainImage_url(x))
  294. # url_columns = [i for i in decom_df.columns if "url" in i.lower()]
  295. # if len(url_columns) > 0:
  296. # decom_df[url_columns] = decom_df[url_columns].astype("string")
  297. # asin_columns = [i for i in decom_df.columns if 'asin' in i.lower()]
  298. # if len(asin_columns) > 0:
  299. # decom_df[asin_columns] = decom_df[asin_columns].astype("string")
  300. # if 'pending-quantity' in decom_df.columns:
  301. # decom_df['pending-quantity'] = decom_df['pending-quantity'].map(
  302. # lambda x: 0 if pd.isna(x) or np.isinf(x) else x).astype("int32")
  303. # deletecolumns = [i for i in decom_df.columns if 'zshop' in i.lower()]
  304. # decom_df.drop(columns=deletecolumns, inplace=True)
  305. # if 'quantity' in decom_df.columns:
  306. # decom_df['quantity'] = decom_df['quantity'].map(lambda x: 0 if pd.isna(x) or np.isinf(x) else x).astype(
  307. # "int32")
  308. # decom_df['opendate_date'] = decom_df['open-date'].map(lambda x: self.datetime_deal(x))
  309. # if 'add-delete' in decom_df.columns:
  310. # decom_df['add-delete'] = decom_df['add-delete'].astype('string', errors='ignore')
  311. # if 'will-ship-internationally' in decom_df.columns:
  312. # decom_df['will-ship-internationally'] = decom_df['will-ship-internationally'].astype('string',
  313. # errors='ignore')
  314. # if 'expedited-shipping' in decom_df.columns:
  315. # decom_df['expedited-shipping'] = decom_df['expedited-shipping'].astype('string', errors='ignore')
  316. # decom_df['updateTime'] = datetime.now()
  317. # decom_df['timezone'] = "UTC"
  318. # decom_df['seller_id'] = seller_id
  319. # #
  320. # decom_df['item-description'] = decom_df['item-description'].str.slice(0, 500)
  321. # decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].fillna(0.0)
  322. # decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].fillna(0)
  323. # decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[decom_df.select_dtypes(datetime).columns].astype(
  324. # 'string')
  325. # decom_df.fillna('', inplace=True)
  326. # # print(decom_df.info())
  327. # return decom_df
  328. def fba_inventorySQL(self,conn,seller_id):
  329. cursor = conn.cursor()
  330. # 执行语句
  331. cursor.execute(f""" select asin,sku,seller_id,marketplace_id,country_code,quantity,fulfillment_channel
  332. from
  333. (select asin,sku,seller_id,marketplace_id,country_code,quantity,fulfillment_channel,
  334. ROW_NUMBER() over(partition by asin,sku,seller_id,marketplace_id,country_code order by update_datetime desc) as row_
  335. from asj_ads.seller_listings) as t
  336. where row_=1 and seller_id='{seller_id}' and marketplace_id='{self.marketplace.marketplace_id}'
  337. and fulfillment_channel='FBA'
  338. """)#,quantity
  339. query_ = cursor.fetchall()
  340. col_name = [i[0] for i in cursor.description]
  341. df_datatable = pd.DataFrame(query_, columns=col_name)
  342. df_datatable.columns = ['asin_', 'sku_', 'seller_id_', 'marketplace_id_', 'country_code_',
  343. 'afn-fulfillable-quantity']
  344. return df_datatable
  345. def get_fba_neccessary_segment(self,conn,seller_id):
  346. para = {"reportType": ReportType.GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA}
  347. reportid = self.create_report(**para)
  348. df = self.decompression(reportid)
  349. if len(df) == 0:
  350. return self.fba_inventorySQL(conn, seller_id)
  351. # pd.DataFrame()
  352. df['seller_id'] = seller_id
  353. df['marketplace_id'] = self.marketplace.marketplace_id
  354. df['country_code'] = str(self.marketplace)[-2:]
  355. df_rel = df.query("condition=='New'")
  356. df_rel = df_rel.groupby(['asin', 'sku', 'seller_id', 'marketplace_id', 'country_code']).agg(
  357. {'afn-fulfillable-quantity': sum}).reset_index()
  358. df_rel.columns = ['asin_', 'sku_', 'seller_id_', 'marketplace_id_', 'country_code_', 'afn-fulfillable-quantity']
  359. print(f"{seller_id}_{str(self.marketplace)[-2:]}_FBA_Inventory_OK")
  360. return df_rel
  361. def GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA(self,refresh_token,conn=None,seller_id=None,days=-1,**kwargs): # FBA库存信息
  362. try:
  363. return self.get_fba_neccessary_segment(conn,seller_id)
  364. except Exception as e:
  365. print(e)
  366. try:
  367. time.sleep(15)
  368. return self.get_fba_neccessary_segment(conn, seller_id)
  369. except Exception as e:
  370. print(e)
  371. df_rel = pd.DataFrame(columns=['asin_', 'sku_', 'seller_id_', 'marketplace_id_', 'country_code_','afn-fulfillable-quantity'])
  372. return df_rel
  373. 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库存
  374. para = {"reportType": ReportType.GET_MERCHANT_LISTINGS_ALL_DATA}
  375. reportid = self.create_report(**para)
  376. df = self.decompression(reportid)
  377. if len(df)>0:
  378. if self.marketplace.marketplace_id =='A1VC38T7YXB528': # 该站点的数据列有所不同
  379. df.columns = ['item-name','listing-id','seller-sku','price','quantity','open-date','product-id-type','item-description',
  380. 'item-condition','overseas shipping','fast shipping','asin1','stock_number','fulfillment-channel','merchant-shipping-group','status']
  381. df['seller_id'] = seller_id
  382. df['marketplace_id'] = self.marketplace.marketplace_id
  383. df['country_code'] = str(self.marketplace)[-2:]
  384. if 'fulfilment-channel' in df.columns: # 判断是否存在’fulfilment‘字段(1个film),如果存在则添加一个’fulfillment‘字段(两个fillm)
  385. df['fulfillment-channel'] = df['fulfilment-channel'].copy()
  386. # 如果是amazon,则字段改为FBA
  387. 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)
  388. # 如果是DEFAULT,则字段该为FBM
  389. 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)
  390. if 'asin1' not in df.columns: # 如果不存在asin1,则添加asin1字段
  391. df['asin1'] = ''
  392. if 'product-id' not in df.columns: # 如果不存在product-id,则添加product-id字段
  393. df['product-id'] = ''
  394. # 空值处理
  395. # df['quantity'] = df['quantity'].fillna(0).astype('int64',errors='ignore')
  396. df['quantity'] = df['quantity'].map(lambda x:0 if pd.isna(x)==True else int(x))
  397. #库存数量格式处理
  398. df['quantity'] = df['quantity'].astype('int64')
  399. # 填充NA值
  400. 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')
  401. # 为NA的价格填充0
  402. df['price'] = df['price'].fillna(0.0).astype('float64',errors='ignore')
  403. df.fillna('',inplace=True)
  404. # 时间处理
  405. df['opendate'] = df['open-date'].map(lambda x: self.datetime_deal(x))
  406. df['update_datetime'] = datetime.now(pytz.UTC).date()
  407. # 保留列
  408. origin_columns = ['listing-id','seller_id',
  409. 'asin1','seller-sku','title','image_link','country_code',
  410. 'marketplace_id','quantity','fulfillment_channel',
  411. 'price','opendate','status','update_datetime','product-id','product-id-type','modifier'
  412. ]
  413. # 连接数据库
  414. conn = SpApiRequest.Data_auth()
  415. cursor = conn.cursor()
  416. # 执行语句,筛选出asin不为空并且product_id不为空的两列唯一数据。
  417. cursor.execute("""select product_id,asin from (select * from asj_ads.seller_listings where asin is not null
  418. and asin<>'' and product_id is not null and product_id <>'') t1 group by product_id,asin""")
  419. query_ = cursor.fetchall()
  420. col_name = [i[0] for i in cursor.description]
  421. df_datatable = pd.DataFrame(query_, columns=col_name)
  422. # 合并数据,左表为新下载的数据,右表为数据库查询的数据
  423. merged_df = df.merge(df_datatable[['product_id','asin']],how='left',left_on='product-id',right_on='product_id')
  424. # 功能函数,提取asin
  425. def func_(asin,asin1,product_id,cred,market_p,seller_id,sku):
  426. if 'B0' in str(product_id)[:3]:
  427. return str(product_id)
  428. if (pd.isna(asin1) or asin1=='') and (pd.isna(asin)==False and asin !=''):
  429. if 'B0' in asin[:3]:
  430. return asin
  431. elif (pd.isna(asin1)==False and asin1!=''):
  432. if 'B0' in asin1[:3]:
  433. return asin1
  434. listingClient = ListingsItems(credentials=cred, marketplace=market_p)
  435. try:
  436. r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  437. print(r1.payload)
  438. asin = r1.payload.get("summaries")[0].get("asin")
  439. return asin
  440. except Exception as e:
  441. print("获取图片url过程错误重试, 错误message: ", e)
  442. time.sleep(3)
  443. r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  444. print(r1.payload)
  445. asin = r1.payload.get("summaries")[0].get("asin")
  446. return asin
  447. # 应用处理函数,返回asin
  448. 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']
  449. merged_df['image_link'] = ''
  450. # 暂时将refresh_token添加在title列,后面获取asin详细数据时需要用到
  451. merged_df['title'] = refresh_token
  452. merged_df['modifier'] = ''
  453. # 填充NA值
  454. merged_df.fillna('',inplace=True)
  455. df1 = merged_df.copy()
  456. # df1.to_csv("第一次合并处理后.csv")
  457. #获取FBA库存数据
  458. df_fbaInventory = self.GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA(refresh_token, conn, seller_id, days)
  459. # 合并fba库存数据
  460. if len(df_fbaInventory)>0:
  461. 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_'])
  462. 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)
  463. df1['quantity'] = df1['quantity'].map(lambda x:0 if pd.isna(x) else int(x))
  464. df1['quantity'] = df1['quantity'].fillna(0)
  465. # df1.to_csv("第二次合并处理后的数据.csv")
  466. # 判断更新数据
  467. update_df = self.update_data(df1,seller_id,str(self.marketplace)[-2:],conn)
  468. if len(update_df)==0:
  469. return '无更新数据插入'
  470. # update_df['country_code'] = update_df['country_code'].map({"GB":"UK"})
  471. conn = SpApiRequest.Data_auth()
  472. cursor = conn.cursor()
  473. # 插入更新的数据
  474. try:
  475. insertsql = """insert into
  476. asj_ads.seller_listings(listing_id,seller_id,asin,sku,title,image_link,country_code,marketplace_id,quantity,
  477. fulfillment_channel,price,launch_datetime,status,update_datetime,product_id,product_id_type,modifier)
  478. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  479. conn.begin()
  480. cursor.executemany(insertsql,tuple(update_df[origin_columns].to_numpy().tolist()))
  481. conn.commit()
  482. print("插入完成")
  483. delete_sql = f"""delete from asj_ads.seller_listings where update_datetime<'{(datetime.today()+timedelta(days=-3)).date().isoformat()}'"""
  484. cursor.execute(delete_sql)
  485. conn.commit()
  486. return '插入完成'
  487. except Exception as e:
  488. print("插入错误:",e)
  489. conn.rollback()
  490. return '出错回滚'
  491. return ''
  492. # def get_listing_info(self, sku,seller_id): # desprecated
  493. # listingClient = ListingsItems(credentials=self.credentials, marketplace=self.marketplace)
  494. # try:
  495. # r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  496. # # print(r1.payload)
  497. # json_content = r1.payload.get("summaries")[0]
  498. # item_name = json_content.get("itemName")
  499. # item_name ='###' if item_name==None else item_name
  500. # img = json_content.get("mainImage")
  501. # img_url = '###' if img is None else img.get("link")
  502. # return str(img_url)+"-----"+ str(item_name)
  503. # except Exception as e:
  504. # try:
  505. # print("获取图片url过程错误重试, 错误message: ",e)
  506. # time.sleep(3)
  507. # r1 = listingClient.get_listings_item(sellerId=seller_id, sku=sku)
  508. # print(r1.payload)
  509. # json_content = r1.payload.get("summaries")[0]
  510. #
  511. # item_name = json_content.get("itemName")
  512. # item_name = '###' if item_name == None else item_name
  513. # img = json_content.get("mainImage")
  514. # img_url = '###' if img is None else img.get("link")
  515. # return str(img_url)+"-----"+ str(item_name)
  516. # except Exception as e:
  517. # print(e)
  518. # return "###-----###"
  519. def datetime_deal(self,timestring): # used in GET_FLAT_FILE_OPEN_LISTINGS_DATA, time deal -时间处理函数
  520. timezone_ = {"AEST":"Australia/Sydney","AEDT":"Australia/Sydney","PST":"America/Los_Angeles",
  521. "PDT":"America/Los_Angeles","CST":"America/Chicago","CDT":"America/Chicago",
  522. "MET":"MET","MEST":"MET","BST":"Europe/London","GMT":"GMT","CET":"CET",
  523. "CEST":"CET","JST":"Asia/Tokyo","BRT":"America/Sao_Paulo"}
  524. date_list = str.split(timestring,sep = ' ')
  525. if len(date_list)<3:
  526. try:
  527. return datetime.strptime(date_list[0],"%Y-%m-%d")
  528. except:
  529. try:
  530. return datetime.strptime(date_list[0], "%Y/%m/%d")
  531. except:
  532. try:
  533. return datetime.strptime(date_list[0], "%d/%m/%Y")
  534. except Exception as e:
  535. print(e)
  536. return datetime(1999, 12, 31, 0, 0, 0)
  537. try:
  538. time_date = datetime.strptime(date_list[0]+date_list[1],"%Y-%m-%d%H:%M:%S")
  539. timezone = pytz.timezone(timezone_[date_list[2]])
  540. time_ = timezone.localize(time_date)
  541. return time_.astimezone(pytz.UTC)
  542. except:
  543. try:
  544. time_date = datetime.strptime(date_list[0] + date_list[1], "%d/%m/%Y%H:%M:%S")
  545. timezone = pytz.timezone(timezone_[date_list[2]])
  546. time_ = timezone.localize(time_date)
  547. return time_.astimezone(pytz.UTC)
  548. except :
  549. try:
  550. time_date = datetime.strptime(date_list[0] + date_list[1], "%Y/%m/%d%H:%M:%S")
  551. timezone = pytz.timezone(timezone_[date_list[2]])
  552. time_ = timezone.localize(time_date)
  553. return time_.astimezone(pytz.UTC)
  554. except Exception as e1:
  555. print(e1)
  556. return datetime(1999,12,31,0,0,0)
  557. def update_data(self,df,seller_id,country_code,conn): # used in GET_FLAT_FILE_OPEN_LISTINGS_DATA, data compare
  558. conn = SpApiRequest.Data_auth()
  559. cursor = conn.cursor()
  560. columns = ['listing-id', 'seller_id',
  561. 'asin1', 'seller-sku', 'title', 'image_link', 'country_code',
  562. 'marketplace_id', 'quantity', 'fulfillment_channel',
  563. 'price', 'opendate', 'status', 'update_datetime', 'product-id', 'product-id-type','modifier'
  564. ]
  565. if country_code=='GB':
  566. country_code="UK"
  567. df['country_code'] = "UK"
  568. df_data = pd.DataFrame(columns=columns)
  569. delete_list = []
  570. marketplace_id = self.marketplace.marketplace_id
  571. try:
  572. cursor.execute(f"""select * from
  573. asj_ads.seller_listings where seller_id='{seller_id}' and marketplace_id='{marketplace_id}'""")
  574. col = [i[0] for i in cursor.description]
  575. query_rel = cursor.fetchall()
  576. df_rel = pd.DataFrame(query_rel, columns=col)
  577. # df_rel.to_csv("数据库数据.csv")
  578. #数据库数据
  579. df_rel['quantity'] = df_rel['quantity'].fillna(0).astype('int64')
  580. df_rel['price'] = df_rel['price'].fillna(0.0).astype('float64')
  581. df_rel['product_id_type'] = df_rel['product_id_type'].astype('int64')
  582. # 新数据
  583. df['update_datetime'] =df['update_datetime'].astype('datetime64[ns]')
  584. df['quantity'] = df['quantity'].fillna(0).astype('int64')
  585. df['price']= df['price'].fillna(0.0).astype('float64')
  586. row = 0
  587. while row < len(df):
  588. temp_df = df.iloc[row, :]
  589. temp_d = df.iloc[row:row+1, :]
  590. listing_id = temp_df['listing-id']
  591. asin = temp_df['asin1']
  592. sku = temp_df['seller-sku']
  593. quantity = temp_df['quantity']
  594. fulfillment_channel = temp_df['fulfillment_channel']
  595. price = temp_df['price']
  596. product_id = temp_df['product-id']
  597. title = temp_df['title']
  598. imageurl = temp_df['image_link']
  599. modifier = temp_df['modifier']
  600. 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""")
  601. # print("需要关注数据(是否异常):",len(temp),temp.to_numpy().tolist()) if len(temp)>1 else 1
  602. if len(temp)>1:
  603. # temp = temp.head(1).to_numpy().tolist()
  604. df_data = pd.concat((df_data,temp_d),ignore_index=True) #df_data.append(temp_df, ignore_index=True)
  605. delete_list.append((seller_id, marketplace_id, sku, listing_id, product_id))
  606. # print(len(temp))
  607. elif len(temp)==0:
  608. df_data = pd.concat((df_data,temp_d),ignore_index=True)
  609. delete_list.append((seller_id,marketplace_id,sku,listing_id,product_id))
  610. row += 1
  611. print("判断不同数据条数",len(delete_list))
  612. print("预计更新数据条数",len(df_data))
  613. try:
  614. # print(tuple(delete_list))
  615. if len(delete_list)>0:
  616. query = f"""delete from asj_ads.seller_listings
  617. where (seller_id,marketplace_id,sku,listing_id,product_id) in %s""" #where (seller_id,country_code) in %s"""
  618. cursor.execute(query,(delete_list,))
  619. conn.commit()
  620. # print(delete_list)
  621. print("进行中...")
  622. except Exception as e:
  623. print(e)
  624. conn.rollback()
  625. return df_data
  626. except Exception as e:
  627. print("错误:", e)
  628. return df
  629. # def GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE(self,seller_id,days=-2): # not be used,退货报告,空数据
  630. # shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  631. # # print(shopReportday)
  632. # para = {"reportType": ReportType.GET_SELLER_FEEDBACK_DATA,
  633. # "dataStartTime": shopReportday, "dataEndTime": shopReportday,
  634. # }
  635. # reportid = self.create_report(**para) # {"ShowSalesChannel":"true"}
  636. # decom_df = self.decompression(reportid)
  637. # print(decom_df)
  638. # print(decom_df.columns)
  639. def GET_SALES_AND_TRAFFIC_REPORT(self, refresh_token,seller_id,days=-2,**kwargs): # To datatable asj_ads.SalesAndTrafficByAsin,销售流量表
  640. # ,level:Literal["PARENT","CHILD","SKU"]="PARENT")
  641. level = "PARENT" if len(kwargs.get("level"))==0 else kwargs.get("level")
  642. countryCode = None if kwargs.get("countryCode")==None else kwargs.get("countryCode")
  643. # print(level)
  644. shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  645. print(shopReportday,countryCode,seller_id)
  646. try:
  647. conn = self.Data_auth()
  648. cursor = conn.cursor()
  649. except:
  650. time.sleep(5)
  651. conn = self.Data_auth()
  652. cursor = conn.cursor()
  653. if level == 'SKU':
  654. 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"""
  655. elif level == 'CHILD':
  656. 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"""
  657. elif level == 'PARENT':
  658. 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"""
  659. else:
  660. return ''
  661. print(query_judge)
  662. cursor.execute(query_judge)
  663. rel = cursor.fetchall()
  664. # print()
  665. if rel[0][0]!=0:
  666. return '已存在'
  667. # print(shopReportday)
  668. para = {"reportType": ReportType.GET_SALES_AND_TRAFFIC_REPORT,
  669. "dataStartTime": shopReportday, "dataEndTime": shopReportday,
  670. "reportOptions":{"dateGranularity":"DAY","asinGranularity":level}
  671. }
  672. reportid = self.create_report(**para) # {"ShowSalesChannel":"true"}
  673. decom_df = self.decompression(reportid)
  674. # print(decom_df.columns[0])
  675. data_rel = self.sales_traffic_datadeal(decom_df.columns[0],seller_id,countryCode)
  676. try:
  677. conn = self.Data_auth()
  678. cursor = conn.cursor()
  679. except:
  680. time.sleep(5)
  681. conn = self.Data_auth()
  682. cursor = conn.cursor()
  683. # print(list(conn.query("select * from amz_sp_api.orderReport")))
  684. sql = f"""
  685. insert into asj_ads.SalesAndTrafficByAsin(data_date,data_marketpalceId,parent_asin,
  686. childAsin,sku,sBA_unitsOrdered,sBA_unitsOrderedB2B,sBA_amount,
  687. currencyCode,totalOrderItems,totalOrderItemsB2B,tBA_browserSessions,
  688. tBA_browserSessionsB2B,tBA_mobileAppSessions,tBA_mobileAppSessionsB2B,
  689. tBA_sessions,tBA_sessionsB2B,tBA_browserSessionPercentage,
  690. tBA_browserSessionPercentageB2B,tBA_mobileAppSessionPercentage,
  691. tBA_mobileAppSessionPercentageB2B,tBA_sessionPercentage,
  692. tBA_sessionPercentageB2B,tBA_browserPageViews,tBA_browserPageViewsB2B,
  693. tBA_mobileAppPageViews,tBA_mobileAppPageViewsB2B,tBA_pageViews,
  694. tBA_pageViewsB2B,tBA_browserPageViewsPercentage,tBA_browserPageViewsPercentageB2B,
  695. tBA_mobileAppPageViewsPercentage,tBA_mobileAppPageViewsPercentageB2B,
  696. tBA_pageViewsPercentage,tBA_pageViewsPercentageB2B,tBA_buyBoxPercentage,
  697. tBA_buyBoxPercentageB2B,tBA_unitSessionPercentage,tBA_unitSessionPercentageB2B,seller_id,countryCode)
  698. 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)
  699. """ # ok
  700. try:
  701. # TODO
  702. conn.begin()
  703. cursor.executemany(sql, data_rel)
  704. conn.commit()
  705. print("插入完成")
  706. conn.close()
  707. time.sleep(1)
  708. except Exception as e:
  709. conn.rollback()
  710. print(e)
  711. def sales_traffic_datadeal(self,data,seller_id,countryCode): # used in GET_SALES_AND_TRAFFIC_REPORT
  712. data = eval(data)
  713. if len(data['salesAndTrafficByAsin'])==0:
  714. return []
  715. data_list = []
  716. data_date = data["reportSpecification"]["dataEndTime"]
  717. data_marketpalceId = data["reportSpecification"]["marketplaceIds"][0]
  718. # print(data_marketpalceId)
  719. for single_item in data["salesAndTrafficByAsin"]:
  720. # print(single_item)
  721. parent_asin = single_item.get("parentAsin")
  722. childAsin = single_item.get("childAsin")
  723. sku = single_item.get("sku")
  724. salesByAsin = single_item.get("salesByAsin")
  725. # if salesByAsin is not None:
  726. sBA_unitsOrdered = salesByAsin.get("unitsOrdered") if salesByAsin is not None else ''
  727. sBA_unitsOrderedB2B = salesByAsin.get("unitsOrderedB2B") if salesByAsin is not None else ''
  728. orderedProductSales = salesByAsin.get("orderedProductSales")
  729. sBA_amount = orderedProductSales.get("amount") if orderedProductSales is not None else ''
  730. currencyCode = orderedProductSales.get("currencyCode") if orderedProductSales is not None else ''
  731. orderedProductSalesB2B = salesByAsin.get("orderedProductSalesB2B") if salesByAsin is not None else None
  732. # if orderedProductSalesB2B is not None:
  733. oPS_amount = orderedProductSalesB2B.get("amount") if orderedProductSalesB2B is not None else ''
  734. totalOrderItems = salesByAsin.get("totalOrderItems") if salesByAsin is not None else ''
  735. totalOrderItemsB2B = salesByAsin.get("totalOrderItemsB2B") if salesByAsin is not None else ''
  736. trafficByAsin = single_item.get("trafficByAsin")
  737. # if trafficByAsin is not None:
  738. tBA_browserSessions = trafficByAsin.get("browserSessions") if trafficByAsin is not None else ''
  739. tBA_browserSessionsB2B = trafficByAsin.get("browserSessionsB2B") if trafficByAsin is not None else ''
  740. tBA_mobileAppSessions = trafficByAsin.get("mobileAppSessions") if trafficByAsin is not None else ''
  741. tBA_mobileAppSessionsB2B = trafficByAsin.get("mobileAppSessionsB2B") if trafficByAsin is not None else ''
  742. tBA_sessions = trafficByAsin.get("sessions") if trafficByAsin is not None else ''
  743. tBA_sessionsB2B = trafficByAsin.get("sessionsB2B") if trafficByAsin is not None else ''
  744. tBA_browserSessionPercentage = trafficByAsin.get("browserSessionPercentage") if trafficByAsin is not None else ''
  745. tBA_browserSessionPercentageB2B = trafficByAsin.get("browserSessionPercentageB2B") if trafficByAsin is not None else ''
  746. tBA_mobileAppSessionPercentage = trafficByAsin.get("mobileAppSessionPercentage") if trafficByAsin is not None else ''
  747. tBA_mobileAppSessionPercentageB2B = trafficByAsin.get("mobileAppSessionPercentageB2B") if trafficByAsin is not None else ''
  748. tBA_sessionPercentage = trafficByAsin.get("sessionPercentage") if trafficByAsin is not None else ''
  749. tBA_sessionPercentageB2B = trafficByAsin.get("sessionPercentageB2B") if trafficByAsin is not None else ''
  750. tBA_browserPageViews = trafficByAsin.get("browserPageViews") if trafficByAsin is not None else ''
  751. tBA_browserPageViewsB2B = trafficByAsin.get("browserPageViewsB2B") if trafficByAsin is not None else ''
  752. tBA_mobileAppPageViews = trafficByAsin.get("mobileAppPageViews") if trafficByAsin is not None else ''
  753. tBA_mobileAppPageViewsB2B = trafficByAsin.get("mobileAppPageViewsB2B") if trafficByAsin is not None else ''
  754. tBA_pageViews = trafficByAsin.get("pageViews") if trafficByAsin is not None else ''
  755. tBA_pageViewsB2B = trafficByAsin.get("pageViewsB2B") if trafficByAsin is not None else ''
  756. tBA_browserPageViewsPercentage = trafficByAsin.get("browserPageViewsPercentage") if trafficByAsin is not None else ''
  757. tBA_browserPageViewsPercentageB2B = trafficByAsin.get("browserPageViewsPercentageB2B") if trafficByAsin is not None else ''
  758. tBA_mobileAppPageViewsPercentage = trafficByAsin.get("mobileAppPageViewsPercentage") if trafficByAsin is not None else ''
  759. tBA_mobileAppPageViewsPercentageB2B = trafficByAsin.get("mobileAppPageViewsPercentageB2B") if trafficByAsin is not None else ''
  760. tBA_pageViewsPercentage = trafficByAsin.get("pageViewsPercentage") if trafficByAsin is not None else ''
  761. tBA_pageViewsPercentageB2B = trafficByAsin.get("pageViewsPercentageB2B") if trafficByAsin is not None else ''
  762. tBA_buyBoxPercentage = trafficByAsin.get("buyBoxPercentage") if trafficByAsin is not None else ''
  763. tBA_buyBoxPercentageB2B = trafficByAsin.get("buyBoxPercentageB2B") if trafficByAsin is not None else ''
  764. tBA_unitSessionPercentage = trafficByAsin.get("unitSessionPercentage") if trafficByAsin is not None else ''
  765. tBA_unitSessionPercentageB2B = trafficByAsin.get("unitSessionPercentageB2B") if trafficByAsin is not None else ''
  766. data_list.append([data_date,data_marketpalceId,parent_asin,
  767. childAsin,sku,sBA_unitsOrdered,sBA_unitsOrderedB2B,sBA_amount,
  768. currencyCode,totalOrderItems,totalOrderItemsB2B,tBA_browserSessions,
  769. tBA_browserSessionsB2B,tBA_mobileAppSessions,tBA_mobileAppSessionsB2B,
  770. tBA_sessions,tBA_sessionsB2B,tBA_browserSessionPercentage,
  771. tBA_browserSessionPercentageB2B,tBA_mobileAppSessionPercentage,
  772. tBA_mobileAppSessionPercentageB2B,tBA_sessionPercentage,
  773. tBA_sessionPercentageB2B,tBA_browserPageViews,tBA_browserPageViewsB2B,
  774. tBA_mobileAppPageViews,tBA_mobileAppPageViewsB2B,tBA_pageViews,
  775. tBA_pageViewsB2B,tBA_browserPageViewsPercentage,tBA_browserPageViewsPercentageB2B,
  776. tBA_mobileAppPageViewsPercentage,tBA_mobileAppPageViewsPercentageB2B,
  777. tBA_pageViewsPercentage,tBA_pageViewsPercentageB2B,tBA_buyBoxPercentage,
  778. tBA_buyBoxPercentageB2B,tBA_unitSessionPercentage,tBA_unitSessionPercentageB2B,seller_id,countryCode
  779. ])
  780. # print(data_list)
  781. return data_list
  782. def GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL(self, refresh_token,seller_id,days=-1,**kwargs): # To datatable asj_ads.orderReport_ - 获取订单报告
  783. countryCode = None if kwargs.get("countryCode")==None else kwargs.get("countryCode")
  784. shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  785. print(shopReportday)
  786. try:
  787. conn = self.Data_auth()
  788. cursor = conn.cursor()
  789. except Exception as e:
  790. print(e)
  791. time.sleep(5)
  792. conn = self.Data_auth()
  793. cursor = conn.cursor()
  794. query_judge = f"""select count(*) from asj_ads.orderReport_ where ReportDate='{shopReportday}' and country_code='{countryCode}' and seller_id='{seller_id}'"""
  795. print(query_judge)
  796. cursor.execute(query_judge)
  797. rel = cursor.fetchall()
  798. # print()
  799. if rel[0][0]!=0:
  800. print("已存在")
  801. return '已存在'
  802. para = {"reportType": ReportType.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL,
  803. "dataStartTime": shopReportday, "dataEndTime": shopReportday,
  804. "reportOptions": {"ShowSalesChannel": "true"}}
  805. reportid = self.create_report(**para) # {"ShowSalesChannel":"true"}
  806. decom_df = self.decompression(reportid)
  807. # print(decom_df)
  808. # print(decom_df.info())
  809. decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].fillna(0.0)
  810. decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].fillna(0)
  811. decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[decom_df.select_dtypes(datetime).columns].astype(
  812. 'string')
  813. if "purchase-order-number" in decom_df.columns:
  814. decom_df['purchase-order-number'] = decom_df['purchase-order-number'].astype("string")
  815. decom_df.fillna('', inplace=True)
  816. # decom_df.to_csv('order.csv')
  817. decom_df["ReportDate"] = parse(shopReportday)
  818. # decom_df['timezone'] = decom_df["purchase-date"].map(lambda x: parse(x).tzname()).fillna(method='bfill')
  819. decom_df['timezone'] = "UTC"
  820. print("==========================================================")
  821. if len(decom_df)==0:
  822. return ""
  823. decom_df[["purchase-date", "last-updated-date"]] = decom_df[["purchase-date", "last-updated-date"]].applymap(
  824. lambda x: self.timeDeal(x) if pd.isna(x) == False or x != None else x)
  825. if 'is-business-order' not in decom_df.columns:
  826. decom_df['is-business-order'] = None
  827. if 'purchase-order-number' not in decom_df.columns:
  828. decom_df['purchase-order-number'] = '-'
  829. if 'price-designation' not in decom_df.columns:
  830. decom_df['price-designation'] = '-'
  831. decom_df['seller_id'] = seller_id
  832. country_code = str(self.marketplace)[-2:]
  833. if country_code == 'GB':
  834. country_code = "UK"
  835. # decom_df['country_code'] = "UK"
  836. decom_df['country_code'] = country_code
  837. decom_df['insert_time'] = datetime.now()
  838. # print(decom_df[])
  839. reserve_columns = ["amazon-order-id", "merchant-order-id", "purchase-date", "last-updated-date", "order-status",
  840. "fulfillment-channel", "sales-channel", "order-channel", "ship-service-level",
  841. "product-name",
  842. "sku", "asin", "item-status", "quantity", "currency", "item-price", "item-tax",
  843. "shipping-price",
  844. "shipping-tax", "gift-wrap-price", "gift-wrap-tax", "item-promotion-discount",
  845. "ship-promotion-discount", "ship-city", "ship-state", "ship-postal-code", "ship-country",
  846. "promotion-ids", "is-business-order", "purchase-order-number", "price-designation",
  847. "ReportDate",
  848. "timezone", "seller_id", "country_code",'insert_time'
  849. ]
  850. list_df = decom_df[reserve_columns].to_numpy().tolist()
  851. try:
  852. conn = self.Data_auth()
  853. cursor = conn.cursor()
  854. except:
  855. time.sleep(5)
  856. conn = self.Data_auth()
  857. cursor = conn.cursor()
  858. # print(list(conn.query("select * from amz_sp_api.orderReport")))
  859. sql = f"""
  860. insert into asj_ads.orderReport_(`amazon_order_id`, `merchant_order_id`, `purchase_date`, `last_updated_date`, `order_status`,
  861. `fulfillment_channel`, `sales_channel`, `order_channel`, `ship_service_level`,
  862. `product_name`,
  863. `sku`, `asin`, `item_status`, `quantity`, `currency`, `item_price`, `item_tax`,
  864. `shipping_price`,
  865. `shipping_tax`, `gift_wrap_price`, `gift_wrap_tax`, `item_promotion_discount`,
  866. `ship_promotion_discount`, `ship_city`, `ship_state`, `ship_postal_code`, `ship_country`,
  867. `promotion_ids`, `is_business_order`, `purchase_order_number`, `price_designation`,
  868. `ReportDate`,
  869. `timezone`, `seller_id`, `country_code`,`insert_time`)
  870. 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)
  871. """ # ok
  872. try:
  873. conn.begin()
  874. cursor.executemany(sql, list_df)
  875. conn.commit()
  876. print("插入完成")
  877. conn.close()
  878. time.sleep(1)
  879. except Exception as e:
  880. conn.rollback()
  881. print(e)
  882. def timeDeal(self, orgTime): # time-deal
  883. orgTime = parse(orgTime)
  884. timezone = pytz.timezone("UTC")
  885. shopTime = orgTime.astimezone(timezone)
  886. shopTime_datetime = datetime(shopTime.year, shopTime.month, shopTime.day, shopTime.hour, shopTime.minute,
  887. shopTime.second)
  888. return shopTime_datetime
  889. @classmethod
  890. def listing_infoTable(cls): # To datatable asj_ads.Goods - Goods表,包括排名,图片,父子关系
  891. conn = SpApiRequest.Data_auth()
  892. cursor = conn.cursor()
  893. #
  894. 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""")
  895. query_ = cursor.fetchall()
  896. # print(query_)
  897. col_name = [i[0] for i in cursor.description]
  898. df_datatable = pd.DataFrame(query_, columns=col_name)
  899. count=0
  900. distance = 50
  901. print(len(df_datatable))
  902. while count<len(df_datatable):
  903. print(f"进度:{round(count / len(df_datatable) * 100, 2)}%")
  904. df = df_datatable.iloc[count:count+distance,:]
  905. count = count+distance
  906. df['detail_info'] = df.apply(lambda x: cls.get_listing_info01(x['title'],x['country_code'],x['asin'],x['seller_id']),axis=1)
  907. detail_info_k = df['detail_info'].map(lambda x: list(x.keys())).to_numpy().tolist()
  908. detail_info = df['detail_info'].to_numpy().tolist() #df['detail_info'].map(lambda x: list(x.values())).to_numpy().tolist()
  909. conn = SpApiRequest.Data_auth()
  910. print(count)
  911. SpApiRequest.Goods_insert(conn,detail_info,detail_info_k)
  912. if count%distance==0:
  913. cursor = conn.cursor()
  914. cursor.execute(
  915. f"""select seller_id,countryCode,asin from asj_ads.Goods where update_time>='{datetime.today().date()}'""")
  916. query_d = cursor.fetchall()
  917. # print(query_d)
  918. try:
  919. # print(tuple(delete_list))
  920. query = f"""delete from asj_ads.Goods where update_time<'{datetime.today().date()}'
  921. and (seller_id,countryCode,asin) in {query_d}
  922. """ #where (seller_id,country_code) in %s"""
  923. cursor.execute(query)
  924. conn.commit()
  925. # print(delete_list)
  926. # print("进行中...")
  927. except Exception as e:
  928. print(e)
  929. conn.rollback()
  930. print("Success")
  931. conn.close()
  932. @classmethod
  933. def Goods_drop_duplicates(cls):
  934. conn = SpApiRequest.Data_auth()
  935. cursor = conn.cursor()
  936. cursor.execute(
  937. f"""select seller_id,countryCode,asin as count_ from asj_ads.Goods group by seller_id,countryCode,asin having count(asin)>=2""")
  938. query_ = cursor.fetchall()
  939. print(len(query_))
  940. if len(query_)>0:
  941. query_sql2 = cursor.execute(
  942. f"""select distinct 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 from asj_ads.Goods where (seller_id,countryCode,asin) in {query_}""")#
  943. query_2 = cursor.fetchall()
  944. try:
  945. query = f"""delete from asj_ads.Goods where (seller_id,countryCode,asin) in {query_}
  946. """ # where (seller_id,country_code) in %s"""
  947. cursor.execute(query)
  948. conn.commit()
  949. except Exception as e:
  950. print("错误过程1",e)
  951. conn.rollback()
  952. sql = """insert into
  953. 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)
  954. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  955. try:
  956. conn.begin()
  957. cursor.executemany(sql, query_2)
  958. conn.commit()
  959. print("插入完成")
  960. conn.close()
  961. time.sleep(1)
  962. except Exception as e:
  963. conn.rollback()
  964. print("错误过程2",e)
  965. @staticmethod
  966. def get_listing_info01(refresh_token, countryCode, asin, seller_id): # used in listing_infoTable
  967. # print(refresh_token)
  968. aws_credentials = {
  969. 'refresh_token': refresh_token,
  970. 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  971. 'lwa_client_secret': 'amzn1.oa2-cs.v1.13ebfa8ea7723b478215a2b61f4dbf5ca6f6927fa097c2dd0941a66d510aca7f',
  972. 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  973. 'aws_secret_key': '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',
  974. 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  975. }
  976. mak = {'AE': Marketplaces.AE, 'BE': Marketplaces.BE, 'DE': Marketplaces.DE,
  977. 'PL': Marketplaces.PL, 'EG': Marketplaces.EG, 'ES': Marketplaces.ES,
  978. 'FR': Marketplaces.FR, 'GB': Marketplaces.GB, 'IN': Marketplaces.IN,
  979. 'IT': Marketplaces.IT, 'NL': Marketplaces.NL, 'SA': Marketplaces.SA,
  980. 'SE': Marketplaces.SE, 'TR': Marketplaces.TR, 'UK': Marketplaces.UK,
  981. 'AU': Marketplaces.AU, 'JP': Marketplaces.JP, 'SG': Marketplaces.SG,
  982. 'US': Marketplaces.US,
  983. 'BR': Marketplaces.BR, 'CA': Marketplaces.CA, 'MX': Marketplaces.MX
  984. }
  985. cate_item = CatalogItems(credentials=aws_credentials, marketplace=mak[countryCode],version='2022-04-01')
  986. try:
  987. variations_info = SpApiRequest.variations_judge(cate_item, asin)
  988. except:
  989. time.sleep(2.5)
  990. variations_info = SpApiRequest.variations_judge(cate_item, asin)
  991. try:
  992. cate_item = CatalogItems(credentials=aws_credentials, marketplace=mak[countryCode], version='2020-12-01')
  993. detail_info = SpApiRequest.get_detail_cat(cate_item, asin, mak, countryCode)
  994. except:
  995. time.sleep(2.5)
  996. cate_item = CatalogItems(credentials=aws_credentials, marketplace=mak[countryCode], version='2020-12-01')
  997. detail_info = SpApiRequest.get_detail_cat(cate_item, asin, mak, countryCode)
  998. detail_info.update(variations_info)
  999. detail_info['asin'] = asin
  1000. detail_info['countryCode'] = countryCode
  1001. detail_info['marketplace_id'] = mak[countryCode].marketplace_id
  1002. detail_info['seller_id'] = seller_id
  1003. detail_info['update_time'] = datetime.now()
  1004. return detail_info
  1005. @staticmethod
  1006. def variations_judge(cate_item, asin): # used in listing_infoTable, 判断是否有父子关系
  1007. def temp_func(cate_item, asin):
  1008. variations = cate_item.get_catalog_item(asin=asin, **{"includedData": ['relationships']}) # 'variations',
  1009. var_info = variations.payload
  1010. # print(variations)
  1011. IsParent = 'Y'
  1012. parent_asin = ''
  1013. try:
  1014. relationships = var_info.get("relationships")[0]['relationships']
  1015. except:
  1016. relationships = []
  1017. if len(relationships) > 0:
  1018. variationType = relationships[0]['type']
  1019. if relationships[0].get('parentAsins') is not None:
  1020. parent_asin = relationships[0]['parentAsins'][0]
  1021. IsParent = 'N'
  1022. elif relationships[0].get('childAsins') is not None:
  1023. IsParent = 'Y'
  1024. parent_asin = asin
  1025. else:
  1026. parent_asin = 'Erro_01'
  1027. else:
  1028. IsParent = 'SG'
  1029. parent_asin = asin
  1030. print(IsParent, '父asin:', parent_asin, '子asin', asin)
  1031. return {"IsParent": IsParent, "parent_asin": parent_asin}
  1032. try:
  1033. return temp_func(cate_item, asin)
  1034. except:
  1035. try:
  1036. time.sleep(12)
  1037. return temp_func(cate_item, asin)
  1038. except Exception as e:
  1039. print("判断是否为父子asin时出错:", e)
  1040. return {"IsParent": 'Erro', "parent_asin": 'Erro'}
  1041. @staticmethod
  1042. def Goods_insert(conn,detail_info,detail_info_k): # To datatable asj.Goods
  1043. # print(detail_info)
  1044. df = pd.DataFrame(detail_info)
  1045. # print(df.columns)
  1046. try:
  1047. cursor = conn.cursor()
  1048. except:
  1049. time.sleep(2.5)
  1050. conn = SpApiRequest.Data_auth()
  1051. cursor = conn.cursor()
  1052. query_sql = "select * from asj_ads.Goods"
  1053. cursor.execute(query_sql)
  1054. col = [i[0] for i in cursor.description]
  1055. query_rel = cursor.fetchall()
  1056. df_query = pd.DataFrame(query_rel, columns=col)
  1057. merge_df = df.merge(df_query,how='left',on=['asin', 'countryCode', 'marketplace_id', 'seller_id'],suffixes=['','_right'])
  1058. merge_df['IsParent'] = merge_df.apply(lambda x:x['IsParent_right'] if x['IsParent']=='Erro' else x['IsParent'],axis=1)
  1059. merge_df['parent_asin'] = merge_df.apply(lambda x: x['parent_asin_right'] if x['parent_asin'] == 'Erro' else x['parent_asin'], axis=1)
  1060. merge_df = merge_df.query("IsParent!='Erro' and parent_asin!='Erro'")
  1061. detail_info_value = merge_df[['main_image', 'productTypes', 'BigCat_rank', 'BigCat_title', 'SmallCat_rank',
  1062. 'SmallCat_title', 'brandName', 'browseNode', 'itemName', 'IsParent', 'parent_asin',
  1063. 'asin', 'countryCode', 'marketplace_id', 'seller_id', 'update_time']].to_numpy().tolist()
  1064. try:
  1065. insertsql = """insert into
  1066. 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)
  1067. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  1068. conn.begin()
  1069. cursor.executemany(insertsql, tuple(detail_info_value))
  1070. conn.commit()
  1071. print("插入完成Goods")
  1072. except Exception as e:
  1073. print("插入错误Goods:", e)
  1074. conn.rollback()
  1075. sales_rankData = []
  1076. for i in detail_info_value:
  1077. tmp_list = []
  1078. for j in [2,3,4,5,6,8,11,12,13,14]:
  1079. tmp_list.extend([i[j]])
  1080. tmp_list.extend([datetime.now(),datetime.utcnow()])
  1081. sales_rankData.append(tmp_list)
  1082. # print(sales_rankData,len(sales_rankData))
  1083. try:
  1084. insertsql = """insert into
  1085. asj_ads.ProductRank(BigCat_rank, BigCat_title, SmallCat_rank, SmallCat_title, brandName, itemName, asin, countryCode, marketplace_id, seller_id, update_time,time_UTC)
  1086. values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
  1087. conn.begin()
  1088. cursor.executemany(insertsql, tuple(sales_rankData))
  1089. conn.commit()
  1090. print("插入完成rank")
  1091. # return '插入完成'
  1092. except Exception as e:
  1093. print("插入错误rank:", e)
  1094. conn.rollback()
  1095. @staticmethod
  1096. def get_detail_cat(cate_item, asin, mak, countryCode): # used in listing_infoTable, category sp-api - 获取listing的信息数据
  1097. try:
  1098. detail_info = cate_item.get_catalog_item(asin=asin, **{
  1099. "includedData": ["images,productTypes,salesRanks,summaries"],
  1100. "marketplaceIds": [str(mak[countryCode].marketplace_id)]})
  1101. payload = detail_info.payload
  1102. # print(payload)
  1103. try:
  1104. main_image = payload['images'][0]['images'][0]['link'] if len(payload['images']) > 0 else "#"
  1105. except:
  1106. main_image = '#-'
  1107. try:
  1108. productTypes = payload['productTypes'][0]['productType'] if len(payload['productTypes'][0]) > 0 else "#"
  1109. except:
  1110. productTypes = '#-'
  1111. try:
  1112. # print(payload['ranks'][0])
  1113. if len(payload['ranks'][0]) > 0:
  1114. BigCat_rank = payload['ranks'][0]['ranks'][0]['rank']
  1115. BigCat_title = payload['ranks'][0]['ranks'][0]['title']
  1116. SmallCat_rank = payload['ranks'][0]['ranks'][1]['rank']
  1117. SmallCat_title = payload['ranks'][0]['ranks'][1]['title']
  1118. else:
  1119. BigCat_rank, BigCat_title, SmallCat_rank, SmallCat_title = 0, '#', 0, '#'
  1120. except:
  1121. BigCat_rank, BigCat_title, SmallCat_rank, SmallCat_title = 0, '#-', 0, '#-'
  1122. try:
  1123. if len(payload['summaries'][0]) > 0:
  1124. brandName = payload['summaries'][0]['brandName']
  1125. browseNode = payload['summaries'][0]['browseNode']
  1126. itemName = payload['summaries'][0]['itemName']
  1127. else:
  1128. brandName, browseNode, itemName = '#', '#', '#'
  1129. except:
  1130. brandName, browseNode, itemName = '#-', '#-', '#-'
  1131. return {'main_image': main_image, 'productTypes': productTypes, 'BigCat_rank': BigCat_rank,
  1132. 'BigCat_title': BigCat_title, 'SmallCat_rank': SmallCat_rank, 'SmallCat_title': SmallCat_title,
  1133. 'brandName': brandName, 'browseNode': browseNode, 'itemName': itemName}
  1134. except:
  1135. return {'main_image': '', 'productTypes': '', 'BigCat_rank': 0,
  1136. 'BigCat_title': '', 'SmallCat_rank': 0, 'SmallCat_title': '',
  1137. 'brandName': '', 'browseNode': '', 'itemName': ''}
  1138. def GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT(self, refresh_token,seller_id,days=-3,**kwargs):
  1139. shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-04-21")
  1140. shopReportday_E = (datetime.now() + timedelta(days=days)).strftime("%Y-04-27")
  1141. print(shopReportday)
  1142. para = {"reportType": ReportType.GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT,"reportOptions":{"reportPeriod": "WEEK"},"dataStartTime": shopReportday, "dataEndTime": shopReportday_E,}
  1143. reportid = self.create_report(**para)
  1144. @staticmethod
  1145. def GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT_DAY(self,**kwargs):
  1146. shopReportday = "2024-09-04"
  1147. shopReportday_E = "2024-09-04"
  1148. print(shopReportday)
  1149. para = {"reportType": ReportType.GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT,"reportOptions":{"reportPeriod": "DAY"},"dataStartTime": shopReportday, "dataEndTime": shopReportday_E,}
  1150. reportid = self.create_report(**para)
  1151. def BRAND_ANALYTICS_TEXT_deal(self,text):
  1152. pass
  1153. def GET_SELLER_FEEDBACK_DATA(self,refresh_token,seller_id,days,**a_kw):
  1154. kwargs = a_kw
  1155. country_code = str(self.marketplace)[-2:]
  1156. if country_code == 'GB':
  1157. country_code = "UK"
  1158. insert_time = datetime.now()
  1159. shopReportday = (datetime.now().date() + timedelta(days=days)).strftime("%Y-%m-%d")
  1160. shopReportday_E = (datetime.now().date() + timedelta(days=days)).strftime("%Y-%m-%d")
  1161. client = get_client(host='3.93.43.158', port=8123, username='root',
  1162. password='6f0eyLuiVn3slzbGWpzI')
  1163. tmp_df = client.query_df(
  1164. """select * from ams.performance where seller_id='%s' and country_code='%s' and date='%s' and isFeedback=1""" % (
  1165. seller_id, country_code, shopReportday))
  1166. if len(tmp_df) > 0:
  1167. print("数据已存在")
  1168. return 'Done'
  1169. print(shopReportday)
  1170. para = {"reportType": ReportType.GET_SELLER_FEEDBACK_DATA,#GET_SELLER_FEEDBACK_DATA,# GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE |GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA
  1171. "dataStartTime": shopReportday,
  1172. "dataEndTime": shopReportday_E, "reportOptions":{"reportPeriod": "DAY"}}
  1173. try:
  1174. reportid = self.create_report(**para)
  1175. decom_df = self.decompression(reportid)
  1176. except:
  1177. return pd.DataFrame()
  1178. if len(decom_df) == 0:
  1179. return reportid
  1180. decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].applymap(
  1181. lambda x: str(x) if not pd.isna(x) else '')
  1182. decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].applymap(
  1183. lambda x: str(x) if not pd.isna(x) else '')
  1184. decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[
  1185. decom_df.select_dtypes(datetime).columns].applymap(lambda x: str(x) if not pd.isna(x) else '')
  1186. decom_df.fillna('', inplace=True)
  1187. # decom_df.to_csv('order.csv')
  1188. decom_df["ReportDate"] = parse(shopReportday)
  1189. # decom_df['timezone'] = decom_df["purchase-date"].map(lambda x: parse(x).tzname()).fillna(method='bfill')
  1190. decom_df['timezone'] = "UTC"
  1191. # print("==========================================================")
  1192. decom_df['seller_id'] = seller_id
  1193. decom_df['country_code'] = country_code
  1194. decom_df['insert_time'] = datetime.now()
  1195. df_feedback = decom_df.copy()
  1196. df_feedback[["date", "rating", "comment", "order_id"]] = df_feedback[["Date", "Rating", "Comments", "Order ID"]]
  1197. df_feedback['isFeedback'] = 1
  1198. df_feedback['date'] = df_feedback['date'].map(lambda x: pd.to_datetime(x).date())
  1199. df_feedback['seller_id'] = seller_id
  1200. df_feedback['country_code'] = country_code
  1201. # client = get_client(host='3.93.43.158', port=8123, username='root',
  1202. # password='6f0eyLuiVn3slzbGWpzI')
  1203. try:
  1204. client.insert_df(table='ams.performance', df=df_feedback[
  1205. ["date", "rating", "comment", "order_id", "isFeedback", 'seller_id', 'country_code','insert_time']],
  1206. column_names=["date", "rating", "comment", "order_id", "isFeedback", 'seller_id',
  1207. 'country_code','insert_time'])
  1208. except Exception as e:
  1209. print(e)
  1210. client.close()
  1211. # print(decom_df.columns)
  1212. # print(decom_df)
  1213. return reportid
  1214. def GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA(self,refresh_token,seller_id,days,**a_kw):
  1215. kwargs = a_kw
  1216. country_code = str(self.marketplace)[-2:]
  1217. if country_code == 'GB':
  1218. country_code = "UK"
  1219. insert_time = datetime.now()
  1220. shopReportday = (datetime.now().date() + timedelta(days=days)).strftime("%Y-%m-%d")
  1221. shopReportday_E = (datetime.now().date() + timedelta(days=days)).strftime("%Y-%m-%d")
  1222. # print(shopReportday)
  1223. # print("1"*50)
  1224. client = get_client(host='3.93.43.158', port=8123, username='root',
  1225. password='6f0eyLuiVn3slzbGWpzI')
  1226. tmp_df = client.query_df(
  1227. """select * from ams.performance where seller_id='%s' and country_code='%s' and date='%s' and isFeedback=0""" % (
  1228. seller_id, country_code, shopReportday))
  1229. if len(tmp_df) > 0:
  1230. print("数据已存在")
  1231. return 'Done'
  1232. para = {"reportType": ReportType.GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA,#GET_SELLER_FEEDBACK_DATA,# GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE |GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA
  1233. "dataStartTime": shopReportday,
  1234. "dataEndTime": shopReportday_E, "reportOptions":{"reportPeriod": "DAY"}}
  1235. try:
  1236. reportid = self.create_report(**para)
  1237. decom_df = self.decompression(reportid)
  1238. except:
  1239. return pd.DataFrame()
  1240. if len(decom_df) == 0:
  1241. return reportid
  1242. # print("2"*100)
  1243. decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].applymap(
  1244. lambda x: str(x) if not pd.isna(x) else '')
  1245. decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].applymap(
  1246. lambda x: str(x) if not pd.isna(x) else '')
  1247. decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[
  1248. decom_df.select_dtypes(datetime).columns].applymap(lambda x: str(x) if not pd.isna(x) else '')
  1249. decom_df.fillna('', inplace=True)
  1250. # decom_df.to_csv('order.csv')
  1251. decom_df["ReportDate"] = parse(shopReportday)
  1252. # decom_df['timezone'] = decom_df["purchase-date"].map(lambda x: parse(x).tzname()).fillna(method='bfill')
  1253. decom_df['timezone'] = "UTC"
  1254. print("==========================================================")
  1255. decom_df['seller_id'] = seller_id
  1256. decom_df['country_code'] = country_code
  1257. decom_df['insert_time'] = datetime.now()
  1258. df_fbaR = decom_df.copy()
  1259. df_fbaR[['date', 'order_id', 'product_name', 'detailed_disposition', 'comment']] = df_fbaR[
  1260. ['return-date', 'order-id', 'product-name', 'detailed-disposition', 'customer-comments']]
  1261. # df_fbaR[['return-date','order-id','sku','asin','fnsku','product-name','quantity','reason','detailed-disposition','customer-comments']]
  1262. df_fbaR['isFeedback'] = 0
  1263. df_fbaR['date'] = df_fbaR['date'].map(lambda x: pd.to_datetime(x).date())
  1264. df_fbaR['comment'].fillna("", inplace=True)
  1265. # df_fbaR[['order_id','sku','asin','fnsku','detailed_disposition','product_name','isFeedback','date']]
  1266. try:
  1267. client.insert_df(table='ams.performance', df=df_fbaR[
  1268. ['order_id', 'sku', 'asin', 'fnsku', 'detailed_disposition', 'product_name', 'isFeedback', 'date',
  1269. 'comment', 'seller_id', 'country_code','insert_time']],
  1270. column_names=['order_id', 'sku', 'asin', 'fnsku', 'detailed_disposition', 'product_name',
  1271. 'isFeedback', 'date', 'comment', 'seller_id', 'country_code','insert_time'])
  1272. except Exception as e:
  1273. print(e)
  1274. client.close()
  1275. # print(decom_df.columns)
  1276. # print(decom_df)
  1277. return reportid
  1278. def GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE(self, refresh_token, seller_id, days, **a_kw):
  1279. kwargs = a_kw
  1280. country_code = str(self.marketplace)[-2:]
  1281. if country_code == 'GB':
  1282. country_code = "UK"
  1283. insert_time = datetime.now()
  1284. shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  1285. shopReportday_E = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  1286. client = get_client(host='3.93.43.158', port=8123, username='root',
  1287. password='6f0eyLuiVn3slzbGWpzI')
  1288. tmp_df = client.query_df("""select * from ams.return_record where seller_id='%s' and country_code='%s' and ReportDate='%s'""" % (seller_id,country_code,shopReportday))
  1289. if len(tmp_df)>0:
  1290. print("数据已存在")
  1291. return 'Done'
  1292. para = {"reportType": ReportType.GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE,
  1293. # GET_SELLER_FEEDBACK_DATA,# GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE |GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA
  1294. "dataStartTime": shopReportday,
  1295. "dataEndTime": shopReportday_E, "reportOptions": {"reportPeriod": "DAY"}}
  1296. try:
  1297. reportid = self.create_report(**para)
  1298. decom_df = self.decompression(reportid)
  1299. except Exception as e:
  1300. print(e)
  1301. return pd.DataFrame()
  1302. if len(decom_df) == 0:
  1303. return reportid
  1304. print("执行插入")
  1305. decom_df[decom_df.select_dtypes(float).columns] = decom_df[decom_df.select_dtypes(float).columns].applymap(lambda x: str(x) if not pd.isna(x) else '')
  1306. decom_df[decom_df.select_dtypes(int).columns] = decom_df[decom_df.select_dtypes(int).columns].applymap(lambda x: str(x) if not pd.isna(x) else '')
  1307. decom_df[decom_df.select_dtypes(datetime).columns] = decom_df[decom_df.select_dtypes(datetime).columns].applymap(lambda x: str(x) if not pd.isna(x) else '')
  1308. decom_df.fillna('', inplace=True)
  1309. # decom_df.to_csv('order.csv')
  1310. #parse(shopReportday)
  1311. # decom_df['timezone'] = decom_df["purchase-date"].map(lambda x: parse(x).tzname()).fillna(method='bfill')
  1312. decom_df['timezone'] = "UTC"
  1313. decom_df['seller_id'] = seller_id
  1314. decom_df['country_code'] = country_code
  1315. decom_df['insert_time'] = datetime.now()
  1316. decom_df['Order date'] = decom_df['Order date'].map(lambda x:'' if pd.isna(x) or x=='' else parse(x))
  1317. decom_df['Return request date'] = decom_df['Return request date'].map(lambda x:'' if pd.isna(x) or x=='' else parse(x))
  1318. decom_df["ReportDate"] = decom_df["Return request date"]
  1319. # print(decom_df.dtypes)
  1320. # print("======================-------------==================")
  1321. # decom_df['SafeT claim reimbursement amount'] = decom_df['SafeT claim reimbursement amount'].map(str)
  1322. # decom_df['Refunded Amount'] = decom_df['Refunded Amount'].map(str)
  1323. # decom_df['Label cost'] = decom_df['Label cost'].astype('string')
  1324. # print(decom_df.dtypes)
  1325. print("="*100)
  1326. try:
  1327. client.insert_df('ams.return_record',df=decom_df[['Order ID', 'Order date', 'Return request date',
  1328. 'Return request status', 'Amazon RMA ID', 'Merchant RMA ID',
  1329. 'Label type', 'Label cost', 'Currency code', 'Return carrier',
  1330. 'Tracking ID', 'Label to be paid by', 'A-to-Z Claim', 'Is prime',
  1331. 'ASIN', 'Merchant SKU', 'Item Name', 'Return quantity', 'Return Reason',
  1332. 'In policy', 'Return type', 'Resolution', 'Invoice number',
  1333. 'Return delivery date', 'Order Amount', 'Order quantity',
  1334. 'SafeT Action reason', 'SafeT claim id', 'SafeT claim state',
  1335. 'SafeT claim creation time', 'SafeT claim reimbursement amount',
  1336. 'Refunded Amount', 'ReportDate', 'timezone', 'seller_id',
  1337. 'country_code', 'insert_time']],column_names=['Order_ID', 'Order_date', 'Return_request_date','Return_request_status',
  1338. 'Amazon_RMA_ID', 'Merchant_RMA_ID','Label_type', 'Label_cost', 'Currency_code',
  1339. 'Return_carrier','Tracking_ID', 'Label_to_be_paid_by', 'A-to-Z_Claim', 'Is_prime',
  1340. 'ASIN', 'Merchant_SKU', 'Item_Name', 'Return_quantity', 'Return_Reason',
  1341. 'In_policy', 'Return_type', 'Resolution', 'Invoice_number','Return_delivery_date',
  1342. 'Order_Amount', 'Order_quantity','SafeT_Action_reason', 'SafeT_claim_id',
  1343. 'SafeT_claim_state','SafeT_claim_creation_time', 'SafeT_claim_reimbursement_amount',
  1344. 'Refunded_Amount', 'ReportDate', 'timezone', 'seller_id','country_code', 'insert_time'])
  1345. print("完成插入")
  1346. except Exception as e:
  1347. print(e)
  1348. client.close()
  1349. return reportid
  1350. # def GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE(self, refresh_token,seller_id,days=-1,**kwargs):
  1351. # countryCode = None if kwargs.get("countryCode") == None else kwargs.get("countryCode")
  1352. # shopReportday = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
  1353. # print(shopReportday)
  1354. # para = {"reportType": ReportType.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL,
  1355. # "dataStartTime": shopReportday, "dataEndTime": shopReportday,
  1356. # "reportOptions": {"ShowSalesChannel": "true"}}
  1357. # reportid = self.create_report(**para) # {"ShowSalesChannel":"true"}
  1358. # decom_df = self.decompression(reportid)
  1359. # decom_df['seller_id'] = seller_id
  1360. # country_code = str(self.marketplace)[-2:]
  1361. # if country_code == 'GB':
  1362. # country_code = "UK"
  1363. # # decom_df['country_code'] = "UK"
  1364. # decom_df['country_code'] = country_code
  1365. # decom_df['insert_time'] = datetime.now()
  1366. # shopReportday = "2024-11-04"
  1367. # shopReportday_E = "2024-11-04"
  1368. # print(shopReportday)
  1369. # para = {"reportType": ReportType.GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE,
  1370. # # GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE |GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA
  1371. # "dataStartTime": shopReportday,
  1372. # "dataEndTime": shopReportday_E, "reportOptions": {"reportPeriod": "DAY"}}
  1373. # reportid = self.create_report(**para)
  1374. # print(reportid)
  1375. # return reportid
  1376. @staticmethod
  1377. def data_judge_secondTry(refresh_token,sp_api,data_type,seller_id,auth_conn,days=-1,**kwargs): # Main-retry, 重试函数,重试次数2次
  1378. a_kw = kwargs
  1379. try:
  1380. SpApiRequest.data_judge(refresh_token,sp_api, data_type, seller_id, auth_conn,days=days,**a_kw)
  1381. except Exception as e:
  1382. try:
  1383. if e.args[0][0]['code']=='InvalidInput':
  1384. return ''
  1385. print('first time to try...')
  1386. time.sleep(15)
  1387. SpApiRequest.data_judge(refresh_token,sp_api, data_type, seller_id, auth_conn,days=days,**a_kw)
  1388. except Exception as e:
  1389. print(e)
  1390. print('twice time to try...')
  1391. time.sleep(20)
  1392. SpApiRequest.data_judge(refresh_token, sp_api, data_type, seller_id, auth_conn, days=days, **a_kw)
  1393. @staticmethod
  1394. def data_judge(refresh_token,sp_api,data_type,seller_id,auth_conn,days=-1,**kwargs): # select Report type - 报告获取类型判断
  1395. a_kw = kwargs
  1396. if data_type == "GET_FLAT_FILE_OPEN_LISTINGS_DATA":
  1397. return sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(refresh_token,auth_conn,seller_id,days)
  1398. elif data_type =="GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL":
  1399. # for day_ in range(31,1):
  1400. # sp_api.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL(seller_id,days=day_*-1)
  1401. return sp_api.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL(refresh_token,seller_id,days,**a_kw)
  1402. # elif data_type =="GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE":
  1403. # return sp_api.GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE(refresh_token,seller_id,days)
  1404. elif data_type =="GET_SALES_AND_TRAFFIC_REPORT":
  1405. return sp_api.GET_SALES_AND_TRAFFIC_REPORT(refresh_token,seller_id,days,**a_kw)
  1406. elif data_type == "GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA":
  1407. return sp_api.GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA(refresh_token,auth_conn,seller_id,days,**a_kw)
  1408. elif data_type=="GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT":
  1409. return sp_api.GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT(refresh_token,seller_id,days,**a_kw)
  1410. elif data_type=="GET_SELLER_FEEDBACK_DATA":
  1411. return sp_api.GET_SELLER_FEEDBACK_DATA(refresh_token,seller_id,days,**a_kw)
  1412. elif data_type=="GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA":
  1413. return sp_api.GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA(refresh_token,seller_id,days,**a_kw)
  1414. elif data_type=="GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE":
  1415. return sp_api.GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE(refresh_token,seller_id,days,**a_kw)
  1416. else:
  1417. return ""
  1418. @classmethod
  1419. 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, 所有店铺数据报告获取的主要函数
  1420. df = cls.auth_info()
  1421. zosi = df.query("account_name=='AM-ZOSI-US'")['refresh_token'].to_numpy().tolist()
  1422. # zosi = df.query("account_name==' ANX防犯工房'")['refresh_token'].to_numpy().tolist()
  1423. # print(zosi)
  1424. refreshtoken_list = df.query("account_name!='AM-ZOSI-US'")['refresh_token'].to_numpy().tolist()
  1425. # refreshtoken_list = []
  1426. zosi.extend(refreshtoken_list)
  1427. refreshtoken_list = zosi.copy()
  1428. print(len(refreshtoken_list))
  1429. # refreshtoken_list = refreshtoken_list+refreshtoken_li
  1430. a_kw = kwargs
  1431. for refresh_token in refreshtoken_list:
  1432. aws_credentials = {
  1433. 'refresh_token': refresh_token,
  1434. 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  1435. 'lwa_client_secret': 'amzn1.oa2-cs.v1.13ebfa8ea7723b478215a2b61f4dbf5ca6f6927fa097c2dd0941a66d510aca7f',
  1436. 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  1437. 'aws_secret_key': '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',
  1438. 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  1439. }
  1440. single_info = df.query("refresh_token==@refresh_token")
  1441. region_circle = single_info['region'].values[0]
  1442. seller_id = single_info['selling_partner_id'].values[0]
  1443. account_name = single_info['account_name'].values[0]
  1444. if region_circle == 'NA':
  1445. pass
  1446. for marketplace in [Marketplaces.US, Marketplaces.BR, Marketplaces.CA,Marketplaces.MX]:
  1447. sp_api = SpApiRequest(aws_credentials, marketplace)
  1448. a_kw['countryCode'] = str(marketplace)[-2:]
  1449. # print(a_kw)
  1450. try:
  1451. print("refresh_token:",refresh_token,'data_type:',data_type,'seller_id:',seller_id,'marketplace:',marketplace.marketplace_id,'country_code:',a_kw['countryCode'],sep='\n')
  1452. auth_conn = SpApiRequest.Token_auth()
  1453. print("CHECK>>>>>>>>>>>>>>>>>>>>>>>>>")
  1454. # print(a_kw)
  1455. cls.data_judge_secondTry(refresh_token,sp_api, data_type, seller_id, auth_conn,days,**a_kw)
  1456. ## sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  1457. except Exception as e:
  1458. print(e)
  1459. time.sleep(3.5)
  1460. elif region_circle == 'EU':
  1461. pass
  1462. for marketplace in [Marketplaces.DE,Marketplaces.AE, Marketplaces.BE, Marketplaces.PL,
  1463. Marketplaces.EG,Marketplaces.ES, Marketplaces.GB, Marketplaces.IN, Marketplaces.IT,
  1464. Marketplaces.NL, Marketplaces.SA, Marketplaces.SE, Marketplaces.TR,Marketplaces.UK,Marketplaces.FR,
  1465. ]:
  1466. sp_api = SpApiRequest(aws_credentials, marketplace)
  1467. a_kw['countryCode'] = str(marketplace)[-2:]
  1468. try:
  1469. auth_conn = SpApiRequest.Token_auth()
  1470. cls.data_judge_secondTry(refresh_token,sp_api, data_type, seller_id, auth_conn,days,**a_kw)
  1471. ## sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  1472. except Exception as e:
  1473. print(e)
  1474. time.sleep(3.5)
  1475. else:
  1476. # if region_circle not in ['NA','EU']:
  1477. auth_conn = SpApiRequest.Token_auth()
  1478. print(region_circle)
  1479. marketplace = eval(f'Marketplaces.{region_circle}')
  1480. sp_api = SpApiRequest(aws_credentials, marketplace)
  1481. a_kw['countryCode'] = str(marketplace)[-2:]
  1482. cls.data_judge_secondTry(refresh_token,sp_api, data_type, seller_id, auth_conn,days,**a_kw)
  1483. ## sp_api.GET_FLAT_FILE_OPEN_LISTINGS_DATA(auth_conn, seller_id)
  1484. def price_tracker(self,asin):
  1485. base_product = Products(credentials=self.credentials,marketplace=Marketplaces.US)
  1486. return base_product.get_product_pricing_for_asins(asin)
  1487. if __name__ == '__main__':
  1488. # for days in range(-17,-2):
  1489. # SpApiRequest.get_allShops("GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE",days=days,**{})
  1490. for days in range(-5,-60,-1):
  1491. SpApiRequest.get_allShops("GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA",days=days,**{})
  1492. #
  1493. # SpApiRequest.listing_infoTable()
  1494. # rel = SpApiRequest.get_catelog(account_name='AM-ZOSI-US',country=Marketplaces.US,asin='B0B8CPHSL4')
  1495. # print(rel)
  1496. # SpApiRequest
  1497. ###TEST
  1498. # df = SpApiRequest.auth_info()
  1499. # print(df)
  1500. # zosi = df.query("account_name=='AM-ZOSI-US'")['refresh_token'].to_numpy().tolist()
  1501. # # print(zosi)
  1502. # refreshtoken_list = df.query("account_name!='AM-ZOSI-US'")['refresh_token'].to_numpy().tolist()
  1503. # zosi.extend(refreshtoken_list)
  1504. # refreshtoken_list = zosi.copy()
  1505. # aws_credentials = {
  1506. # 'refresh_token': refreshtoken_list[0],
  1507. # 'lwa_app_id': 'amzn1.application-oa2-client.1f9d3d4747e14b22b4b598e54e6b922e', # 卖家中心里面开发者资料LWA凭证
  1508. # 'lwa_client_secret': 'amzn1.oa2-cs.v1.13ebfa8ea7723b478215a2b61f4dbf5ca6f6927fa097c2dd0941a66d510aca7f',
  1509. # 'aws_access_key': 'AKIARBAGHTGOZC7544GN',
  1510. # 'aws_secret_key': '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',
  1511. # 'role_arn': 'arn:aws:iam::070880041373:role/Amazon_SP_API_ROLE'
  1512. # }
  1513. # sp_api = SpApiRequest(aws_credentials, Marketplaces.US)
  1514. # id = sp_api.GET_SELLER_FEEDBACK_DATA()
  1515. # print(id)
  1516. # df= sp_api.decompression(str(id))
  1517. # print(df)
  1518. # df.to_csv('GET_SELLER_FEEDBACK_DATA.csv')
  1519. #### END
  1520. # print(sp_api.price_tracker(['B00L3W2QJ2']))
  1521. # shopReportday = "2024-08-25"
  1522. # shopReportday_E = "2024-08-31"
  1523. # print(shopReportday)
  1524. # # para = {"reportType": ReportType.GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT, "reportOptions": {"reportPeriod": "WEEK"},
  1525. # # "dataStartTime": shopReportday, "dataEndTime": shopReportday_E, }
  1526. # # report = Reports(credentials=aws, marketplace=self.marketplace)
  1527. # report = Reports(credentials=aws_credentials, marketplace=Marketplaces.US)
  1528. # rel = report.create_report(
  1529. # reportType=ReportType.GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT, marketplaceIds=['ATVPDKIKX0DER'],
  1530. # reportOptions={"reportPeriod": "WEEK"}, dataStartTime=shopReportday, dataEndTime=shopReportday_E
  1531. # )
  1532. # reportId = rel.payload.get("reportId")
  1533. #
  1534. # while True:
  1535. # reportId_info = report.get_report(reportId=reportId)
  1536. # # print(reportId_info.payload)
  1537. # print("please wait...",reportId_info.payload.get("processingStatus"))
  1538. # # print(reportId_info)
  1539. # if reportId_info.payload.get("processingStatus") == ProcessingStatus.DONE:
  1540. # print(reportId_info.payload)
  1541. # reportDocumentId = reportId_info.payload.get("reportDocumentId")
  1542. # rp_table = report.get_report_document(reportDocumentId=reportDocumentId, download=False)
  1543. # print(rp_table)
  1544. # elif reportId_info.payload.get("processingStatus") == ProcessingStatus.FATAL:
  1545. # reportDocumentId = reportId_info.payload.get("reportDocumentId")
  1546. # rp_table = report.get_report_document(reportDocumentId=reportDocumentId, download=False)
  1547. # import requests
  1548. # # requests.get(rp_table['payload']['url'])
  1549. #
  1550. # df = pd.read_table(filepath_or_buffer=rp_table.payload['url'], compression={"method": 'gzip'},
  1551. # encoding='iso-8859-1')
  1552. # # df = pandas.read_csv(rp_table['payload']['url'],)
  1553. # print(df.to_dict(orient='records'))
  1554. # break