smartpush 2.0.5__py3-none-any.whl → 2.0.7__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.
@@ -77,3 +77,10 @@ class ActivityTemplateRequestBase(RequestBase):
77
77
  def __init__(self, activityTemplateId, host, headers, **kwargs):
78
78
  super().__init__(host, headers, **kwargs)
79
79
  self.activityTemplateId = activityTemplateId
80
+
81
+
82
+ class OpenApiRequestBase(RequestBase):
83
+ def __init__(self, event_id, host, headers, **kwargs):
84
+ super().__init__(host, headers, **kwargs)
85
+ self.event_id = event_id
86
+
@@ -64,8 +64,20 @@ class URL:
64
64
  step1 = "/marketing/insertOrUpdateActivity/step1", POST
65
65
  step2 = "/marketing/insertOrUpdateActivity/step2", POST
66
66
  step2_get = "/marketing/activityDetail/step2", GET
67
- delete = "/marketing/deleteActivity",GET
68
- copy = '/marketing/copyActivity',GET
67
+ delete = "/marketing/deleteActivity", GET
68
+ copy = '/marketing/copyActivity', GET
69
+
70
+ class OpenApi(BaseEnum):
71
+ """
72
+ :type OpenApi
73
+ """
74
+ getEventMetaList = '/metrics/getEventMetaList', POST
75
+ getEventMetaById = '/metrics/getEventMetaById', POST
76
+ delEventMetaById = '/metrics/delEventMetaById', POST
77
+ editEventMeta = '/metrics/editEventMeta', POST
78
+ getEventChannel = '/metrics/getEventChannel', GET
79
+ getEventAttr = '/metrics/getEventAttr', POST
80
+
69
81
 
70
82
 
71
83
  if __name__ == '__main__':
@@ -1,17 +1,7 @@
1
- import json
2
-
3
- from smartpush.base.request_base import ActivityTemplateRequestBase, RequestBase
1
+ from smartpush.base.request_base import ActivityTemplateRequestBase
4
2
  from smartpush.base.url_enum import URL
5
- from smartpush.utils.date_utils import *
6
3
  from smartpush.email.schema import *
7
-
8
- """
9
- 创建活动草稿
10
- """
11
-
12
- """
13
- 更新活动草稿内容
14
- """
4
+ from smartpush.utils.date_utils import *
15
5
 
16
6
 
17
7
  class ActivityTemplate(ActivityTemplateRequestBase):
smartpush/email/schema.py CHANGED
@@ -11,6 +11,18 @@ def generate_UUID(length=None):
11
11
  return _uuid
12
12
 
13
13
 
14
+ class BlockType(Enum):
15
+ Section = 1
16
+ Block = 0
17
+
18
+ @staticmethod
19
+ def getType(block_type):
20
+ if block_type == BlockType.Section.name:
21
+ return BlockType.Section.value
22
+ else:
23
+ return BlockType.Block.value
24
+
25
+
14
26
  @unique
15
27
  class BlockSchema(Enum):
