smartpush 1.2.9__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -113,6 +113,10 @@ def check_excel_content_including_expected(actual, expected, expected_oss, **kwa
113
113
 
114
114
  def find_missing_elements(list1, list2):
115
115
  missing = []
116
+ sorted_list1 = sorted(list1)
117
+ sorted_list2 = sorted(list2)
118
+ if sorted_list1 == sorted_list2:
119
+ return missing
116
120
  for element in list1:
117
121
  if element not in list2:
118
122
  missing.append(element)
@@ -126,7 +130,7 @@ def assert_flow(expected, actual, expected_oss):
126
130
  ex_sheet1 = expected.get("Flow node data by sending time", [])
127
131
  ac_sheet1 = actual.get("Flow node data by sending time", [])
128
132
  differences = []
129
- res=[]
133
+ res = []
130
134
  ex_sheet1.append(ex_sheet0)
131
135
  ac_sheet1.append(ac_sheet0)
132
136
  for i in ac_sheet1:
@@ -176,7 +180,7 @@ def check_excel_all(actual_oss, expected_oss, check_type=None, **kwargs):
176
180
  return all([flag1, flag2, flag3])
177
181
 
178
182
 
179
- def check_and_get_file_suffix_name(actual_oss, expected_oss) -> str:
183
+ def check_and_get_file_suffix_name(actual_oss, expected_oss, **kwargs) -> str:
180
184
  """
181
185
  校验并获取oss的后缀类型
182
186
  @param actual_oss:
@@ -185,6 +189,8 @@ def check_and_get_file_suffix_name(actual_oss, expected_oss) -> str:
185
189
  """
186
190
  actual_file_suffix_name = get_file_suffix_name(actual_oss)
187
191
  expected_file_suffix_name = get_file_suffix_name(expected_oss)
192
+ if actual_oss == expected_oss and kwargs.get("test", False):
193
+ raise Exception("oss链接不允许相同,请检查oss链接是否为相同链接,调试需要请传参数test=True")
188
194
  try:
189
195
  assert actual_file_suffix_name == expected_file_suffix_name
190
196
  return actual_file_suffix_name
@@ -270,11 +276,6 @@ def check_excel_header(actual, expected, **kwargs):
270
276
  @return:
271
277
  """
272
278
  try:
273
- # if all([isinstance(actual, str), isinstance(expected, str)]):
274
- # actual1, expected1 = read_excel_header(read_excel_from_oss(actual), **kwargs), read_excel_header(
275
- # read_excel_from_oss(
276
- # expected), **kwargs)
277
- # else:
278
279
  actual1, expected1 = read_excel_header(actual, return_type='dict', **kwargs), read_excel_header(expected,
279
280
  return_type='dict',
280
281
  **kwargs)
@@ -364,12 +365,11 @@ def compare_lists(actual_dict_list, expected_dict_list):
364
365
  def check_field_format(actual_oss, **kwargs):
365
366
  """
366
367
  逐个校验字段类型
367
- **kwargs: fileds为需检查字段,结构为dict,如{"0": {"1": "email", "2": "time"}},
368
+ **kwargs: fileds为需检查字段,结构为dict,如{0: {0: "email", 1: "time"}},
368
369
  即校验第一个sheet第二个字段需符合email格式,第二个字段需符合time格式
369
370
  """
370
371
  # 获取oss内容并存入dict
371
372
  actual = read_excel_from_oss(actual_oss)
372
- actual_data_copy = copy.deepcopy(actual)
373
373
  actual_dict = read_excel_and_write_to_dict(actual, **kwargs)
374
374
  # 解析参数并校验字段类型
375
375
  errors = []
@@ -2,10 +2,11 @@ import json
2
2
  import urllib
3
3
 
4
4
  import requests
5
- from tenacity import retry, stop_after_attempt, wait_fixed, RetryError
5
+ from requests import HTTPError
6
+ from tenacity import retry, stop_after_attempt, wait_fixed, RetryError, stop_any
6
7
  from smartpush.utils.StringUtils import StringUtils
7
8
 
8
- _requestParam = {
9
+ export_requestParam = {
9
10
  "page": 1,
10
11
  "pageSize": 20,
11
12
  "type": "EXPORT",
@@ -14,6 +15,17 @@ _requestParam = {
14
15
  "endTime": None
15
16
  }
16
17
 
18
+ import_requestParam = {
19
+ "page": 1,
20
+ "pageSize": 20,
21
+ "type": "IMPORT",
22
+ "status": None,
23
+ "startTime": None,
24
+ "endTime": None
25
+ }
26
+
27
+ manually_stop = False # 手动停止表示
28
+
17
29
 
18
30
  # 用于技术第几次重试,无需修改
19
31
  def log_attempt(retry_state):
@@ -24,10 +36,18 @@ def log_attempt(retry_state):
24
36
  print(f"当前重试次数: {attempt_number}")
25
37
 
26
38
 
27
- def get_oss_address_with_retry(target_id, url, requestHeader, requestParam=None, **kwargs) -> str:
39
+ # 自定义停止条件函数
40
+ def should_stop(retry_state):
41
+ if manually_stop:
42
+ print("数据导入/导出状态是失败,立即停止重试")
43
+ return manually_stop
44
+
45
+
46
+ def get_oss_address_with_retry(target_id, url, requestHeader, requestParam=None, is_import=False, **kwargs) -> str:
28
47
  """
29
48
  创建带有动态重试配置的获取 OSS 地址
30
49
  **kwargs 可传参:tries=10, delay=2, backoff=1
50
+ :param is_import: 如果是导入的则传True
31
51
  :param requestParam:
32
52
  :param url:
33
53
  :param target_id:
@@ -35,23 +55,34 @@ def get_oss_address_with_retry(target_id, url, requestHeader, requestParam=None,
35
55
  :return: 带有重试配置的获取 OSS 地址的
36
56
  """
37
57
  if requestParam is None:
38
- requestParam = _requestParam
58
+ requestParam = import_requestParam if is_import else export_requestParam
39
59
  tries = kwargs.get('tries', 30) # 重试次数
40
60
  delay = kwargs.get('delay', 2)
61
+ _url = url + '/bulkOps/query'
62
+ if StringUtils.is_empty(target_id):
63
+ raise ValueError("缺少target_id参数")
41
64
 
42
- @retry(stop=stop_after_attempt(tries), wait=wait_fixed(delay), after=log_attempt)
65
+ def bulkOps_query(_url, _requestHeader, _requestParam):
66
+ response = requests.request(url=_url, headers=_requestHeader, data=json.dumps(_requestParam),
67
+ method="post")
68
+ response.raise_for_status()
69
+ result = response.json()
70
+ if result['code'] != 1:
71
+ raise HTTPError(f"{result}")
72
+ return result
73
+
74
+ @retry(stop=stop_after_attempt(tries) | stop_any(should_stop), wait=wait_fixed(delay), after=log_attempt)
43
75
  def get_oss_address():
44
- _url = url + '/bulkOps/query'
45
- result = None
46
- if StringUtils.is_empty(target_id):
47
- raise ValueError("缺少target_id参数")
48
76
  try:
49
- response = requests.request(url=_url, headers=requestHeader, data=json.dumps(requestParam),
50
- method="post")
51
- response.raise_for_status()
52
- result = response.json()
77
+ result = bulkOps_query(_url, requestHeader, requestParam)
53
78
  id_url_dict = {item["id"]: item["url"] for item in result["resultData"]["datas"]}
79
+ id_status_dict = {item["id"]: [item["status"], item["reason"]] for item in result["resultData"]["datas"]}
54
80
  if target_id in id_url_dict:
81
+ if id_status_dict[target_id][0] == "FAIL":
82
+ reason = id_status_dict[target_id][1]
83
+ print(f"导出id {target_id}失败,原因是 [{reason}]")
84
+ global manually_stop
85
+ manually_stop = True
55
86
  if len(id_url_dict[target_id]) == 1:
56
87
  target_url = urllib.parse.unquote(id_url_dict[target_id][0])
57
88
  print(f"target_id [{target_id}] 的oss链接为: {target_url}")
@@ -59,16 +90,45 @@ def get_oss_address_with_retry(target_id, url, requestHeader, requestParam=None,
59
90
  else:
60
91
  raise ValueError(f"存在多条 id 为 {target_id} 的记录,记录为:{id_url_dict[target_id]}")
61
92
  else:
62
- raise ValueError(f"未找到 id 为 {target_id} 的记录,未包含有效的 OSS 地址,")
93
+ raise ValueError(f"未找到 导出id 为 {target_id} 的记录,未包含有效的 OSS 地址")
63
94
  except (KeyError, json.JSONDecodeError) as e:
64
95
  raise ValueError(f"响应数据格式错误,响应结果: {result},异常: {e}")
65
96
  except requests.RequestException as e:
66
97
  print(f"请求发生异常: {e},正在重试...")
67
98
  raise
68
99
 
100
+ @retry(stop=stop_after_attempt(tries) | stop_any(should_stop), wait=wait_fixed(delay), after=log_attempt)
101
+ def get_import_success():
102
+ target_id_list = []
103
+ try:
104
+ result = bulkOps_query(_url, requestHeader, requestParam)
105
+ for item in result["resultData"]["datas"]:
106
+ if item.get("id") == int(target_id):
107
+ status = item.get("status")
108
+ reason = item.get("reason")
109
+ if status == "FAIL":
110
+ print(f"导入id {target_id}失败,原因是 [{reason}]")
111
+ global manually_stop
112
+ manually_stop = True
113
+ assert status == "SUCCESS"
114
+ return f"导入id {target_id} 导入成功"
115
+ else:
116
+ target_id_list.append(item.get("id"))
117
+ if target_id not in target_id_list:
118
+ raise ValueError(f"未找到 导入id 为 {target_id} 的记录,请检查是否发起导入")
119
+ except AssertionError:
120
+ raise AssertionError(f"导入id 为 {target_id} 的记录非SUCCESS,状态为:{status}")
121
+ except (KeyError, json.JSONDecodeError) as e:
122
+ raise ValueError(f"响应数据格式错误,响应结果: {result},异常: {e}")
123
+ except requests.RequestException as e:
124
+ print(f"请求发生异常: {e},正在重试...")
125
+ raise
126
+ except Exception:
127
+ raise
128
+
69
129
  def cancel_export_file(_target_id):
70
130
  """
71
- 用于失败后取消导出
131
+ 用于失败后取消导出/导入
72
132
  :param _target_id:
73
133
  :return:
74
134
  """
@@ -76,13 +136,19 @@ def get_oss_address_with_retry(target_id, url, requestHeader, requestParam=None,
76
136
  response = requests.request(url=cancel_url, headers=requestHeader, params={'id': _target_id}, method="get")
77
137
  response.raise_for_status()
78
138
  result = response.json()
79
- print(f"获取Oss Url失败,取消 {_target_id} 的导出记录,响应:{result}")
139
+ if is_import:
140
+ print(f"导入文件失败,取消 {_target_id} 的导入记录,响应:{result}")
141
+ else:
142
+ print(f"获取Oss Url失败,取消 {_target_id} 的导出记录,响应:{result}")
80
143
  return result
81
144
 
82
145
  try:
83
- return get_oss_address()
146
+ if is_import:
147
+ return get_import_success()
148
+ else:
149
+ return get_oss_address()
84
150
  except Exception as e:
85
151
  # print(f"最终失败,错误信息: {e}")
86
152
  if isinstance(e, RetryError):
87
153
  cancel_export_file(target_id)
88
- return None
154
+ return f"执行失败,错误信息: {e}"
smartpush/test.py CHANGED
@@ -7,7 +7,7 @@ from smartpush.export.basic.ExcelExportChecker import check_excel_all, read_exce
7
7
  read_excel_from_oss, read_excel_csv_data, check_excel
8
8
  from smartpush.export.basic.ReadExcel import read_excel_from_oss
9
9
  from smartpush.export.basic.ReadExcel import read_excel_and_write_to_dict
10
- from smartpush.export.basic.GetOssUrl import get_oss_address_with_retry
10
+ from smartpush.export.basic.GetOssUrl import get_oss_address_with_retry, export_requestParam, import_requestParam
11
11
 
12
12
  if __name__ == '__main__':
13
13
  oss1 = "https://cdn.smartpushedm.com/material_ec2/2025-02-25/58c4a3a885884741b22380c360ac2894/【自动化导出】营销活动URL点击与热图.xlsx"
@@ -20,18 +20,22 @@ if __name__ == '__main__':
20
20
 
21
21
  e_person_oss1 = "https://cdn.smartpushedm.com/material_ec2/2025-02-27/b48f34b3e88045d189631ec1f0f23d51/%E5%AF%BC%E5%87%BA%E5%85%A8%E9%83%A8%E5%AE%A2%E6%88%B7.csv"
22
22
  a_person_oss2 = "https://cdn.smartpushedm.com/material_ec2/2025-02-27/c50519d803c04e3b9b52d9f625fed413/%E5%AF%BC%E5%87%BA%E5%85%A8%E9%83%A8%E5%AE%A2%E6%88%B7.csv"
23
-
24
- # # #actual_oss= get_oss_address_with_retry("23161","https://cdn.smartpushedm.com/material_ec2_prod/2025-02-20/dae941ec20964ca5b106407858676f89/%E7%BE%A4%E7%BB%84%E6%95%B0%E6%8D%AE%E6%A6%82%E8%A7%88.xlsx","",'{"page":1,"pageSize":10,"type":null,"status":null,"startTime":null,"endTime":null}')
23
+ host = "https://test.smartpushedm.com/api-em-ec2"
24
+ reqHeaders = {
25
+ 'cookie': 'osudb_appid=SMARTPUSH;osudb_oar=#01#SID0000123BL6ciRHRKpvOm/vWT9OS9brpfhSErcOdgeXJc0RJFopg83z0N3RzDE4w2DE5cQj6ALkLP8vG6Rhs0sR7NfToZvCLWXdQtYk6DJoKe4tqdo4kNcIc9F5obzLuyRmwGy9CZKcg/bMlmNyDZwBI1SIO;osudb_subappid=1;osudb_uid=4213785247;ecom_http_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDM4NDI1NTIsImp0aSI6IjEwNGQwOTVjLTA3MDItNDI5MC1iZjQzLWQ4YTVhNjdmNDM2NSIsInVzZXJJbmZvIjp7ImlkIjowLCJ1c2VySWQiOiI0MjEzNzg1MjQ3IiwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImZlbGl4LnNoYW9Ac2hvcGxpbmVhcHAuY29tIiwidXNlclJvbGUiOiJvd25lciIsInBsYXRmb3JtVHlwZSI6Nywic3ViUGxhdGZvcm0iOjEsInBob25lIjoiIiwibGFuZ3VhZ2UiOiJ6aC1oYW5zLWNuIiwiYXV0aFR5cGUiOiIiLCJhdHRyaWJ1dGVzIjp7ImNvdW50cnlDb2RlIjoiQ04iLCJjdXJyZW5jeSI6IkpQWSIsImN1cnJlbmN5U3ltYm9sIjoiSlDCpSIsImRvbWFpbiI6InNtYXJ0cHVzaDQubXlzaG9wbGluZXN0Zy5jb20iLCJsYW5ndWFnZSI6ImVuIiwibWVyY2hhbnRFbWFpbCI6ImZlbGl4LnNoYW9Ac2hvcGxpbmUuY29tIiwibWVyY2hhbnROYW1lIjoiU21hcnRQdXNoNF9lYzJf6Ieq5Yqo5YyW5bqX6ZO6IiwicGhvbmUiOiIiLCJzY29wZUNoYW5nZWQiOmZhbHNlLCJzdGFmZkxhbmd1YWdlIjoiemgtaGFucy1jbiIsInN0YXR1cyI6MCwidGltZXpvbmUiOiJBc2lhL01hY2FvIn0sInN0b3JlSWQiOiIxNjQ0Mzk1OTIwNDQ0IiwiaGFuZGxlIjoic21hcnRwdXNoNCIsImVudiI6IkNOIiwic3RlIjoiIiwidmVyaWZ5IjoiIn0sImxvZ2luVGltZSI6MTc0MTI1MDU1MjI4Miwic2NvcGUiOlsiZW1haWwtbWFya2V0IiwiY29va2llIiwic2wtZWNvbS1lbWFpbC1tYXJrZXQtbmV3LXRlc3QiLCJlbWFpbC1tYXJrZXQtbmV3LWRldi1mcyIsImFwaS11Yy1lYzIiLCJhcGktc3UtZWMyIiwiYXBpLWVtLWVjMiIsImZsb3ctcGx1Z2luIl0sImNsaWVudF9pZCI6ImVtYWlsLW1hcmtldCJ9.SjeTCLaZqbEFEFNeKe_EjrwmR0LdEYO9697ymVNzf5Q;',
26
+ 'Content-Type': 'application/json'}
27
+ actual_oss = get_oss_address_with_retry(11911, host, reqHeaders, import_requestParam, is_import=True)
28
+ actual_oss = get_oss_address_with_retry(11896, host, reqHeaders, export_requestParam)
25
29
  # # res=read_excel_and_write_to_dict(read_excel_from_oss(actual_oss))
26
30
  # # print(res)
27
31
  # # print(read_excel_and_write_to_dict(read_excel_from_oss(oss1), type=".xlsx"))
28
32
  # print(check_excel(check_type="all", actual_oss=actual_oss, expected_oss=expected_oss))
29
33
  # print(check_excel_all(actual_oss=oss1, expected_oss=oss2,skiprows =1))
30
- #print(check_excel_all(actual_oss=oss1, expected_oss=oss2, ignore_sort=0))
34
+ # print(check_excel_all(actual_oss=oss1, expected_oss=oss2, ignore_sort=0))
31
35
  # print(check_excel_all(actual_oss=a_person_oss2, expected_oss=e_person_oss1, check_type="including"))
32
36
  # print(check_excel_all(actual_oss=e_person_oss1, expected_oss=a_person_oss2, check_type="person"))
33
37
  # read_excel_csv_data(type=)
34
38
 
35
- flow_ex="https://cdn.smartpushedm.com/material_ec2/2025-02-20/ad9e1534b8134dd098e96813f17d4b4d/%E6%B5%8B%E8%AF%95flow%E6%95%B0%E6%8D%AE%E6%8A%A5%E5%91%8A%E5%AF%BC%E5%87%BA%E5%8B%BF%E5%8A%A8%E6%95%B0%E6%8D%AE%E6%A6%82%E8%A7%88.xlsx"
36
- flow_ac="https://cdn.smartpushedm.com/material_ec2/2025-03-04/0c8f919f28d4455f9908f905aada7efb/测试flow数据报告导出勿动数据概览.xlsx"
37
- print(check_excel_all(actual_oss=flow_ac, expected_oss=flow_ex, check_type="including",export_type="flow",skiprows=1))
39
+ # flow_ex="https://cdn.smartpushedm.com/material_ec2/2025-02-20/ad9e1534b8134dd098e96813f17d4b4d/%E6%B5%8B%E8%AF%95flow%E6%95%B0%E6%8D%AE%E6%8A%A5%E5%91%8A%E5%AF%BC%E5%87%BA%E5%8B%BF%E5%8A%A8%E6%95%B0%E6%8D%AE%E6%A6%82%E8%A7%88.xlsx"
40
+ # flow_ac="https://cdn.smartpushedm.com/material_ec2/2025-03-04/0c8f919f28d4455f9908f905aada7efb/测试flow数据报告导出勿动数据概览.xlsx"
41
+ # print(check_excel_all(actual_oss=flow_ac, expected_oss=flow_ex, check_type="including",export_type="flow",skiprows=1))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: smartpush
3
- Version: 1.2.9
3
+ Version: 1.3.0
4
4
  Summary: 用于smartpush自动化测试工具包
5
5
  Author: 卢泽彬、邵宇飞、周彦龙
6
6
 
@@ -1,15 +1,15 @@
1
1
  smartpush/__init__.py,sha256=XJrl1vhGATHSeSVqKmPXxYqxyseriUpvY5tLIXir3EE,24
2
2
  smartpush/get_jira_info.py,sha256=dmCwkKa94xwyE2hegE1KBI3cV_LbrJ67P9osORUGPt4,2633
3
- smartpush/test.py,sha256=pMXVJzsiQc7INFYmH_ZUPkHBbjl0xmFD8-9yKL8Wn1o,3564
3
+ smartpush/test.py,sha256=lbPkb0Pk0r4C0u_dD3Qov59MUOhjXomIbb0Ktw3rnV4,5117
4
4
  smartpush/export/__init__.py,sha256=D9GbWcmwnetEndFDty5XbVienFK1WjqV2yYcQp3CM84,99
5
- smartpush/export/basic/ExcelExportChecker.py,sha256=BOcIEqYrZD9yhMSvHrqPFDOUj_5zKhm2_OyQSN7KOds,17718
6
- smartpush/export/basic/GetOssUrl.py,sha256=zlExF_jy_TRV5lp0fws8Wed5MF_byp7JAEmvARVqlIg,3263
5
+ smartpush/export/basic/ExcelExportChecker.py,sha256=iZe-cb9YAIdLhbJb32xh6WUDgzIFyUx9XIAlpciGiNc,17716
6
+ smartpush/export/basic/GetOssUrl.py,sha256=LeF1y1_uJaYXth1KvO6mEDS29ezb9tliBv5SrbqYkXc,6136
7
7
  smartpush/export/basic/ReadExcel.py,sha256=ZnG2mtYqLY-xuYx9SyulbdYUP_0E5jIeKDewfakAsTw,7342
8
8
  smartpush/export/basic/__init__.py,sha256=6tcrS-2NSlsJo-UwEsnGUmwCf7jgOsh_UEbM0FD-gYE,70
9
9
  smartpush/utils/DataTypeUtils.py,sha256=BC7ioztO3vAfKd1EOoNvXdVuXYY8qjNskV1DP7LhW-M,1082
10
10
  smartpush/utils/StringUtils.py,sha256=NXomJ4qmyBRAFnGj5hrFRWwQnRQMTcPzy20fk1dunSw,3980
11
11
  smartpush/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- smartpush-1.2.9.dist-info/METADATA,sha256=NLRbHHvxDiBoF4HDuR8tV_7F61tySFBVumFx0Jcebew,145
13
- smartpush-1.2.9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
14
- smartpush-1.2.9.dist-info/top_level.txt,sha256=5_CXqu08EfbPaKLjuSAOAqCmGU6shiatwDU_ViBGCmg,10
15
- smartpush-1.2.9.dist-info/RECORD,,
12
+ smartpush-1.3.0.dist-info/METADATA,sha256=mtKumAl9qgD0gtQNvF0y65zblr6KXMRuX48Ym31Eqcc,145
13
+ smartpush-1.3.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
14
+ smartpush-1.3.0.dist-info/top_level.txt,sha256=5_CXqu08EfbPaKLjuSAOAqCmGU6shiatwDU_ViBGCmg,10
15
+ smartpush-1.3.0.dist-info/RECORD,,