PipeGraphPy 2.0.6__py3-none-win_amd64.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.
- PipeGraphPy/__init__.py +10 -0
- PipeGraphPy/common.py +4 -0
- PipeGraphPy/config/__init__.py +276 -0
- PipeGraphPy/config/custom.py +6 -0
- PipeGraphPy/config/default_settings.py +125 -0
- PipeGraphPy/constants.py +421 -0
- PipeGraphPy/core/__init__.py +2 -0
- PipeGraphPy/core/anchor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/edge.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/graph.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/graph_base.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/__init__.py +3 -0
- PipeGraphPy/core/modcls/base.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/branchselect.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/classifier.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/cluster.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/datacharts.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/deeplearning.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/endscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/ensemble.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/evaluate.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/exportdata.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/handlescript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/importdata.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/merge.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/mergescript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/metrics.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/postprocessor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/preprocessor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/pythonscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/regressor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/selector.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/selectscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/special.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/split.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/splitscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/startscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/transformer.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/module.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modules/__init__.py +65 -0
- PipeGraphPy/core/modules/classifier/__init__.py +2 -0
- PipeGraphPy/core/modules/cluster/__init__.py +0 -0
- PipeGraphPy/core/modules/custom/__init__.py +0 -0
- PipeGraphPy/core/modules/custom/classifier/__init__.py +0 -0
- PipeGraphPy/core/modules/datacharts/__init__.py +5 -0
- PipeGraphPy/core/modules/datacharts/dataview.py +28 -0
- PipeGraphPy/core/modules/deeplearning/__init__.py +0 -0
- PipeGraphPy/core/modules/ensemble/__init__.py +0 -0
- PipeGraphPy/core/modules/evaluate/__init__.py +0 -0
- PipeGraphPy/core/modules/exportdata/__init__.py +0 -0
- PipeGraphPy/core/modules/importdata/__init__.py +0 -0
- PipeGraphPy/core/modules/merge/__init__.py +0 -0
- PipeGraphPy/core/modules/model_selector/__init__.py +3 -0
- PipeGraphPy/core/modules/postprocessor/__init__.py +0 -0
- PipeGraphPy/core/modules/preprocessor/__init__.py +0 -0
- PipeGraphPy/core/modules/pythonscript/__init__.py +0 -0
- PipeGraphPy/core/modules/regressor/__init__.py +0 -0
- PipeGraphPy/core/modules/selector/__init__.py +0 -0
- PipeGraphPy/core/modules/special/__init__.py +0 -0
- PipeGraphPy/core/modules/split/__init__.py +0 -0
- PipeGraphPy/core/modules/transformer/__init__.py +0 -0
- PipeGraphPy/core/node.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/pipegraph.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/db/__init__.py +2 -0
- PipeGraphPy/db/models.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/db/utils.py +106 -0
- PipeGraphPy/decorators.py +42 -0
- PipeGraphPy/logger.py +170 -0
- PipeGraphPy/plot/__init__.py +0 -0
- PipeGraphPy/plot/draw.py +424 -0
- PipeGraphPy/storage/__init__.py +10 -0
- PipeGraphPy/storage/base.py +2 -0
- PipeGraphPy/storage/dict_backend.py +102 -0
- PipeGraphPy/storage/file_backend.py +342 -0
- PipeGraphPy/storage/redis_backend.py +183 -0
- PipeGraphPy/tools.py +388 -0
- PipeGraphPy/utils/__init__.py +1 -0
- PipeGraphPy/utils/check.py +179 -0
- PipeGraphPy/utils/core.py +295 -0
- PipeGraphPy/utils/examine.py +259 -0
- PipeGraphPy/utils/file_operate.py +101 -0
- PipeGraphPy/utils/format.py +303 -0
- PipeGraphPy/utils/functional.py +422 -0
- PipeGraphPy/utils/handle_graph.py +31 -0
- PipeGraphPy/utils/lock.py +1 -0
- PipeGraphPy/utils/mq.py +54 -0
- PipeGraphPy/utils/osutil.py +29 -0
- PipeGraphPy/utils/redis_operate.py +195 -0
- PipeGraphPy/utils/str_handle.py +122 -0
- PipeGraphPy/utils/version.py +108 -0
- PipeGraphPy-2.0.6.dist-info/METADATA +17 -0
- PipeGraphPy-2.0.6.dist-info/RECORD +94 -0
- PipeGraphPy-2.0.6.dist-info/WHEEL +5 -0
- PipeGraphPy-2.0.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# coding:utf-8
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import json
|
|
5
|
+
import copy
|
|
6
|
+
import datetime
|
|
7
|
+
import pandas as pd
|
|
8
|
+
from decimal import Decimal
|
|
9
|
+
from PipeGraphPy.constants import GRAPH_DICT_FORMAT
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def replace_json(data):
|
|
13
|
+
"""替换json数据
|
|
14
|
+
|
|
15
|
+
Example: >>> data = u'[{"rid": "46", "cap": "30000", \
|
|
16
|
+
"nwp_config": {"GFS": "001"}, "layer": "70"}, \
|
|
17
|
+
{"rid": "46", "cap": "30000", \
|
|
18
|
+
"nwp_config": {"GFS": "001"}, "layer": "70"}]'
|
|
19
|
+
>>> replace_json(data)
|
|
20
|
+
|
|
21
|
+
Return: >>>
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
for k, v in data.items():
|
|
25
|
+
try:
|
|
26
|
+
row = json.loads(v)
|
|
27
|
+
data[k] = row
|
|
28
|
+
except Exception:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
return data
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def binary_to_utf8(data):
|
|
35
|
+
"""
|
|
36
|
+
二进制编码转成utf-8编码
|
|
37
|
+
>>> binary_to_utf8(b'example')
|
|
38
|
+
'example'
|
|
39
|
+
>>> binary_to_utf8([b'aa', b'bb', b'cc'])
|
|
40
|
+
['aa', 'bb', 'cc']
|
|
41
|
+
"""
|
|
42
|
+
if isinstance(data, list):
|
|
43
|
+
return [binary_to_utf8(i) for i in data]
|
|
44
|
+
else:
|
|
45
|
+
try:
|
|
46
|
+
return str(data, 'utf-8')
|
|
47
|
+
except Exception:
|
|
48
|
+
return data
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def filter_keys(data, keys):
|
|
52
|
+
"""
|
|
53
|
+
字典过滤keys
|
|
54
|
+
"""
|
|
55
|
+
if isinstance(data, list):
|
|
56
|
+
return [filter_keys(i, keys) for i in data]
|
|
57
|
+
elif isinstance(data, dict):
|
|
58
|
+
return {k: v for k, v in data.items() if k in keys}
|
|
59
|
+
else:
|
|
60
|
+
return data
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def filter_keys_pass(data, keys):
|
|
64
|
+
"""
|
|
65
|
+
字典过滤掉keys
|
|
66
|
+
"""
|
|
67
|
+
if isinstance(data, list):
|
|
68
|
+
return [filter_keys_pass(i, keys) for i in data]
|
|
69
|
+
elif isinstance(data, dict):
|
|
70
|
+
return {k: v for k, v in data.items() if k not in keys}
|
|
71
|
+
else:
|
|
72
|
+
return data
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# LOG = logging.getLogger('ATP.WebApi')
|
|
76
|
+
#
|
|
77
|
+
# def log(func):
|
|
78
|
+
# """log wrapper"""
|
|
79
|
+
# def wrapper(*args, **kw):
|
|
80
|
+
# try:
|
|
81
|
+
# res = func(*args, **kw)
|
|
82
|
+
# return res
|
|
83
|
+
# except Exception as e:
|
|
84
|
+
# errInfo = '(%s),详细错误:%s'%(func.__name__, e)
|
|
85
|
+
# err_msg = '%s --- 错误代码 --- %s'%(errInfo, traceback.format_exc())
|
|
86
|
+
# LOG.error(err_msg)
|
|
87
|
+
# return json.dumps({'message':'接口异常请联系管理员', 'status':0})
|
|
88
|
+
# return wrapper
|
|
89
|
+
#
|
|
90
|
+
# def sql_filter(sql, max_length=1000):
|
|
91
|
+
# dirty_stuff = ["select", "delete", "update", "insert"]
|
|
92
|
+
# for stuff in dirty_stuff:
|
|
93
|
+
# sql = sql.replace(stuff, "")
|
|
94
|
+
# return sql[:max_length]
|
|
95
|
+
|
|
96
|
+
def pretty_data(obj):
|
|
97
|
+
'''转换数据'''
|
|
98
|
+
if isinstance(obj, float):
|
|
99
|
+
return round(obj, 4)
|
|
100
|
+
elif isinstance(obj, datetime.datetime):
|
|
101
|
+
return obj.strftime('%Y-%m-%d %H:%M:%S')
|
|
102
|
+
elif isinstance(obj, Decimal):
|
|
103
|
+
return round(float(obj), 4)
|
|
104
|
+
elif isinstance(obj, datetime.date):
|
|
105
|
+
return obj.strftime("%Y-%m-%d")
|
|
106
|
+
elif isinstance(obj, dict):
|
|
107
|
+
return dict((pretty_data(k), pretty_data(v)) for k, v in obj.items())
|
|
108
|
+
elif isinstance(obj, (list, tuple)):
|
|
109
|
+
return [pretty_data(i) for i in obj]
|
|
110
|
+
return obj
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def format_response(data, index_as_column=False):
|
|
114
|
+
'''格式化rpc和http返回数据, DataFrame转dict'''
|
|
115
|
+
if isinstance(data, pd.DataFrame):
|
|
116
|
+
data = data.where(pd.notnull(data), None)
|
|
117
|
+
if index_as_column:
|
|
118
|
+
data = data.reset_index()
|
|
119
|
+
data = data.to_dict(orient='index')
|
|
120
|
+
return pretty_data(data)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def is_valid_foldername(foldername):
|
|
124
|
+
# 文件夹名长度限制(根据操作系统的不同,最大长度可能会有所不同)
|
|
125
|
+
if len(foldername) > 255:
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
# 不能包含中文
|
|
129
|
+
if re.search(r'[\u4e00-\u9fff]+', foldername):
|
|
130
|
+
return False
|
|
131
|
+
|
|
132
|
+
# 无效字符:在Windows中,文件夹名不能包含以下字符
|
|
133
|
+
invalid_chars = r'[<>:"/\\|?*\x00-\x1F]'
|
|
134
|
+
if re.search(invalid_chars, foldername):
|
|
135
|
+
return False
|
|
136
|
+
|
|
137
|
+
# 不能存在空格
|
|
138
|
+
if foldername.find(" ") != -1:
|
|
139
|
+
return False
|
|
140
|
+
|
|
141
|
+
# 检查是否以空格、点或其他不符合规范的字符开头或结尾
|
|
142
|
+
if foldername.startswith(" ") or foldername.endswith(" ") or foldername.startswith(".") or foldername.endswith("."):
|
|
143
|
+
return False
|
|
144
|
+
|
|
145
|
+
return True
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def verify_graph_dict_format(kw:dict):
|
|
149
|
+
assert isinstance(kw, dict), Exception("模型只接收dict类型构建")
|
|
150
|
+
value_local = ["kw"]
|
|
151
|
+
def verify_one(key:str, rule:dict, v_kw:dict):
|
|
152
|
+
if not rule:
|
|
153
|
+
if v_kw.get(key):
|
|
154
|
+
return {key:k_kw[key]}
|
|
155
|
+
else:
|
|
156
|
+
return None
|
|
157
|
+
nonlocal value_local
|
|
158
|
+
verify_kw = {}
|
|
159
|
+
|
|
160
|
+
# 别名取值
|
|
161
|
+
real_key = key
|
|
162
|
+
value = None
|
|
163
|
+
keys = [key, rule["alias"]] if rule.get("alias") else [key]
|
|
164
|
+
for k in keys:
|
|
165
|
+
if v_kw.get(k) is not None:
|
|
166
|
+
real_key = k
|
|
167
|
+
value = v_kw[k]
|
|
168
|
+
|
|
169
|
+
value_local.append("['%s']" % real_key)
|
|
170
|
+
local_str = "".join(value_local)
|
|
171
|
+
dest_key = rule.get("dest") or real_key
|
|
172
|
+
|
|
173
|
+
# 判断必传
|
|
174
|
+
if rule.get("required"):
|
|
175
|
+
if value is None:
|
|
176
|
+
raise Exception("必传值%s不存在" % local_str)
|
|
177
|
+
|
|
178
|
+
# 没有值就直接返回,不再继续验证,存在值则继续验证
|
|
179
|
+
if value is None:
|
|
180
|
+
if rule.get("default") is not None:
|
|
181
|
+
verify_kw[dest_key] = rule["default"]
|
|
182
|
+
elif rule.get("fillnone") is not None:
|
|
183
|
+
verify_kw[dest_key] = v_kw.get(rule["fillnone"])
|
|
184
|
+
else:
|
|
185
|
+
value_local.pop()
|
|
186
|
+
return None
|
|
187
|
+
else:
|
|
188
|
+
if rule.get("type"):
|
|
189
|
+
if not isinstance(value, rule["type"]):
|
|
190
|
+
raise Exception("传值%s类型错误, 应该是%s" % (local_str, str(rule["type"])))
|
|
191
|
+
|
|
192
|
+
if rule.get("type") == list:
|
|
193
|
+
verify_kw[dest_key] = list()
|
|
194
|
+
if rule["elements"].get("required"):
|
|
195
|
+
if not value:
|
|
196
|
+
raise Exception("传值%s列表不能为空" % local_str)
|
|
197
|
+
for n, el in enumerate(value):
|
|
198
|
+
value_local.append("[%s]" % n)
|
|
199
|
+
local_str = "".join(value_local)
|
|
200
|
+
# 验证类型
|
|
201
|
+
if rule["elements"].get("type"):
|
|
202
|
+
if not isinstance(el, rule["elements"]["type"]):
|
|
203
|
+
raise Exception("传值%s类型错误, 应该是%s" % (
|
|
204
|
+
local_str, rule["elements"]["type"]))
|
|
205
|
+
if rule["elements"].get("type") == dict:
|
|
206
|
+
verify_el = {}
|
|
207
|
+
for k, v in rule["elements"]["elements"].items():
|
|
208
|
+
verify_res = verify_one(k,v,el)
|
|
209
|
+
if verify_res:
|
|
210
|
+
verify_el.update(verify_res)
|
|
211
|
+
verify_kw[dest_key].append(verify_el)
|
|
212
|
+
else:
|
|
213
|
+
verify_kw[dest_key].append(value)
|
|
214
|
+
value_local.pop()
|
|
215
|
+
elif rule.get("type") == dict:
|
|
216
|
+
verify_kw[dest_key] = dict()
|
|
217
|
+
if rule.get("elements"):
|
|
218
|
+
for k, v in rule["elements"].items():
|
|
219
|
+
verify_res = verify_one(k,v,value)
|
|
220
|
+
if verify_res:
|
|
221
|
+
verify_kw[dest_key].update(verify_res)
|
|
222
|
+
else:
|
|
223
|
+
verify_kw[dest_key] = value
|
|
224
|
+
else:
|
|
225
|
+
verify_kw[dest_key] = value
|
|
226
|
+
|
|
227
|
+
value_local.pop()
|
|
228
|
+
return verify_kw
|
|
229
|
+
|
|
230
|
+
verify_dict = {}
|
|
231
|
+
for k, v in GRAPH_DICT_FORMAT.items():
|
|
232
|
+
verify_res = verify_one(k, v, kw)
|
|
233
|
+
if verify_res is not None:
|
|
234
|
+
verify_dict.update(verify_res)
|
|
235
|
+
|
|
236
|
+
# # 验证模型id不能重复
|
|
237
|
+
# graph_ids = [i["id"] for i in verify_dict["graphs"]]
|
|
238
|
+
# if len(set(graph_ids)) < len(verify_dict["graphs"]):
|
|
239
|
+
# raise Exception("模型id存在重复")
|
|
240
|
+
|
|
241
|
+
# 验证节点id不能重复
|
|
242
|
+
# for g in verify_dict["graphs"]:
|
|
243
|
+
# node_ids = [i["id"] for i in g["nodes"]]
|
|
244
|
+
# if len(set(node_ids)) < len(g["nodes"]):
|
|
245
|
+
# raise Exception("模型%s的节点id存在重复" % g["id"])
|
|
246
|
+
# # 验证边的id都在节点id里面
|
|
247
|
+
# edge_node_ids = []
|
|
248
|
+
# edge_node_ids.extend([i["source_id"] for i in g["edges"]])
|
|
249
|
+
# edge_node_ids.extend([i["target_id"] for i in g["edges"]])
|
|
250
|
+
# outoff_node_ids = set(edge_node_ids) - set(node_ids)
|
|
251
|
+
# if outoff_node_ids:
|
|
252
|
+
# raise Exception("模型%s的edges配置的%s在nodes里未找到" % (g["id"], outoff_node_ids))
|
|
253
|
+
|
|
254
|
+
# 验证模型id是否符合命名规范
|
|
255
|
+
if not is_valid_foldername(verify_dict["id"]):
|
|
256
|
+
raise Exception("模型id:(%s) 不符合命名规范" % verify_dict["id"])
|
|
257
|
+
|
|
258
|
+
# 验证节点id不能重复
|
|
259
|
+
node_ids = [i["id"] for i in verify_dict["nodes"]]
|
|
260
|
+
if len(set(node_ids)) < len(verify_dict["nodes"]):
|
|
261
|
+
raise Exception("模型%s的节点id存在重复" % verify_dict["id"])
|
|
262
|
+
# 验证边的id都在节点id里面
|
|
263
|
+
edge_node_ids = []
|
|
264
|
+
edge_node_ids.extend([i["source_id"] for i in verify_dict["edges"]])
|
|
265
|
+
edge_node_ids.extend([i["target_id"] for i in verify_dict["edges"]])
|
|
266
|
+
outoff_node_ids = set(edge_node_ids) - set(node_ids)
|
|
267
|
+
if outoff_node_ids:
|
|
268
|
+
raise Exception("模型%s的edges配置的%s在nodes里未找到" % (verify_dict["id"], outoff_node_ids))
|
|
269
|
+
|
|
270
|
+
# 验证节点id是否符合命名规范
|
|
271
|
+
for i in verify_dict["nodes"]:
|
|
272
|
+
if not is_valid_foldername(i["id"]):
|
|
273
|
+
raise Exception("节点id: (%s) 不符合命名规范" % i["id"])
|
|
274
|
+
|
|
275
|
+
# 验证建模对象的id不能重复
|
|
276
|
+
object_ids = [i["id"] for i in verify_dict["object_infos"]]
|
|
277
|
+
if len(set(object_ids)) < len(verify_dict["object_infos"]):
|
|
278
|
+
raise Exception("模型对象id存在重复")
|
|
279
|
+
|
|
280
|
+
# 验证建模对象是否符合命名规范
|
|
281
|
+
for i in verify_dict["object_infos"]:
|
|
282
|
+
if not is_valid_foldername(i["id"]):
|
|
283
|
+
raise Exception("建模对象id: (%s) 不符合命名规范" % i["id"])
|
|
284
|
+
|
|
285
|
+
# 验证执行器的id都在模型id内
|
|
286
|
+
# actuator_graph_ids = []
|
|
287
|
+
# actuator_graph_ids.extend([i["source_graph_id"] for i in verify_dict["actuator"]])
|
|
288
|
+
# actuator_graph_ids.extend([i["target_graph_id"] for i in verify_dict["actuator"]])
|
|
289
|
+
# outoff_graph_ids = set(actuator_graph_ids) - set(graph_ids)
|
|
290
|
+
# if outoff_graph_ids:
|
|
291
|
+
# raise Exception("actuator里配置的%s在graphs里未找到" % outoff_graph_ids)
|
|
292
|
+
|
|
293
|
+
return verify_dict
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
if __name__ == '__main__':
|
|
297
|
+
data = {'algo_param': u'{"C":10, "gamma":20}',
|
|
298
|
+
'region': u'[{"rid": "46", "cap": "30000", "nwp_config": \
|
|
299
|
+
{"GFS": "001"}, "layer": "70"}, {"rid": "46", "cap": \
|
|
300
|
+
"30000", "nwp_config": {"GFS": "001"}, "layer": "70"}]'}
|
|
301
|
+
replace_json(data)
|
|
302
|
+
|
|
303
|
+
|