16
28
  Logo = {
@@ -548,6 +560,7 @@ class BlockSchema(Enum):
548
560
  elif isinstance(node, list):
549
561
  for item in node:
550
562
  recursive_parse(item)
563
+
551
564
  recursive_parse(schema if isinstance(schema, dict) else schema.value)
552
565
  schemaAnalysis = {"schema": result}
553
566
  return json.dumps(schemaAnalysis)
@@ -1,15 +1,14 @@
1
- import json
2
1
  import time
2
+ from typing import Optional, List, Dict, Any
3
3
 
4
4
  from smartpush.base.request_base import RequestBase
5
5
  from smartpush.base.url_enum import *
6
6
  from smartpush.email.schema import *
7
- from smartpush.email.activity import ActivityTemplate
8
7
 
9
8
 
10
9
  def gen_universal_request_param(universalId, schema, **kwargs):
11
10
  """
12
-
11
+ 生成单个universal的请求参数
13
12
  :param schema:
14
13
  :type universalId:
15
14
  kwargs :
@@ -23,15 +22,88 @@ def gen_universal_request_param(universalId, schema, **kwargs):
23
22
  "universalName": universalName,
24
23
  "schema": json.dumps(result_schema),
25
24
  "subUniversalId": kwargs.get('subUniversal_id', universalId),
26
- "type": kwargs.get('type', 0),
25
+ "type": BlockType.getType(result_schema.get('type')),
27
26
  "blockType": result_schema.get('type'),
28
27
  "flowModal": kwargs.get('flowModal', '')
29
28
  }
30
- return json.dumps(requestParam)
29
+ return json.dumps(requestParam) if kwargs.get('jsonDumps') else requestParam
30
+
31
+
32
+ def gen_update_universal_param(
33
+ block_schema_list: Optional[List[Dict[str, Any]]] = None,
34
+ section_schema: Optional[Dict[str, Any]] = None
35
+ ) -> dict[str, list[dict[str, Any]] | int]:
36
+ """
37
+ 根据Block列表生成更新参数,支持同时更新关联的Section(Section始终放在参数列表首位)
38
+
39
+ :param block_schema_list: Block schema列表(每个元素为字典格式的schema)
40
+ :param section_schema: Section schema字典(可选,传入则同步更新Section)
41
+ :return: 统一格式的更新请求参数列表(字典类型,未序列化)
42
+ """
43
+ # 初始化参数列表和Block收集列表(默认空列表,避免None判断)
44
+ update_params: List[Dict[str, Any]] = []
45
+ valid_block_schemas: List[Dict[str, Any]] = []
46
+ type = 0
47
+ # 处理Block参数(过滤无效schema,避免异常)
48
+ block_schema_list = block_schema_list or []
49
+ for block_schema in block_schema_list:
50
+ if not isinstance(block_schema, dict):
51
+ print("不符合格式:",block_schema)
52
+ continue # 跳过非字典格式的无效schema
53
+ # 提取必要字段(无默认值时用空字符串兜底,避免KeyError)
54
+ universal_id = block_schema.get('universalId', '')
55
+ universal_name = block_schema.get('universalName', '')
56
+
57
+ # 生成Block更新参数(指定jsonDumps=False返回字典,保持格式统一)
58
+ block_param = gen_universal_request_param(
59
+ universalId=universal_id,
60
+ schema=block_schema,
61
+ jsonDumps=False,
62
+ universalName=universal_name
63
+ )
64
+ update_params.append(block_param)
65
+
66
+ # 收集有效Block,用于更新Section的children
67
+ if section_schema:
68
+ valid_block_schemas.append(block_schema)
69
+
70
+ # 处理Section参数(如需同步更新,插入列表首位)
71
+ if isinstance(section_schema, dict):
72
+ # 提取Section必要字段
73
+ section_id = section_schema.get('universalId', '')
74
+ section_name = section_schema.get('universalName', '')
75
+ section_inner_id = section_schema.get('id', '')
76
+
77
+ # 若有有效Block,更新Section的children(保持原逻辑)
78
+ final_section_schema = section_schema
79
+ if valid_block_schemas:
80
+ final_section_schema = get_universal_schema(
81
+ schema=BlockSchema.genSection(valid_block_schemas),
82
+ _id=section_inner_id,
83
+ universalId=section_id,
84
+ universalName=section_name
85
+ )
86
+
87
+ # 生成Section更新参数
88
+ section_param = gen_universal_request_param(
89
+ universalId=section_id,
90
+ schema=final_section_schema,
91
+ jsonDumps=False,
92
+ universalName=section_name
93
+ )
94
+ type = 1
95
+ # 插入列表开头(确保Section在首位)
96
+ update_params.insert(0, section_param)
97
+ print(f"生成更新请求参数(共{len(update_params)}个):\n{json.dumps(update_params, indent=2, ensure_ascii=False)}")
98
+ return {'data':update_params,'type':type}
31
99
 
32
100
 
33
101
  class UniversalContent(RequestBase):
34
- # 获取universal创建参数
102
+ # 写一个init初始化
103
+ def __init__(self, universal_id=None, *args, **kwargs):
104
+ """初始化,传入"""
105
+ super().__init__(*args, **kwargs) # 调用父类初始化
106
+ self.universal_id = universal_id # 初始化event_id属性
35
107
 
36
108
  # 创建universal
37
109
  def create_universal(self, requestParam):
@@ -57,35 +129,53 @@ class UniversalContent(RequestBase):
57
129
  return result
58
130
 
59
131
  # 更新universal
60
- def update_universal(self, universal_list, _type=0):
132
+ def update_universal(self, universal_list):
61
133
  """
62
- 更新素材
63
- :param _type:
134
+ 更新素材,需要多个universal参数组合,type参数为section =1 ,block =0,有section和block时取section
64
135
  :param universal_list:
65
- [{"universalId": _dict.get('universa_id'),
66
- "universalName": _dict.get('universa_name'),
67
- "schema": json.dumps(result_schema),
68
- "subUniversalId": _dict.get('subUniversal_id', _dict.get('universa_id')),
69
- "type": _dict.get('type'),
70
- "blockType": _dict.get('schema').name,
71
- "flowModal": ""
72
- }]
136
+ {
137
+ "data": [
138
+ {
139
+ "universalId": "9a1d1b16-7b48-4f9e-9dc9-f379efd746a5",
140
+ "universalName": "Auto-Section-2025-12-03 14:44:01",
141
+ "schema": "{\"id\": \"546bced03\", \"universalId\": \"9a1d1b16-7b48-4f9e-9dc9-f379efd746a5\", \"universalName\": \"Auto-Section-2025-12-03 14:44:01\", \"type\": \"Section\", \"props\": {\"backgroundColor\": \"#f1e6e6\", \"borderLeft\": \"1px none #ffffff\", \"borderRight\": \"1px none #ffffff\", \"borderTop\": \"1px none #ffffff\", \"borderBottom\": \"1px none #ffffff\", \"paddingTop\": \"0px\", \"paddingBottom\": \"0px\", \"paddingLeft\": \"0px\", \"paddingRight\": \"0px\", \"cols\": [12]}, \"children\": [{\"id\": \"8cab9aa48\", \"type\": \"Column\", \"props\": {}, \"children\": [{\"id\": \"f4baab96e\", \"universalId\": \"eed20601-e227-4481-897b-42e4a1a9d37a\", \"universalName\": \"Auto-Logo-2025-12-03 14:44:01\", \"type\": \"Logo\", \"props\": {\"width\": \"120\", \"height\": \"120\", \"imgRatio\": 1, \"src\": \"https://cdn.smartpushedm.com/frontend/smart-push/staging/1741054956275/1758595834300_74d62ae6.png?width=120&height=120\", \"href\": \"https://smartpush4.myshoplinestg.com\", \"align\": \"center\", \"containerBackgroundColor\": \"transparent\", \"paddingLeft\": \"20px\", \"paddingRight\": \"20px\", \"paddingTop\": \"20px\", \"paddingBottom\": \"20px\", \"paddingCondition\": true, \"segmentTypeConfig\": 1}, \"children\": []}]}]}",
142
+ "subUniversalId": "9a1d1b16-7b48-4f9e-9dc9-f379efd746a5",
143
+ "type": 1,
144
+ "blockType": "Section",
145
+ "flowModal": ""
146
+ },
147
+ {
148
+ "universalId": "eed20601-e227-4481-897b-42e4a1a9d37a",
149
+ "universalName": "Auto-Logo-2025-12-03 14:44:01",
150
+ "schema": "{\"id\": \"f4baab96e\", \"universalId\": \"eed20601-e227-4481-897b-42e4a1a9d37a\", \"universalName\": \"Auto-Logo-2025-12-03 14:44:01\", \"type\": \"Logo\", \"props\": {\"width\": \"120\", \"height\": \"120\", \"imgRatio\": 1, \"src\": \"https://cdn.smartpushedm.com/frontend/smart-push/staging/1741054956275/1758595834300_74d62ae6.png?width=120&height=120\", \"href\": \"https://smartpush4.myshoplinestg.com\", \"align\": \"center\", \"containerBackgroundColor\": \"transparent\", \"paddingLeft\": \"20px\", \"paddingRight\": \"20px\", \"paddingTop\": \"20px\", \"paddingBottom\": \"20px\", \"paddingCondition\": true, \"segmentTypeConfig\": 1}, \"children\": []}",
151
+ "subUniversalId": "eed20601-e227-4481-897b-42e4a1a9d37a",
152
+ "type": 0,
153
+ "blockType": "Logo",
154
+ "flowModal": ""
155
+ }
156
+ ],
157
+ "type": 1
158
+ }
73
159
  :return:
74
160
  """
75
- requestParam = {
76
- "data": universal_list,
77
- "type": _type
78
- }
161
+ # block_type_list = []
162
+ # for data in universal_list:
163
+ # block_type_list.append(data['type'])
164
+ # if BlockType.Section.value in set(block_type_list):
165
+ # _type = BlockType.Section.value
166
+ # else:
167
+ # _type = BlockType.Block.value
168
+ requestParam = universal_list
79
169
  result = self.request(method=URL.UniversalContent.updateUniversalContent.method,
80
170
  path=URL.UniversalContent.updateUniversalContent.url,
81
171
  data=requestParam)
82
- # TODO 未完成
83
172
  return result
84
173
 
85
174
  # 删除universal
86
175
  def delete_universal(self, universalId):
87
176
  """
88
177
  删除素材
178
+ :param universalId:
89
179
  :param universa_id:
90
180
  :return:
91
181
  """
@@ -131,15 +221,17 @@ class UniversalContent(RequestBase):
131
221
  print(f"------收藏的block在该section({section_universa_name})中,断言成功------")
132
222
  except:
133
223
  raise
224
+
134
225
  @staticmethod
135
- def assert_universal_schema_is_update(schema, property='containerBackgroundColor', value ='#123456'):
226
+ def assert_universal_schema_is_update(schema, property='containerBackgroundColor', value='#123456'):
136
227
  """
137
228
  用于查找素材schema的属性是否更新成功
229
+ :param schema:
138
230
  :param property:
139
231
  :param value:
140
232
  :return:
141
233
  """
142
- _schema =schema if isinstance(schema,dict) else json.loads(schema)
234
+ _schema = schema if isinstance(schema, dict) else json.loads(schema)
143
235
  assert _schema['props'][property] == value
144
236
 
145
237
 
@@ -148,6 +240,11 @@ def get_time():
148
240
 
149
241
 
150
242
  def gen_universal_name(schema):
243
+ """
244
+ 生成素材名称
245
+ :param schema:
246
+ :return:
247
+ """
151
248
  schema = schema if isinstance(schema, dict) else schema.value
152
249
  if schema['type']:
153
250
  return 'Auto-' + schema['type'] + '-' + get_time()
@@ -156,77 +253,67 @@ def gen_universal_name(schema):
156
253
 
157
254
 
158
255
  def get_universal_schema(schema, _id, universalId, universalName):
256
+ """
257
+ 获取素材中的schema
258
+ :param schema:
259
+ :param _id:
260
+ :param universalId:
261
+ :param universalName:
262
+ :return:
263
+ """
159
264
  schema = schema if isinstance(schema, dict) else schema.value
160
265
  schema.update(id=_id, universalId=universalId, universalName=universalName)
161
266
  return schema
162
267
 
163
268
 
164
269
  if __name__ == '__main__':
165
- # _list = [get_universal_schema(BlockSchema.Logo, _id=generate_UUID(9), universalId=generate_UUID(),
166
- # universalName=gen_universal_name(BlockSchema.Logo))]
167
- # print(json.dumps(_list))
168
- # print(gen_universal_request_param(generate_UUID(),
169
- # get_universal_schema(genSection(_list), _id=generate_UUID(9),
170
- # universalId=generate_UUID(),
171
- # universalName=gen_universal_name(
172
- # BlockSchema.Section))))
173
270
  sectionUniversalId = generate_UUID()
174
271
  sectionUniversalName = gen_universal_name(BlockSchema.Section)
175
- print(sectionUniversalName)
176
- block_list = [BlockSchema.Logo]
177
- block_dict = {}
272
+ # print(sectionUniversalName)
273
+ block_list = [BlockSchema.Logo,BlockSchema.Discount]
274
+ # block_dict = {}
178
275
  result_list = []
179
- blockUniversalNameList = []
276
+ # update_request_param = []
277
+ # blockUniversalNameList = []
180
278
  for block in block_list:
181
279
  name = block.name
182
- block_schema = get_universal_schema(block, _id=generate_UUID(9), universalId=generate_UUID(),
280
+ universal_id = generate_UUID()
281
+ block_schema = get_universal_schema(block, _id=generate_UUID(9), universalId=universal_id,
183
282
  universalName=gen_universal_name(block))
283
+ block_request_param = gen_universal_request_param(universal_id, block_schema, jsonDumps=False)
184
284
  result_list.append(block_schema)
185
- print(result_list)
285
+ # update_request_param.append(block_request_param)
186
286
  section_schema = get_universal_schema(BlockSchema.genSection(result_list), _id=generate_UUID(9),
187
287
  universalId=sectionUniversalId,
188
288
  universalName=sectionUniversalName)
189
- universal_request_param = gen_universal_request_param(sectionUniversalId, section_schema)
190
- print(universal_request_param)
191
- head = {
192
- "cookie": "osudb_appid=SMARTPUSH;osudb_oar=#01#SID0000141BOhqtUqYGMjRho2SIPBeE5o1HNWFHo9q+qttt/jMLf+gRshde7x0NZUgAST4PB4CfSuAa450BCuCZf6pwolP1vXs/cF+6e/snBhESLvofXaxDaIFN9swZq4Np2xBc4uw6R4V58uWjrwg+s8XTLVv;osudb_subappid=1;osudb_uid=4213785247;ecom_http_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjU1OTg0NzQsImp0aSI6ImU0YzAyZjcxLWQ4NDktNDZlYS1iNzNmLTY1YjU0YTc3MTJjZCIsInVzZXJJbmZvIjp7ImlkIjowLCJ1c2VySWQiOiI0MjEzNzg1MjQ3IiwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImZlbGl4LnNoYW9Ac2hvcGxpbmVhcHAuY29tIiwidXNlclJvbGUiOiJvd25lciIsInBsYXRmb3JtVHlwZSI6Nywic3ViUGxhdGZvcm0iOjEsInBob25lIjoiIiwibGFuZ3VhZ2UiOiJ6aC1oYW5zLWNuIiwiYXV0aFR5cGUiOiIiLCJhdHRyaWJ1dGVzIjp7ImNvdW50cnlDb2RlIjoiQ04iLCJjdXJyZW5jeSI6IkpQWSIsImN1cnJlbmN5U3ltYm9sIjoiSlDCpSIsImRvbWFpbiI6InNtYXJ0cHVzaDQubXlzaG9wbGluZXN0Zy5jb20iLCJsYW5ndWFnZSI6ImVuIiwibWVyY2hhbnRFbWFpbCI6ImZlbGl4LnNoYW9Ac2hvcGxpbmUuY29tIiwibWVyY2hhbnROYW1lIjoiU21hcnRQdXNoNF9lYzJf6Ieq5Yqo5YyW5bqX6ZO6IiwicGhvbmUiOiIiLCJzY29wZUNoYW5nZWQiOmZhbHNlLCJzdGFmZkxhbmd1YWdlIjoiemgtaGFucy1jbiIsInN0YXR1cyI6MCwidGltZXpvbmUiOiJBc2lhL01hY2FvIn0sInN0b3JlSWQiOiIxNjQ0Mzk1OTIwNDQ0IiwiaGFuZGxlIjoic21hcnRwdXNoNCIsImVudiI6IkNOIiwic3RlIjoiIiwidmVyaWZ5IjoiIn0sImxvZ2luVGltZSI6MTc2MzAwNjQ3NDQzNywic2NvcGUiOlsiZW1haWwtbWFya2V0IiwiY29va2llIiwic2wtZWNvbS1lbWFpbC1tYXJrZXQtbmV3LXRlc3QiLCJlbWFpbC1tYXJrZXQtbmV3LWRldi1mcyIsImFwaS11Yy1lYzIiLCJhcGktc3UtZWMyIiwiYXBpLWVtLWVjMiIsImZsb3ctcGx1Z2luIiwiYXBpLXNwLW1hcmtldC1lYzIiXSwiY2xpZW50X2lkIjoiZW1haWwtbWFya2V0In0.erTiG4r364sutySNgx8X1rmrAjFsyfoe3UIUZ6J9e-o;",
193
- "Content-Type": "application/json", "accept-language": "zh-CN"}
194
- universal = UniversalContent(headers=head, host='https://test.smartpushedm.com/bff/api-sp-market-ec2')
195
- try:
196
- # universal.create_universal(requestParam=universal_request_param)
197
- # universal.assert_block_in_the_section(sectionUniversalName, result_list)
198
- _list =[
199
- {"universalId": "ec5d5278-4ed7-4933-8010-2b0c6a776356", "universalName": "Auto-Logo-2025-11-26 00:35:35",
200
- "schema": "{\"id\":\"96997bb0a\",\"universalId\":\"ec5d5278-4ed7-4933-8010-2b0c6a776356\",\"universalName\":\"Auto-Logo-2025-11-26 00:35:35\",\"type\":\"Logo\",\"props\":{\"width\":120,\"height\":120,\"imgRatio\":1,\"src\":\"https://cdn.smartpushedm.com/frontend/smart-push/staging/1741054956275/1758595834300_74d62ae6.png?width=120&height=120\",\"href\":\"https://smartpush4.myshoplinestg.com\",\"align\":\"center\",\"containerBackgroundColor\":\"#b46b6b\",\"paddingLeft\":\"20px\",\"paddingRight\":\"20px\",\"paddingTop\":\"20px\",\"paddingBottom\":\"20px\",\"paddingCondition\":\"true\",\"segmentTypeConfig\":1},\"children\":[]}",
201
- "subUniversalId": "ec5d5278-4ed7-4933-8010-2b0c6a776356", "type": 0, "blockType": "Logo",
202
- "flowModal": ""}]
203
- universal.update_universal(_list)
204
- except:
205
- raise
206
- finally:
207
- # universal.delete_universal(sectionUniversalId)
208
- # pass
209
- pass
210
- #
211
- # if __name__ == '__main__':
212
- # sectionUniversalId = generate_UUID()
213
- # sectionUniversalName = gen_universal_name(BlockSchema.Section)
214
- # print(sectionUniversalName)
215
- # block_list = [BlockSchema.Logo] # 添加block
289
+ # section_universal_request_param = gen_universal_request_param(sectionUniversalId, section_schema, jsonDumps=False)
290
+ #
291
+ # update_request_param.insert(0, section_universal_request_param)
292
+ # print("update_request_param:", update_request_param)
293
+ # print(result_list)
294
+ # print(section_schema)
295
+ print(gen_update_universal_param(result_list,section_schema))
296
+ # print("universal_request_param:", section_universal_request_param)
297
+ # head = {
298
+ # "cookie": "osudb_appid=SMARTPUSH;osudb_oar=#01#SID0000141BOhqtUqYGMjRho2SIPBeE5o1HNWFHo9q+qttt/jMLf+gRshde7x0NZUgAST4PB4CfSuAa450BCuCZf6pwolP1vXs/cF+6e/snBhESLvofXaxDaIFN9swZq4Np2xBc4uw6R4V58uWjrwg+s8XTLVv;osudb_subappid=1;osudb_uid=4213785247;ecom_http_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjU1OTg0NzQsImp0aSI6ImU0YzAyZjcxLWQ4NDktNDZlYS1iNzNmLTY1YjU0YTc3MTJjZCIsInVzZXJJbmZvIjp7ImlkIjowLCJ1c2VySWQiOiI0MjEzNzg1MjQ3IiwidXNlcm5hbWUiOiIiLCJlbWFpbCI6ImZlbGl4LnNoYW9Ac2hvcGxpbmVhcHAuY29tIiwidXNlclJvbGUiOiJvd25lciIsInBsYXRmb3JtVHlwZSI6Nywic3ViUGxhdGZvcm0iOjEsInBob25lIjoiIiwibGFuZ3VhZ2UiOiJ6aC1oYW5zLWNuIiwiYXV0aFR5cGUiOiIiLCJhdHRyaWJ1dGVzIjp7ImNvdW50cnlDb2RlIjoiQ04iLCJjdXJyZW5jeSI6IkpQWSIsImN1cnJlbmN5U3ltYm9sIjoiSlDCpSIsImRvbWFpbiI6InNtYXJ0cHVzaDQubXlzaG9wbGluZXN0Zy5jb20iLCJsYW5ndWFnZSI6ImVuIiwibWVyY2hhbnRFbWFpbCI6ImZlbGl4LnNoYW9Ac2hvcGxpbmUuY29tIiwibWVyY2hhbnROYW1lIjoiU21hcnRQdXNoNF9lYzJf6Ieq5Yqo5YyW5bqX6ZO6IiwicGhvbmUiOiIiLCJzY29wZUNoYW5nZWQiOmZhbHNlLCJzdGFmZkxhbmd1YWdlIjoiemgtaGFucy1jbiIsInN0YXR1cyI6MCwidGltZXpvbmUiOiJBc2lhL01hY2FvIn0sInN0b3JlSWQiOiIxNjQ0Mzk1OTIwNDQ0IiwiaGFuZGxlIjoic21hcnRwdXNoNCIsImVudiI6IkNOIiwic3RlIjoiIiwidmVyaWZ5IjoiIn0sImxvZ2luVGltZSI6MTc2MzAwNjQ3NDQzNywic2NvcGUiOlsiZW1haWwtbWFya2V0IiwiY29va2llIiwic2wtZWNvbS1lbWFpbC1tYXJrZXQtbmV3LXRlc3QiLCJlbWFpbC1tYXJrZXQtbmV3LWRldi1mcyIsImFwaS11Yy1lYzIiLCJhcGktc3UtZWMyIiwiYXBpLWVtLWVjMiIsImZsb3ctcGx1Z2luIiwiYXBpLXNwLW1hcmtldC1lYzIiXSwiY2xpZW50X2lkIjoiZW1haWwtbWFya2V0In0.erTiG4r364sutySNgx8X1rmrAjFsyfoe3UIUZ6J9e-o;",
299
+ # "Content-Type": "application/json", "accept-language": "zh-CN"}
300
+ # universal = UniversalContent(headers=head, host='https://test.smartpushedm.com/bff/api-sp-market-ec2')
301
+ # universal.update_universal(update_request_param)
302
+ #
303
+ # universal = UniversalContent(headers=head, host='https://test.smartpushedm.com/bff/api-sp-market-ec2')
304
+ # try:
305
+ # # universal.create_universal(requestParam=universal_request_param)
306
+ # # universal.assert_block_in_the_section(sectionUniversalName, result_list)
307
+ # _list =[
308
+ # {"universalId": "ec5d5278-4ed7-4933-8010-2b0c6a776356", "universalName": "Auto-Logo-2025-11-26 00:35:35",
309
+ # "schema": "{\"id\":\"96997bb0a\",\"universalId\":\"ec5d5278-4ed7-4933-8010-2b0c6a776356\",\"universalName\":\"Auto-Logo-2025-11-26 00:35:35\",\"type\":\"Logo\",\"props\":{\"width\":120,\"height\":120,\"imgRatio\":1,\"src\":\"https://cdn.smartpushedm.com/frontend/smart-push/staging/1741054956275/1758595834300_74d62ae6.png?width=120&height=120\",\"href\":\"https://smartpush4.myshoplinestg.com\",\"align\":\"center\",\"containerBackgroundColor\":\"#b46b6b\",\"paddingLeft\":\"20px\",\"paddingRight\":\"20px\",\"paddingTop\":\"20px\",\"paddingBottom\":\"20px\",\"paddingCondition\":\"true\",\"segmentTypeConfig\":1},\"children\":[]}",
310
+ # "subUniversalId": "ec5d5278-4ed7-4933-8010-2b0c6a776356", "type": 0, "blockType": "Logo",
311
+ # "flowModal": ""}]
312
+ # universal.update_universal(_list)
313
+ # except:
314
+ # raise
315
+ # finally:
316
+ # # universal.delete_universal(sectionUniversalId)
317
+ # # pass
318
+ # pass
216
319
  #
217
- # block_dict = {}
218
- # result_list = []
219
- # blockUniversalNameList = []
220
- # for block in block_list:
221
- # name = block.name
222
- # block_schema = get_universal_schema(block, _id=generate_UUID(9), universalId=generate_UUID(),
223
- # universalName=gen_universal_name(block))
224
- # result_list.append(block_schema)
225
- # print(result_list)
226
- # # vars['result_list'] = result_list
227
- # section_schema = get_universal_schema(BlockSchema.genSection(result_list), _id=generate_UUID(9),
228
- # universalId=sectionUniversalId,
229
- # universalName=sectionUniversalName)
230
- # universal_request_param = gen_universal_request_param(sectionUniversalId, section_schema)
231
- # vars['universal_request_param'] = universal_request_param
232
- # print(universal_request_param)
File without changes
@@ -0,0 +1,159 @@
1
+ import random
2
+
3
+ from smartpush.base.request_base import OpenApiRequestBase
4
+ from smartpush.base.url_enum import URL
5
+
6
+
7
+ class OpenApi(OpenApiRequestBase):
8
+ def __init__(self, event_id=None, *args, **kwargs):
9
+ """初始化OpenApi,支持传入event_id"""
10
+ super().__init__(*args, **kwargs) # 调用父类初始化
11
+ self.event_id = event_id # 初始化event_id属性
12
+ self.attrTypeList = ('STRING', 'BIGINT', 'BOOLEAN', 'DATE', 'DECIMAL')
13
+
14
+ def get_attribute_type(self, _type=None):
15
+ """
16
+ 返回一个数据类型('STRING', 'BIGINT', 'BOOLEAN', 'DATE', 'DECIMAL')
17
+ :param _type:
18
+ :return:
19
+ """
20
+
21
+ if _type is not None and _type in self.attrTypeList:
22
+ return _type
23
+ else:
24
+ return random.choice(self.attrTypeList)
25
+
26
+ def getEventMetaList(self, code=None, channel=None):
27
+ """
28
+ 获取EventMeta数据
29
+ :param code: 事件编码
30
+ :param channel: 渠道类型
31
+ :return: 请求结果
32
+ """
33
+ requestParam = {"pageModel": {"page": 1, "pageSize": 20}}
34
+ # 正确的参数更新逻辑:有值才更新
35
+ if channel:
36
+ requestParam["channel"] = channel
37
+ if code:
38
+ requestParam["code"] = code
39
+ result = self.request(
40
+ URL.OpenApi.getEventMetaList.url,
41
+ URL.OpenApi.getEventMetaList.method,
42
+ data=requestParam
43
+ )
44
+ return result
45
+
46
+ def getEventMetaById(self, eventCode):
47
+ """
48
+ 获取事件详情
49
+ :param eventCode: 事件编码
50
+ :return: 请求结果
51
+ """
52
+ if not self.event_id:
53
+ raise ValueError("event_id未初始化,请在实例化时传入")
54
+ requestParam = {"id": self.event_id, "eventCode": eventCode}
55
+ result = self.request(
56
+ URL.OpenApi.getEventMetaById.url,
57
+ URL.OpenApi.getEventMetaById.method,
58
+ data=requestParam
59
+ )
60
+ return result
61
+
62
+ def deleteEventMetaById(self, eventCode):
63
+ """
64
+ 删除事件(根据ID)
65
+ :param eventCode: 事件编码
66
+ :return: 请求结果
67
+ """
68
+ if not self.event_id:
69
+ raise ValueError("event_id未初始化,请在实例化时传入")
70
+ requestParam = {"id": self.event_id, "eventCode": eventCode}
71
+ result = self.request(
72
+ URL.OpenApi.delEventMetaById.url,
73
+ URL.OpenApi.delEventMetaById.method,
74
+ data=requestParam
75
+ )
76
+ return result
77
+
78
+ def editEventMeta(self, eventCode, eventName, eventChannel, channelMetaTabi, eventAttrs: list,
79
+ updateEventAttrs: list, deleteEventAttrs: list):
80
+ if not self.event_id:
81
+ raise ValueError("event_id未初始化,请在实例化时传入")
82
+ requestParam = {
83
+ "eventCode": eventCode,
84
+ "eventName": eventName,
85
+ "eventChannel": eventChannel,
86
+ "eventAttrs": eventAttrs,
87
+ "id": self.event_id,
88
+ "channel": {
89
+ "updateEventChannel": {
90
+ "channelMetaTabi": channelMetaTabi,
91
+ "channelCode": "eventChannel"
92
+ }
93
+ },
94
+ "attrs": {
95
+ "updateEventAttrs": updateEventAttrs,
96
+ "deleteEventAttrs": deleteEventAttrs
97
+ }
98
+ }
99
+ result = self.request(
100
+ URL.OpenApi.editEventMeta.url,
101
+ URL.OpenApi.editEventMeta.method,
102
+ data=requestParam
103
+ )
104
+ return result
105
+
106
+ def getEventChannel(self):
107
+ # requestParam = {"id": self.event_id, "eventCode": eventCode}
108
+ result = self.request(
109
+ URL.OpenApi.getEventChannel.url,
110
+ URL.OpenApi.getEventChannel.method,
111
+ )
112
+ return result
113
+
114
+ def getEventAttr(self):
115
+ result = self.request(
116
+ URL.OpenApi.getEventAttr.url,
117
+ URL.OpenApi.getEventAttr.method,
118
+ )
119
+ return result
120
+
121
+
122
+ class AssertOpenApi(OpenApi):
123
+ def assert_event_create_success(self, code, channel, is_delete=True) -> str:
124
+ """
125
+ 断言事件新增成功,并返回eventId
126
+ :param code: 事件编码
127
+ :param channel: 渠道类型
128
+ :param is_delete: 是否删除事件
129
+ :return: eventId
130
+ """
131
+ event_id = None
132
+ try:
133
+ result = self.getEventMetaList(code=code, channel=channel)
134
+ # 安全获取数据,避免KeyError
135
+ result_data = result.get("resultData", {})
136
+ datas = result_data.get("datas", [])
137
+
138
+ if not datas:
139
+ raise AssertionError(f"未找到事件:code={code}, channel={channel}")
140
+ matched_data = None
141
+ for data in datas:
142
+ if data.get("eventCode") == code and data.get("channelType") == channel:
143
+ matched_data = data
144
+ break
145
+ if not matched_data:
146
+ raise AssertionError(f"事件属性不匹配:code={code}, channel={channel}")
147
+
148
+ # 断言关键属性
149
+ assert matched_data.get("isMerchantEvent"), "isMerchantEvent应为True"
150
+ event_id = matched_data.get("eventId")
151
+ assert event_id, "eventId不存在"
152
+ return event_id
153
+
154
+ except Exception as e:
155
+ raise AssertionError(f"事件新增断言失败:{str(e)}") from e
156
+ finally:
157
+ if is_delete and event_id:
158
+ self.event_id = event_id
159
+ self.deleteEventMetaById(code)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: smartpush
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: 用于smartpush自动化测试工具包
5
5
  Author: lulu、felix、long
6
6
 
@@ -5,14 +5,14 @@ smartpush/account/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
5
5
  smartpush/account/operate_account.py,sha256=nzJLLAEwNElavZeWVqnA_MSGTBzQrSrknmezYBwtvWs,1525
6
6
  smartpush/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  smartpush/base/faker_data.py,sha256=-OcFFQnDGpjZR3guo_tHfxV7zQEHo9ciidWGqKv_jNs,25437
8
- smartpush/base/request_base.py,sha256=jQRnURl9-BA5BnymjyD5auqFc256CtmepM_woFVkE6g,2754
9
- smartpush/base/url_enum.py,sha256=TVNCSB23DdervtVpGG0LeVVNkGbZ3Ks6DxEbAqRKfjw,2320
8
+ smartpush/base/request_base.py,sha256=hP5uhCwOMlCgwKjyh1PhJ5fCmWY-8LowZdW97r5cm_0,2938
9
+ smartpush/base/url_enum.py,sha256=OuEd3EqlLvKiYesU2gISPLh9wH2nNYZ-5nzBu_6Zxnw,2748
10
10
  smartpush/crowd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  smartpush/crowd/crowd.py,sha256=KNwvX-BnBnMVVuHM79a-VeBMp_guB-Kqw3tFaAPiAp8,9768
12
12
  smartpush/email/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- smartpush/email/activity.py,sha256=Uogpx0oe0FBw4-SUTc6i1IjOeUql5JcYgDH0Niwz56g,10104
14
- smartpush/email/schema.py,sha256=Uef41D0Z_xw07khOyLiJhjfZ9GVE0urN0tG8orQjIfY,31220
15
- smartpush/email/universal_content.py,sha256=0VaY_-2--AofdJBuRrOClDXZqn-tCU_FOxSPY-GIRIk,11954
13
+ smartpush/email/activity.py,sha256=rQ62GIfg0Yh0fFkwiaRIVATBn5vY1wZzbLEJLwHmx1E,10016
14
+ smartpush/email/schema.py,sha256=mysik-N6cry4HuSxzMMhQFsnnu5_UJ_oqVPTGY1RUkQ,31471
15
+ smartpush/email/universal_content.py,sha256=bST0RCVN4YUglrsCv0OsIox7vceEvJRVkqcMaEgj9No,17226
16
16
  smartpush/export/__init__.py,sha256=D9GbWcmwnetEndFDty5XbVienFK1WjqV2yYcQp3CM84,99
17
17
  smartpush/export/basic/ExcelExportChecker.py,sha256=YqWmDGSFadQdK2vNJ070Qvad9ZtqEwiQyPkOemlACfs,21508
18
18
  smartpush/export/basic/GetOssUrl.py,sha256=zxNZj6x7Ph9N3P5k82pLpBFjZxKrDfbgqS2fTYyhvso,8467
@@ -27,6 +27,8 @@ smartpush/form/form_after.py,sha256=KHatgVQvOiCykbfXm5TD07gvGvMgQYqQIQkcIKkAnQU,
27
27
  smartpush/form/form_assert.py,sha256=wPIRfQHhr7lN1fFd-mp0z_qKMtF4jfrNxRWvp2xfqCg,257
28
28
  smartpush/form/form_before.py,sha256=CCvAC_2yWPlnQGtjEA8LPLy9853Nq3nNjcL2GewFWIs,175
29
29
  smartpush/form/form_client_operation.py,sha256=gg-5uHXCyMa_ypBSYPYFVxXdwZdYBJsNtUCqayknMBw,303
30
+ smartpush/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ smartpush/openapi/openapi.py,sha256=SFZ4HHjHgEQ5HVZu6-r_97C_dhRe6M8McrgaqGjEG5g,5558
30
32
  smartpush/utils/DataTypeUtils.py,sha256=BC7ioztO3vAfKd1EOoNvXdVuXYY8qjNskV1DP7LhW-M,1082
31
33
  smartpush/utils/EmailUtlis.py,sha256=DAHd73bJ8hiJCLEXtD0xcwxPD7SOPSmBB7Jvlf6gN6s,11201
32
34
  smartpush/utils/ListDictUtils.py,sha256=Xc8kfSOZjX_k026Au4cfvtgFh5WoHxw4yRJWASyA_Cc,5041
@@ -34,7 +36,7 @@ smartpush/utils/StringUtils.py,sha256=n8mo9k0JQN63MReImgv-66JxmmymOGknR8pH2fkQrA
34
36
  smartpush/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
37
  smartpush/utils/date_utils.py,sha256=Xgx2DbmWYri71xXBiaKYTZDeh2a8MFhYns_xB0U2JOA,13159
36
38
  smartpush/utils/form_utils.py,sha256=ld-g_Dm_ZlnagQt7imYfUc87bcBRVlTctywuLtzmjXQ,849
37
- smartpush-2.0.5.dist-info/METADATA,sha256=Ng2o6uXjxL0bifLufabbjQrrRxYUCZDmr-7qsLcHJ4Q,131
38
- smartpush-2.0.5.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
39
- smartpush-2.0.5.dist-info/top_level.txt,sha256=5_CXqu08EfbPaKLjuSAOAqCmGU6shiatwDU_ViBGCmg,10
40
- smartpush-2.0.5.dist-info/RECORD,,
39
+ smartpush-2.0.7.dist-info/METADATA,sha256=O5ZwtC49PI2pCh1dafsPRTGR13CSgWKGlJHMnmQdL5Y,131
40
+ smartpush-2.0.7.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
41
+ smartpush-2.0.7.dist-info/top_level.txt,sha256=5_CXqu08EfbPaKLjuSAOAqCmGU6shiatwDU_ViBGCmg,10
42
+ smartpush-2.0.7.dist-info/RECORD,,