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
PipeGraphPy/db/utils.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import traceback
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
|
+
from PipeGraphPy.db.models import GraphsTB, NodesTB, ObjectsTB
|
|
5
|
+
from dbpoolpy import connect_db
|
|
6
|
+
from PipeGraphPy.logger import log
|
|
7
|
+
from PipeGraphPy.constants import BIZ_TYPE, STATUS, DB
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def update_node_params(node_ids, key, value, value_key="value"):
|
|
11
|
+
"""更新节点的params字段信息
|
|
12
|
+
parametes:
|
|
13
|
+
node_ids: list or int 要更新节点的id
|
|
14
|
+
key: str 要更新的键
|
|
15
|
+
value: str 要更新的值
|
|
16
|
+
"""
|
|
17
|
+
if isinstance(node_ids, int):
|
|
18
|
+
node_ids = [node_ids]
|
|
19
|
+
elif isinstance(node_ids, list):
|
|
20
|
+
node_ids = node_ids
|
|
21
|
+
else:
|
|
22
|
+
raise Exception("update_node_params函数node_ids字段传值类型不合法")
|
|
23
|
+
for node_id in node_ids:
|
|
24
|
+
node_info = NodesTB.find_one(id=node_id)
|
|
25
|
+
node_params = json.loads(node_info["params"])
|
|
26
|
+
for i in node_params:
|
|
27
|
+
if i["key"] == key:
|
|
28
|
+
i[value_key] = value
|
|
29
|
+
break
|
|
30
|
+
NodesTB.set(params=json.dumps(node_params)).where(id=node_id)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def insert_batch(dbserver, table, datas, num=2000):
|
|
34
|
+
try:
|
|
35
|
+
cnt = 0
|
|
36
|
+
with connect_db(dbserver) as db:
|
|
37
|
+
while len(datas) > cnt:
|
|
38
|
+
ceil_list = datas[cnt : cnt + num]
|
|
39
|
+
db.insert(table).many(ceil_list).execute()
|
|
40
|
+
cnt += num
|
|
41
|
+
except Exception:
|
|
42
|
+
log.error(traceback.format_exc())
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def df_to_db(dbserver, table, df):
|
|
46
|
+
if df.empty:
|
|
47
|
+
return
|
|
48
|
+
datas = df.to_dict(orient="records")
|
|
49
|
+
insert_batch(dbserver, table, datas)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_object_info(object_id):
|
|
53
|
+
"""获取业务信息
|
|
54
|
+
参数:
|
|
55
|
+
object_id:业务id
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
object_info = ObjectsTB.find_one(id=object_id)
|
|
59
|
+
if object_info:
|
|
60
|
+
if object_info.get("ext_json"):
|
|
61
|
+
try:
|
|
62
|
+
ext_params = json.loads(object_info["ext_json"])
|
|
63
|
+
object_info.update(ext_params)
|
|
64
|
+
except:
|
|
65
|
+
ext_params = {}
|
|
66
|
+
else:
|
|
67
|
+
object_info = {"id": object_id}
|
|
68
|
+
return object_info
|
|
69
|
+
except Exception as e:
|
|
70
|
+
print(traceback.format_exc())
|
|
71
|
+
return {"id": object_id}
|
|
72
|
+
|
|
73
|
+
def graphs_wait_to_run(graph_ids):
|
|
74
|
+
"""模型进入训练队列"""
|
|
75
|
+
if graph_ids:
|
|
76
|
+
running_ids = GraphsTB.map("id").where(
|
|
77
|
+
status=("in", [STATUS.RUNNING, STATUS.WAITRUN]),
|
|
78
|
+
id=("in",graph_ids))
|
|
79
|
+
if running_ids:
|
|
80
|
+
graph_ids = list(set(graph_ids) - set(running_ids))
|
|
81
|
+
if graph_ids:
|
|
82
|
+
now = (datetime.utcnow()+timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")
|
|
83
|
+
GraphsTB.set(
|
|
84
|
+
status=STATUS.WAITRUN,
|
|
85
|
+
wait_run_time=now,
|
|
86
|
+
task_id=''
|
|
87
|
+
).where(id=("in", graph_ids))
|
|
88
|
+
|
|
89
|
+
def graphs_wait_to_predict(graph_ids, clock="12", is_pub=False, **kwargs):
|
|
90
|
+
"""模型进入预测队列"""
|
|
91
|
+
params = {"clock": clock, "is_pub": is_pub}
|
|
92
|
+
if kwargs:
|
|
93
|
+
params.update(kwargs)
|
|
94
|
+
if graph_ids:
|
|
95
|
+
predicting_ids = GraphsTB.map("id").where(
|
|
96
|
+
p_status=("in", [STATUS.RUNNING, STATUS.WAITRUN]),
|
|
97
|
+
id=("in",graph_ids))
|
|
98
|
+
if predicting_ids:
|
|
99
|
+
graph_ids = list(set(graph_ids) - set(predicting_ids))
|
|
100
|
+
if graph_ids:
|
|
101
|
+
now = (datetime.utcnow()+timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")
|
|
102
|
+
GraphsTB.set(
|
|
103
|
+
p_status=STATUS.WAITRUN,
|
|
104
|
+
predict_params=json.dumps(params),
|
|
105
|
+
wait_predict_time=now,
|
|
106
|
+
).where(id=("in", graph_ids))
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class _Missing(object):
|
|
6
|
+
def __repr__(self):
|
|
7
|
+
return "no value"
|
|
8
|
+
|
|
9
|
+
def __reduce__(self):
|
|
10
|
+
return "_missing"
|
|
11
|
+
|
|
12
|
+
_missing = _Missing()
|
|
13
|
+
|
|
14
|
+
class cached_property(property):
|
|
15
|
+
"""将函数转换为惰性属性的装饰器。包装的函数在第一次使用结果时被调用,
|
|
16
|
+
然后在下次访问该值时使用该计算缓存的结果:
|
|
17
|
+
|
|
18
|
+
class Foo(object):
|
|
19
|
+
|
|
20
|
+
@cached_property
|
|
21
|
+
def foo(self):
|
|
22
|
+
# calculate something important here
|
|
23
|
+
return 42
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, func, name=None, doc=None):
|
|
27
|
+
self.__name__ = name or func.__name__
|
|
28
|
+
self.__module__ = func.__module__
|
|
29
|
+
self.__doc__ = doc or func.__doc__
|
|
30
|
+
self.func = func
|
|
31
|
+
|
|
32
|
+
def __set__(self, obj, value):
|
|
33
|
+
obj.__dict__[self.__name__] = value
|
|
34
|
+
|
|
35
|
+
def __get__(self, obj, type=None):
|
|
36
|
+
if obj is None:
|
|
37
|
+
return self
|
|
38
|
+
value = obj.__dict__.get(self.__name__, _missing)
|
|
39
|
+
if value is _missing:
|
|
40
|
+
value = self.func(obj)
|
|
41
|
+
obj.__dict__[self.__name__] = value
|
|
42
|
+
return value
|
PipeGraphPy/logger.py
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
import re
|
|
5
|
+
import logging
|
|
6
|
+
import logging, logging.config
|
|
7
|
+
from logging.handlers import TimedRotatingFileHandler
|
|
8
|
+
from PipeGraphPy.config import settings
|
|
9
|
+
from PipeGraphPy.db.models import PredictRecordTB, OnlineGraphsPredictRecordTB, RunRecordTB, BacktestRecordTB, EvaluateRecordTB, OnlineGraphsEvaluateRecordTB
|
|
10
|
+
|
|
11
|
+
class RecordHandler(logging.Handler, object):
|
|
12
|
+
"""
|
|
13
|
+
自定义日志handler
|
|
14
|
+
"""
|
|
15
|
+
def __init__(self, name, other_attr=None, **kwargs):
|
|
16
|
+
logging.Handler.__init__(self)
|
|
17
|
+
self.kw = kwargs
|
|
18
|
+
|
|
19
|
+
def emit(self, record):
|
|
20
|
+
"""
|
|
21
|
+
emit函数为自定义handler类时必重写的函数,这里可以根据需要对日志消息做一些处理
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
msg = self.format(record)
|
|
25
|
+
if settings.SDK_SHOW_LOG:
|
|
26
|
+
print(msg)
|
|
27
|
+
if self.kw.get("plog_record_id"):
|
|
28
|
+
PredictRecordTB.add_log(id=self.kw["plog_record_id"], msg=msg)
|
|
29
|
+
if self.kw.get("rlog_record_id"):
|
|
30
|
+
RunRecordTB.add_log(id=self.kw["rlog_record_id"], msg=msg)
|
|
31
|
+
if self.kw.get("online_plog_record_id"):
|
|
32
|
+
OnlineGraphsPredictRecordTB.add_log(id=self.kw["online_plog_record_id"], msg=msg)
|
|
33
|
+
if self.kw.get("backtest_record_id"):
|
|
34
|
+
BacktestRecordTB.add_log(id=self.kw["backtest_record_id"], msg=msg)
|
|
35
|
+
if self.kw.get("evaluate_record_id"):
|
|
36
|
+
EvaluateRecordTB.add_log(id=self.kw["evaluate_record_id"], msg=msg)
|
|
37
|
+
if self.kw.get("online_evaluate_record_id"):
|
|
38
|
+
OnlineGraphsEvaluateRecordTB.add_log(id=self.kw["online_evaluate_record_id"], msg=msg)
|
|
39
|
+
except Exception:
|
|
40
|
+
self.handleError(record)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_pgp_logger(log_name='', logfile='', level=logging.INFO,
|
|
44
|
+
backup_count=7, handlers=['console'], **kwargs):
|
|
45
|
+
# 创建logger对象。传入logger名字
|
|
46
|
+
logger = logging.getLogger(log_name)
|
|
47
|
+
# 设置日志记录等级
|
|
48
|
+
logger.setLevel(level)
|
|
49
|
+
if 'file' in handlers:
|
|
50
|
+
# interval 滚动周期,
|
|
51
|
+
# when="MIDNIGHT", interval=1 表示每天0点为更新点,每天生成一个文件
|
|
52
|
+
# backupCount 表示日志保存个数
|
|
53
|
+
file_handler = TimedRotatingFileHandler(
|
|
54
|
+
filename=logfile, when="MIDNIGHT", interval=1, backupCount=backup_count
|
|
55
|
+
)
|
|
56
|
+
# filename="mylog" suffix设置,会生成文件名为mylog.2020-02-25.log
|
|
57
|
+
file_handler.suffix = "%Y-%m-%d.log"
|
|
58
|
+
# extMatch是编译好正则表达式,用于匹配日志文件名后缀
|
|
59
|
+
# 需要注意的是suffix和extMatch一定要匹配的上,如果不匹配,过期日志不会被删除。
|
|
60
|
+
file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}.log$")
|
|
61
|
+
# 定义日志输出格式
|
|
62
|
+
file_handler.setFormatter(
|
|
63
|
+
logging.Formatter(
|
|
64
|
+
"[%(asctime)s] [%(process)d] [%(levelname)s] - %(message)s"
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
logger.addHandler(file_handler)
|
|
68
|
+
if 'console' in handlers:
|
|
69
|
+
logger.addHandler(logging.StreamHandler())
|
|
70
|
+
if 'record' in handlers:
|
|
71
|
+
logger.addHandler(RecordHandler(log_name, **kwargs))
|
|
72
|
+
return logger
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def log_dec(level):
|
|
76
|
+
def wrapper(func):
|
|
77
|
+
def _(cls, *msg, **extra):
|
|
78
|
+
try:
|
|
79
|
+
msg = '\n'.join([str(i) for i in msg])
|
|
80
|
+
if not hasattr(cls, "logger") or cls.logger is None:
|
|
81
|
+
cls.logger = get_pgp_logger(
|
|
82
|
+
logfile=extra.get("pgp_logfile") or "",
|
|
83
|
+
log_name=extra.get("pgp_log_name") or "pgp",
|
|
84
|
+
level=extra.get("pgp_level") or logging.INFO,
|
|
85
|
+
backup_count=extra.get("pgp_backup_count") or 7,
|
|
86
|
+
handlers=extra.get("pgp_handlers") or ["console"],
|
|
87
|
+
**extra
|
|
88
|
+
)
|
|
89
|
+
f = getattr(cls.logger, level)
|
|
90
|
+
f(msg)
|
|
91
|
+
except:
|
|
92
|
+
pass
|
|
93
|
+
return _
|
|
94
|
+
return wrapper
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def get_logger(folder="run"):
|
|
98
|
+
# 不需要mq消息记录日志
|
|
99
|
+
return logging.getLogger(folder)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class LogBase(object):
|
|
103
|
+
__function__ = None
|
|
104
|
+
|
|
105
|
+
@classmethod
|
|
106
|
+
def init(cls, pgp_handlers, **extra):
|
|
107
|
+
cls.logger = get_pgp_logger(
|
|
108
|
+
logfile=extra.get("pgp_logfile") or "",
|
|
109
|
+
log_name=extra.get("pgp_log_name") or "pgp",
|
|
110
|
+
level=extra.get("pgp_level") or logging.INFO,
|
|
111
|
+
backup_count=extra.get("pgp_backup_count") or 7,
|
|
112
|
+
handlers=pgp_handlers,
|
|
113
|
+
**extra
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
@log_dec("info")
|
|
118
|
+
def info(cls, msg, **extra):
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
@classmethod
|
|
122
|
+
@log_dec("error")
|
|
123
|
+
def error(cls, msg, **extra):
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
@classmethod
|
|
127
|
+
@log_dec("warning")
|
|
128
|
+
def warning(cls, msg, **extra):
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
@classmethod
|
|
132
|
+
@log_dec("warn")
|
|
133
|
+
def warn(cls, msg, **extra):
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
@classmethod
|
|
137
|
+
@log_dec("debug")
|
|
138
|
+
def debug(cls, msg, **extra):
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class plog(LogBase):
|
|
143
|
+
"""预测使用的log"""
|
|
144
|
+
|
|
145
|
+
__function__ = "predict"
|
|
146
|
+
logger = None
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def log(cls, level, msg, **kwargs):
|
|
150
|
+
if hasattr(cls, level):
|
|
151
|
+
f = getattr(cls, level)
|
|
152
|
+
f(msg, **kwargs)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class rlog(LogBase):
|
|
156
|
+
"""运行使用的log"""
|
|
157
|
+
|
|
158
|
+
__function__ = "run"
|
|
159
|
+
logger = None
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class log(LogBase):
|
|
163
|
+
"""一般log"""
|
|
164
|
+
logger = None
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if __name__ == "__main__":
|
|
169
|
+
test_log = get_pgp_logger("test")
|
|
170
|
+
test_log.info('test')
|
|
File without changes
|