smartpush 1.2.0__py3-none-any.whl → 1.2.3__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.
- smartpush/export/basic/ExcelExportChecker.py +26 -4
- smartpush/export/basic/GetOssUrl.py +15 -5
- smartpush/export/basic/ReadExcel.py +14 -5
- smartpush/test.py +10 -5
- {smartpush-1.2.0.dist-info → smartpush-1.2.3.dist-info}/METADATA +1 -1
- smartpush-1.2.3.dist-info/RECORD +14 -0
- smartpush-1.2.0.dist-info/RECORD +0 -14
- {smartpush-1.2.0.dist-info → smartpush-1.2.3.dist-info}/WHEEL +0 -0
- {smartpush-1.2.0.dist-info → smartpush-1.2.3.dist-info}/top_level.txt +0 -0
@@ -95,6 +95,25 @@ def check_excel_content_form_dict(actual, expected, **kwargs):
|
|
95
95
|
return check_excel_content(actual, expected)
|
96
96
|
|
97
97
|
|
98
|
+
def check_excel_content_including_expected(actual, expected, **kwargs):
|
99
|
+
"""
|
100
|
+
通过 OSS URL 比较 Excel 内容,期望是包含的结果,actual传的是生成的oss
|
101
|
+
"""
|
102
|
+
actual, expected = read_excel_and_write_to_dict(actual, **kwargs), read_excel_and_write_to_dict(
|
103
|
+
expected, **kwargs)
|
104
|
+
# 判断是否存在差异
|
105
|
+
missing_items = find_missing_elements(expected.values(), actual.values())
|
106
|
+
return (False, {"与期望结果存在差异": missing_items}) if missing_items else (True, "校验期望结果包含校验通过")
|
107
|
+
|
108
|
+
|
109
|
+
def find_missing_elements(list1, list2):
|
110
|
+
missing = []
|
111
|
+
for element in list1:
|
112
|
+
if element not in list2:
|
113
|
+
missing.append(element)
|
114
|
+
return missing
|
115
|
+
|
116
|
+
|
98
117
|
def check_excel_content_form_list(actual, expected):
|
99
118
|
"""
|
100
119
|
通过 内容 比较 Excel 内容,不包含表头
|
@@ -103,7 +122,7 @@ def check_excel_content_form_list(actual, expected):
|
|
103
122
|
return check_excel_content(actual=actual, expected=expected)
|
104
123
|
|
105
124
|
|
106
|
-
def check_excel_all(actual_oss, expected_oss, **kwargs):
|
125
|
+
def check_excel_all(actual_oss, expected_oss, check_type=None, **kwargs):
|
107
126
|
"""
|
108
127
|
校验所有内容
|
109
128
|
**kwargs: skiprows->int 用于跳过读取行数,如果第一行是动态变化的,建议单独过滤,第一行传1
|
@@ -112,10 +131,12 @@ def check_excel_all(actual_oss, expected_oss, **kwargs):
|
|
112
131
|
actual, expected = read_excel_from_oss(actual_oss), read_excel_from_oss(expected_oss)
|
113
132
|
actual_data_copy = copy.deepcopy(actual)
|
114
133
|
expected_data_copy = copy.deepcopy(expected)
|
115
|
-
|
116
134
|
flag1, name_result = check_excel_name(actual_oss, expected_oss)
|
117
|
-
flag2, content_result = check_excel_content_form_dict(actual, expected, type=file_type, **kwargs)
|
118
135
|
flag3, header_result = check_excel_header(actual_data_copy, expected_data_copy, type=file_type, **kwargs)
|
136
|
+
if check_type == "including":
|
137
|
+
flag2, content_result = check_excel_content_including_expected(actual, expected, type=file_type, **kwargs)
|
138
|
+
else:
|
139
|
+
flag2, content_result = check_excel_content_form_dict(actual, expected, type=file_type, **kwargs)
|
119
140
|
print(json.dumps(
|
120
141
|
{f"文件名称-{flag1}": name_result, f"导出内容-{flag2}": content_result, f"表头校验-{flag3}": header_result},
|
121
142
|
ensure_ascii=False))
|
@@ -196,7 +217,8 @@ def check_excel_content(actual, expected):
|
|
196
217
|
continue
|
197
218
|
else:
|
198
219
|
errors.append(
|
199
|
-
f"第{i+1}个sheet的内容-第" + str(i + 1) + "行不匹配,预期为:" + str(
|
220
|
+
f"第{i + 1}个sheet的内容-第" + str(i + 1) + "行不匹配,预期为:" + str(
|
221
|
+
expected[i]) + ", 实际为: " + str(
|
200
222
|
actual[i]))
|
201
223
|
return False, errors
|
202
224
|
else:
|
@@ -5,6 +5,15 @@ import requests
|
|
5
5
|
from tenacity import retry, stop_after_attempt, wait_fixed, RetryError
|
6
6
|
from smartpush.utils.StringUtils import StringUtils
|
7
7
|
|
8
|
+
_requestParam = {
|
9
|
+
"page": 1,
|
10
|
+
"pageSize": 20,
|
11
|
+
"type": "EXPORT",
|
12
|
+
"status": None,
|
13
|
+
"startTime": None,
|
14
|
+
"endTime": None
|
15
|
+
}
|
16
|
+
|
8
17
|
|
9
18
|
# 用于技术第几次重试,无需修改
|
10
19
|
def log_attempt(retry_state):
|
@@ -15,7 +24,7 @@ def log_attempt(retry_state):
|
|
15
24
|
print(f"当前重试次数: {attempt_number}")
|
16
25
|
|
17
26
|
|
18
|
-
def get_oss_address_with_retry(target_id, url, requestHeader, requestParam, **kwargs) -> str:
|
27
|
+
def get_oss_address_with_retry(target_id, url, requestHeader, requestParam=None, **kwargs) -> str:
|
19
28
|
"""
|
20
29
|
创建带有动态重试配置的获取 OSS 地址
|
21
30
|
**kwargs 可传参:tries=10, delay=2, backoff=1
|
@@ -25,7 +34,9 @@ def get_oss_address_with_retry(target_id, url, requestHeader, requestParam, **kw
|
|
25
34
|
:param requestHeader:
|
26
35
|
:return: 带有重试配置的获取 OSS 地址的
|
27
36
|
"""
|
28
|
-
|
37
|
+
if requestParam is None:
|
38
|
+
requestParam = _requestParam
|
39
|
+
tries = kwargs.get('tries', 30) # 重试次数
|
29
40
|
delay = kwargs.get('delay', 2)
|
30
41
|
|
31
42
|
@retry(stop=stop_after_attempt(tries), wait=wait_fixed(delay), after=log_attempt)
|
@@ -33,8 +44,7 @@ def get_oss_address_with_retry(target_id, url, requestHeader, requestParam, **kw
|
|
33
44
|
_url = url + '/bulkOps/query'
|
34
45
|
result = None
|
35
46
|
if StringUtils.is_empty(target_id):
|
36
|
-
|
37
|
-
return
|
47
|
+
raise ValueError("缺少target_id参数")
|
38
48
|
try:
|
39
49
|
response = requests.request(url=_url, headers=requestHeader, data=json.dumps(requestParam),
|
40
50
|
method="post")
|
@@ -75,4 +85,4 @@ def get_oss_address_with_retry(target_id, url, requestHeader, requestParam, **kw
|
|
75
85
|
# print(f"最终失败,错误信息: {e}")
|
76
86
|
if isinstance(e, RetryError):
|
77
87
|
cancel_export_file(target_id)
|
78
|
-
return None
|
88
|
+
return None
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import csv
|
1
2
|
import io
|
2
3
|
import os
|
3
4
|
import re
|
@@ -7,6 +8,8 @@ from io import BytesIO
|
|
7
8
|
import pandas as pd
|
8
9
|
from requests import request
|
9
10
|
|
11
|
+
from smartpush.utils.StringUtils import StringUtils
|
12
|
+
|
10
13
|
warnings.simplefilter("ignore")
|
11
14
|
excel_extensions = ['.xlsb', '.xlsx', '.xlsm', '.xls', '.xltx', '.xltm', '.xlam', None]
|
12
15
|
csv_extensions = ['.csv']
|
@@ -48,7 +51,7 @@ def read_excel_header(excel_data, return_type='list', **kwargs):
|
|
48
51
|
else:
|
49
52
|
# csv的头
|
50
53
|
# result = dfs.keys().values.tolist()
|
51
|
-
result = dfs.
|
54
|
+
result = dfs.index.tolist() # csv转置后读取头数据
|
52
55
|
return result
|
53
56
|
except Exception as e:
|
54
57
|
print(f"excel生成header-list出错:{e}")
|
@@ -65,7 +68,12 @@ def read_excel_csv_data(excel_data, **kwargs):
|
|
65
68
|
io.BytesIO) \
|
66
69
|
else excel_data
|
67
70
|
else:
|
68
|
-
dfs = pd.read_csv(excel_data, na_filter=False)
|
71
|
+
dfs = pd.read_csv(excel_data, encoding='utf-8', na_filter=False, dtype={'\ufeff姓名': str})
|
72
|
+
# 这里替换制表符
|
73
|
+
# for col in dfs.columns:
|
74
|
+
# if dfs[col].dtype == 'object': # 只处理字符串类型的列
|
75
|
+
# dfs[col] = dfs[col].str.replace('\t', '')
|
76
|
+
dfs = dfs.transpose() # 转置
|
69
77
|
return dfs
|
70
78
|
|
71
79
|
|
@@ -87,14 +95,13 @@ def read_excel_and_write_to_dict(excel_data=None, file_name=None, **kwargs):
|
|
87
95
|
for sheet_name, row in dfs.items():
|
88
96
|
row = row.to_dict(orient='records')
|
89
97
|
if kwargs.get("ignore_sort", False):
|
90
|
-
sorted_data_asc = sorted(row[1:], key=lambda x: x[
|
91
|
-
sorted_data_asc = [row[0]]+sorted_data_asc
|
98
|
+
sorted_data_asc = sorted(row[1:], key=lambda x: x[0], reverse=True) # 内部排序
|
99
|
+
sorted_data_asc = [row[0]] + sorted_data_asc
|
92
100
|
row_dict[sheet_name] = sorted_data_asc
|
93
101
|
else:
|
94
102
|
row_dict[sheet_name] = row
|
95
103
|
else:
|
96
104
|
row_dict = dfs.to_dict()
|
97
|
-
print(row_dict)
|
98
105
|
return row_dict
|
99
106
|
except zipfile.BadZipFile:
|
100
107
|
print(f"文件读取错误,请检查文件是否为无效文件:{dfs}")
|
@@ -161,6 +168,8 @@ def read_excel_data_for_oss_write_to_dict(oss, **kwargs) -> dict:
|
|
161
168
|
|
162
169
|
# 从 URL 中提取文件名
|
163
170
|
def get_file_suffix_name(url):
|
171
|
+
if StringUtils.is_empty(url):
|
172
|
+
raise ValueError("Oss Url不允许为空")
|
164
173
|
last_filename = ""
|
165
174
|
filename = url.split("/")[-1]
|
166
175
|
# 从文件名中提取文件后缀
|
smartpush/test.py
CHANGED
@@ -10,19 +10,24 @@ from smartpush.export.basic.ReadExcel import read_excel_and_write_to_dict
|
|
10
10
|
from smartpush.export.basic.GetOssUrl import get_oss_address_with_retry
|
11
11
|
|
12
12
|
if __name__ == '__main__':
|
13
|
-
oss1 = "https://cdn.smartpushedm.com/material_ec2/2025-02-
|
14
|
-
oss2 = "https://cdn.smartpushedm.com/material_ec2/2025-02-
|
13
|
+
oss1 = "https://cdn.smartpushedm.com/material_ec2/2025-02-25/58c4a3a885884741b22380c360ac2894/【自动化导出】营销活动URL点击与热图.xlsx"
|
14
|
+
oss2 = "https://cdn.smartpushedm.com/material_ec2/2025-02-27/a5e18e3b3a83432daca871953cb8471b/【自动化导出】营销活动URL点击与热图.xlsx"
|
15
15
|
# # print(check_excel_all(oss1, oss1))
|
16
16
|
oss3 = "https://cdn.smartpushedm.com/material_ec2/2025-02-25/58c4a3a885884741b22380c360ac2894/【自动化导出】营销活动URL点击与热图.xlsx"
|
17
17
|
oss4 = "https://cdn.smartpushedm.com/material_ec2/2025-02-26/58cee630b4c84eec9572b867af4ce692/%E3%80%90%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AF%BC%E5%87%BA%E3%80%91%E8%90%A5%E9%94%80%E6%B4%BB%E5%8A%A8URL%E7%82%B9%E5%87%BB%E4%B8%8E%E7%83%AD%E5%9B%BE.xlsx"
|
18
|
-
expected_oss ="https://cdn.smartpushedm.com/material_ec2/2025-02-26/757df7e77ce544e193257c0da35a4983/%E3%80%90%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AF%BC%E5%87%BA%E3%80%91%E8%90%A5%E9%94%80%E6%B4%BB%E5%8A%A8%E6%95%B0%E6%8D%AE%E6%A6%82%E8%A7%88.xlsx"
|
18
|
+
expected_oss = "https://cdn.smartpushedm.com/material_ec2/2025-02-26/757df7e77ce544e193257c0da35a4983/%E3%80%90%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AF%BC%E5%87%BA%E3%80%91%E8%90%A5%E9%94%80%E6%B4%BB%E5%8A%A8%E6%95%B0%E6%8D%AE%E6%A6%82%E8%A7%88.xlsx"
|
19
19
|
actual_oss = "https://cdn.smartpushedm.com/material_ec2/2025-02-26/757df7e77ce544e193257c0da35a4983/%E3%80%90%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AF%BC%E5%87%BA%E3%80%91%E8%90%A5%E9%94%80%E6%B4%BB%E5%8A%A8%E6%95%B0%E6%8D%AE%E6%A6%82%E8%A7%88.xlsx"
|
20
|
+
|
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
|
+
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
|
+
|
20
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}')
|
21
25
|
# # res=read_excel_and_write_to_dict(read_excel_from_oss(actual_oss))
|
22
26
|
# # print(res)
|
23
27
|
# # print(read_excel_and_write_to_dict(read_excel_from_oss(oss1), type=".xlsx"))
|
24
28
|
# print(check_excel(check_type="all", actual_oss=actual_oss, expected_oss=expected_oss))
|
25
29
|
# print(check_excel_all(actual_oss=oss1, expected_oss=oss2,skiprows =1))
|
26
|
-
print(check_excel_all(actual_oss=
|
30
|
+
print(check_excel_all(actual_oss=oss1, expected_oss=oss2,ignore_sort=True))
|
31
|
+
# print(check_excel_all(actual_oss=a_person_oss2, expected_oss=e_person_oss1, check_type="including"))
|
32
|
+
# print(check_excel_all(actual_oss=e_person_oss1, expected_oss=a_person_oss2, check_type="person"))
|
27
33
|
# read_excel_csv_data(type=)
|
28
|
-
|
@@ -0,0 +1,14 @@
|
|
1
|
+
smartpush/__init__.py,sha256=XJrl1vhGATHSeSVqKmPXxYqxyseriUpvY5tLIXir3EE,24
|
2
|
+
smartpush/get_jira_info.py,sha256=dmCwkKa94xwyE2hegE1KBI3cV_LbrJ67P9osORUGPt4,2633
|
3
|
+
smartpush/test.py,sha256=4bn3pYr_pZqi4E4mXeX0AX68pLOpasa9V0rD5Hxlud8,3054
|
4
|
+
smartpush/export/__init__.py,sha256=D9GbWcmwnetEndFDty5XbVienFK1WjqV2yYcQp3CM84,99
|
5
|
+
smartpush/export/basic/ExcelExportChecker.py,sha256=BsThRl0rGlGxNQZP8rzgqCwlkdFu7JM5lMy7ypE-kFs,14553
|
6
|
+
smartpush/export/basic/GetOssUrl.py,sha256=zlExF_jy_TRV5lp0fws8Wed5MF_byp7JAEmvARVqlIg,3263
|
7
|
+
smartpush/export/basic/ReadExcel.py,sha256=YSTxfYA_0-FvAoZSYlLV3SCgNeHHzKVb7usAQ5zg6PI,7077
|
8
|
+
smartpush/export/basic/__init__.py,sha256=6tcrS-2NSlsJo-UwEsnGUmwCf7jgOsh_UEbM0FD-gYE,70
|
9
|
+
smartpush/utils/StringUtils.py,sha256=NXomJ4qmyBRAFnGj5hrFRWwQnRQMTcPzy20fk1dunSw,3980
|
10
|
+
smartpush/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
+
smartpush-1.2.3.dist-info/METADATA,sha256=ATvxkB7sdoHBcmBsB0iB9JhdjiEiAJC0u9BY3ulOiqU,145
|
12
|
+
smartpush-1.2.3.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
13
|
+
smartpush-1.2.3.dist-info/top_level.txt,sha256=5_CXqu08EfbPaKLjuSAOAqCmGU6shiatwDU_ViBGCmg,10
|
14
|
+
smartpush-1.2.3.dist-info/RECORD,,
|
smartpush-1.2.0.dist-info/RECORD
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
smartpush/__init__.py,sha256=XJrl1vhGATHSeSVqKmPXxYqxyseriUpvY5tLIXir3EE,24
|
2
|
-
smartpush/get_jira_info.py,sha256=dmCwkKa94xwyE2hegE1KBI3cV_LbrJ67P9osORUGPt4,2633
|
3
|
-
smartpush/test.py,sha256=3yHz44AZaalSQtxgsRlIDK5qFla8JiPp8sBgMfkVNJQ,2666
|
4
|
-
smartpush/export/__init__.py,sha256=D9GbWcmwnetEndFDty5XbVienFK1WjqV2yYcQp3CM84,99
|
5
|
-
smartpush/export/basic/ExcelExportChecker.py,sha256=Ku-UoBKqTE7VwAWA644DNGUmXmXnnjmY6ifLV4rznUI,13593
|
6
|
-
smartpush/export/basic/GetOssUrl.py,sha256=oCbPRGa5SqdPWzzeQ8sG10uZJByhrLAzUtwZi_IZgrg,3062
|
7
|
-
smartpush/export/basic/ReadExcel.py,sha256=MqhfJuqjz8PQYJgV4v26LtO1_5moFLn4dHeqfKXifjg,6609
|
8
|
-
smartpush/export/basic/__init__.py,sha256=6tcrS-2NSlsJo-UwEsnGUmwCf7jgOsh_UEbM0FD-gYE,70
|
9
|
-
smartpush/utils/StringUtils.py,sha256=NXomJ4qmyBRAFnGj5hrFRWwQnRQMTcPzy20fk1dunSw,3980
|
10
|
-
smartpush/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
-
smartpush-1.2.0.dist-info/METADATA,sha256=g00rcKwBscfVLpZkhczQ5WZVPCtsKqgGod4DLonOB3o,145
|
12
|
-
smartpush-1.2.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
13
|
-
smartpush-1.2.0.dist-info/top_level.txt,sha256=5_CXqu08EfbPaKLjuSAOAqCmGU6shiatwDU_ViBGCmg,10
|
14
|
-
smartpush-1.2.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|