vnai 2.1.7__py3-none-any.whl → 2.1.9__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.
- vnai/__init__.py +167 -178
- vnai/beam/__init__.py +2 -2
- vnai/beam/metrics.py +166 -166
- vnai/beam/pulse.py +78 -78
- vnai/beam/quota.py +332 -332
- vnai/flow/__init__.py +1 -1
- vnai/flow/queue.py +99 -99
- vnai/flow/relay.py +340 -355
- vnai/scope/__init__.py +3 -3
- vnai/scope/profile.py +578 -578
- vnai/scope/promo.py +292 -277
- vnai/scope/state.py +154 -154
- {vnai-2.1.7.dist-info → vnai-2.1.9.dist-info}/METADATA +20 -20
- vnai-2.1.9.dist-info/RECORD +16 -0
- vnai-2.1.7.dist-info/RECORD +0 -16
- {vnai-2.1.7.dist-info → vnai-2.1.9.dist-info}/WHEEL +0 -0
- {vnai-2.1.7.dist-info → vnai-2.1.9.dist-info}/top_level.txt +0 -0
vnai/scope/state.py
CHANGED
@@ -1,155 +1,155 @@
|
|
1
|
-
import time
|
2
|
-
import threading
|
3
|
-
import json
|
4
|
-
import os
|
5
|
-
from datetime import datetime
|
6
|
-
from pathlib import Path
|
7
|
-
|
8
|
-
class Tracker:
|
9
|
-
_instance = None
|
10
|
-
_lock = threading.Lock()
|
11
|
-
|
12
|
-
def __new__(cls):
|
13
|
-
with cls._lock:
|
14
|
-
if cls._instance is None:
|
15
|
-
cls._instance = super(Tracker, cls).__new__(cls)
|
16
|
-
cls._instance._initialize()
|
17
|
-
return cls._instance
|
18
|
-
|
19
|
-
def _initialize(self):
|
20
|
-
self.metrics = {
|
21
|
-
"startup_time": datetime.now().isoformat(),
|
22
|
-
"function_calls": 0,
|
23
|
-
"api_requests": 0,
|
24
|
-
"errors": 0,
|
25
|
-
"warnings": 0
|
26
|
-
}
|
27
|
-
self.performance_metrics = {
|
28
|
-
"execution_times": [],
|
29
|
-
"last_error_time": None,
|
30
|
-
"peak_memory": 0
|
31
|
-
}
|
32
|
-
self.privacy_level ="standard"
|
33
|
-
self.home_dir = Path.home()
|
34
|
-
self.project_dir = self.home_dir /".vnstock"
|
35
|
-
self.project_dir.mkdir(exist_ok=True)
|
36
|
-
self.data_dir = self.project_dir /'data'
|
37
|
-
self.data_dir.mkdir(exist_ok=True)
|
38
|
-
self.metrics_path = self.data_dir /"usage_metrics.json"
|
39
|
-
self.privacy_config_path = self.project_dir /'config' /"privacy.json"
|
40
|
-
os.makedirs(os.path.dirname(self.privacy_config_path), exist_ok=True)
|
41
|
-
self._load_metrics()
|
42
|
-
self._load_privacy_settings()
|
43
|
-
self._start_background_collector()
|
44
|
-
|
45
|
-
def _load_metrics(self):
|
46
|
-
if self.metrics_path.exists():
|
47
|
-
try:
|
48
|
-
with open(self.metrics_path,'r') as f:
|
49
|
-
stored_metrics = json.load(f)
|
50
|
-
for key, value in stored_metrics.items():
|
51
|
-
if key in self.metrics:
|
52
|
-
self.metrics[key] = value
|
53
|
-
except:
|
54
|
-
pass
|
55
|
-
|
56
|
-
def _save_metrics(self):
|
57
|
-
try:
|
58
|
-
with open(self.metrics_path,'w') as f:
|
59
|
-
json.dump(self.metrics, f)
|
60
|
-
except:
|
61
|
-
pass
|
62
|
-
|
63
|
-
def _load_privacy_settings(self):
|
64
|
-
if self.privacy_config_path.exists():
|
65
|
-
try:
|
66
|
-
with open(self.privacy_config_path,'r') as f:
|
67
|
-
settings = json.load(f)
|
68
|
-
self.privacy_level = settings.get("level","standard")
|
69
|
-
except:
|
70
|
-
pass
|
71
|
-
|
72
|
-
def setup_privacy(self, level=None):
|
73
|
-
privacy_levels = {
|
74
|
-
"minimal":"Essential system data only",
|
75
|
-
"standard":"Performance metrics and errors",
|
76
|
-
"enhanced":"Detailed operation analytics"
|
77
|
-
}
|
78
|
-
if level is None:
|
79
|
-
level ="standard"
|
80
|
-
if level not in privacy_levels:
|
81
|
-
raise ValueError(f"Invalid privacy level: {level}. Choose from {', '.join(privacy_levels.keys())}")
|
82
|
-
self.privacy_level = level
|
83
|
-
with open(self.privacy_config_path,"w") as f:
|
84
|
-
json.dump({"level": level}, f)
|
85
|
-
return level
|
86
|
-
|
87
|
-
def get_privacy_level(self):
|
88
|
-
return self.privacy_level
|
89
|
-
|
90
|
-
def _start_background_collector(self):
|
91
|
-
def collect_metrics():
|
92
|
-
while True:
|
93
|
-
try:
|
94
|
-
import psutil
|
95
|
-
current_process = psutil.Process()
|
96
|
-
memory_info = current_process.memory_info()
|
97
|
-
memory_usage = memory_info.rss / (1024 * 1024)
|
98
|
-
if memory_usage > self.performance_metrics["peak_memory"]:
|
99
|
-
self.performance_metrics["peak_memory"] = memory_usage
|
100
|
-
self._save_metrics()
|
101
|
-
except:
|
102
|
-
pass
|
103
|
-
time.sleep(300)
|
104
|
-
thread = threading.Thread(target=collect_metrics, daemon=True)
|
105
|
-
thread.start()
|
106
|
-
|
107
|
-
def record(self, event_type, data=None):
|
108
|
-
if self.privacy_level =="minimal" and event_type !="errors":
|
109
|
-
return True
|
110
|
-
if event_type in self.metrics:
|
111
|
-
self.metrics[event_type] += 1
|
112
|
-
else:
|
113
|
-
self.metrics[event_type] = 1
|
114
|
-
if event_type =="errors":
|
115
|
-
self.performance_metrics["last_error_time"] = datetime.now().isoformat()
|
116
|
-
if event_type =="function_calls" and data and"execution_time" in data:
|
117
|
-
self.performance_metrics["execution_times"].append(data["execution_time"])
|
118
|
-
if len(self.performance_metrics["execution_times"]) > 100:
|
119
|
-
self.performance_metrics["execution_times"] = self.performance_metrics["execution_times"][-100:]
|
120
|
-
if self.metrics["function_calls"] % 100 == 0 or event_type =="errors":
|
121
|
-
self._save_metrics()
|
122
|
-
return True
|
123
|
-
|
124
|
-
def get_metrics(self):
|
125
|
-
avg_execution_time = 0
|
126
|
-
if self.performance_metrics["execution_times"]:
|
127
|
-
avg_execution_time = sum(self.performance_metrics["execution_times"]) / len(self.performance_metrics["execution_times"])
|
128
|
-
output = self.metrics.copy()
|
129
|
-
output.update({
|
130
|
-
"avg_execution_time": avg_execution_time,
|
131
|
-
"peak_memory_mb": self.performance_metrics["peak_memory"],
|
132
|
-
"uptime": (datetime.now() - datetime.fromisoformat(self.metrics["startup_time"])).total_seconds(),
|
133
|
-
"privacy_level": self.privacy_level
|
134
|
-
})
|
135
|
-
return output
|
136
|
-
|
137
|
-
def reset(self):
|
138
|
-
self.metrics = {
|
139
|
-
"startup_time": datetime.now().isoformat(),
|
140
|
-
"function_calls": 0,
|
141
|
-
"api_requests": 0,
|
142
|
-
"errors": 0,
|
143
|
-
"warnings": 0
|
144
|
-
}
|
145
|
-
self.performance_metrics = {
|
146
|
-
"execution_times": [],
|
147
|
-
"last_error_time": None,
|
148
|
-
"peak_memory": 0
|
149
|
-
}
|
150
|
-
self._save_metrics()
|
151
|
-
return True
|
152
|
-
tracker = Tracker()
|
153
|
-
|
154
|
-
def record(event_type, data=None):
|
1
|
+
import time
|
2
|
+
import threading
|
3
|
+
import json
|
4
|
+
import os
|
5
|
+
from datetime import datetime
|
6
|
+
from pathlib import Path
|
7
|
+
|
8
|
+
class Tracker:
|
9
|
+
_instance = None
|
10
|
+
_lock = threading.Lock()
|
11
|
+
|
12
|
+
def __new__(cls):
|
13
|
+
with cls._lock:
|
14
|
+
if cls._instance is None:
|
15
|
+
cls._instance = super(Tracker, cls).__new__(cls)
|
16
|
+
cls._instance._initialize()
|
17
|
+
return cls._instance
|
18
|
+
|
19
|
+
def _initialize(self):
|
20
|
+
self.metrics = {
|
21
|
+
"startup_time": datetime.now().isoformat(),
|
22
|
+
"function_calls": 0,
|
23
|
+
"api_requests": 0,
|
24
|
+
"errors": 0,
|
25
|
+
"warnings": 0
|
26
|
+
}
|
27
|
+
self.performance_metrics = {
|
28
|
+
"execution_times": [],
|
29
|
+
"last_error_time": None,
|
30
|
+
"peak_memory": 0
|
31
|
+
}
|
32
|
+
self.privacy_level ="standard"
|
33
|
+
self.home_dir = Path.home()
|
34
|
+
self.project_dir = self.home_dir /".vnstock"
|
35
|
+
self.project_dir.mkdir(exist_ok=True)
|
36
|
+
self.data_dir = self.project_dir /'data'
|
37
|
+
self.data_dir.mkdir(exist_ok=True)
|
38
|
+
self.metrics_path = self.data_dir /"usage_metrics.json"
|
39
|
+
self.privacy_config_path = self.project_dir /'config' /"privacy.json"
|
40
|
+
os.makedirs(os.path.dirname(self.privacy_config_path), exist_ok=True)
|
41
|
+
self._load_metrics()
|
42
|
+
self._load_privacy_settings()
|
43
|
+
self._start_background_collector()
|
44
|
+
|
45
|
+
def _load_metrics(self):
|
46
|
+
if self.metrics_path.exists():
|
47
|
+
try:
|
48
|
+
with open(self.metrics_path,'r') as f:
|
49
|
+
stored_metrics = json.load(f)
|
50
|
+
for key, value in stored_metrics.items():
|
51
|
+
if key in self.metrics:
|
52
|
+
self.metrics[key] = value
|
53
|
+
except:
|
54
|
+
pass
|
55
|
+
|
56
|
+
def _save_metrics(self):
|
57
|
+
try:
|
58
|
+
with open(self.metrics_path,'w') as f:
|
59
|
+
json.dump(self.metrics, f)
|
60
|
+
except:
|
61
|
+
pass
|
62
|
+
|
63
|
+
def _load_privacy_settings(self):
|
64
|
+
if self.privacy_config_path.exists():
|
65
|
+
try:
|
66
|
+
with open(self.privacy_config_path,'r') as f:
|
67
|
+
settings = json.load(f)
|
68
|
+
self.privacy_level = settings.get("level","standard")
|
69
|
+
except:
|
70
|
+
pass
|
71
|
+
|
72
|
+
def setup_privacy(self, level=None):
|
73
|
+
privacy_levels = {
|
74
|
+
"minimal":"Essential system data only",
|
75
|
+
"standard":"Performance metrics and errors",
|
76
|
+
"enhanced":"Detailed operation analytics"
|
77
|
+
}
|
78
|
+
if level is None:
|
79
|
+
level ="standard"
|
80
|
+
if level not in privacy_levels:
|
81
|
+
raise ValueError(f"Invalid privacy level: {level}. Choose from {', '.join(privacy_levels.keys())}")
|
82
|
+
self.privacy_level = level
|
83
|
+
with open(self.privacy_config_path,"w") as f:
|
84
|
+
json.dump({"level": level}, f)
|
85
|
+
return level
|
86
|
+
|
87
|
+
def get_privacy_level(self):
|
88
|
+
return self.privacy_level
|
89
|
+
|
90
|
+
def _start_background_collector(self):
|
91
|
+
def collect_metrics():
|
92
|
+
while True:
|
93
|
+
try:
|
94
|
+
import psutil
|
95
|
+
current_process = psutil.Process()
|
96
|
+
memory_info = current_process.memory_info()
|
97
|
+
memory_usage = memory_info.rss / (1024 * 1024)
|
98
|
+
if memory_usage > self.performance_metrics["peak_memory"]:
|
99
|
+
self.performance_metrics["peak_memory"] = memory_usage
|
100
|
+
self._save_metrics()
|
101
|
+
except:
|
102
|
+
pass
|
103
|
+
time.sleep(300)
|
104
|
+
thread = threading.Thread(target=collect_metrics, daemon=True)
|
105
|
+
thread.start()
|
106
|
+
|
107
|
+
def record(self, event_type, data=None):
|
108
|
+
if self.privacy_level =="minimal" and event_type !="errors":
|
109
|
+
return True
|
110
|
+
if event_type in self.metrics:
|
111
|
+
self.metrics[event_type] += 1
|
112
|
+
else:
|
113
|
+
self.metrics[event_type] = 1
|
114
|
+
if event_type =="errors":
|
115
|
+
self.performance_metrics["last_error_time"] = datetime.now().isoformat()
|
116
|
+
if event_type =="function_calls" and data and"execution_time" in data:
|
117
|
+
self.performance_metrics["execution_times"].append(data["execution_time"])
|
118
|
+
if len(self.performance_metrics["execution_times"]) > 100:
|
119
|
+
self.performance_metrics["execution_times"] = self.performance_metrics["execution_times"][-100:]
|
120
|
+
if self.metrics["function_calls"] % 100 == 0 or event_type =="errors":
|
121
|
+
self._save_metrics()
|
122
|
+
return True
|
123
|
+
|
124
|
+
def get_metrics(self):
|
125
|
+
avg_execution_time = 0
|
126
|
+
if self.performance_metrics["execution_times"]:
|
127
|
+
avg_execution_time = sum(self.performance_metrics["execution_times"]) / len(self.performance_metrics["execution_times"])
|
128
|
+
output = self.metrics.copy()
|
129
|
+
output.update({
|
130
|
+
"avg_execution_time": avg_execution_time,
|
131
|
+
"peak_memory_mb": self.performance_metrics["peak_memory"],
|
132
|
+
"uptime": (datetime.now() - datetime.fromisoformat(self.metrics["startup_time"])).total_seconds(),
|
133
|
+
"privacy_level": self.privacy_level
|
134
|
+
})
|
135
|
+
return output
|
136
|
+
|
137
|
+
def reset(self):
|
138
|
+
self.metrics = {
|
139
|
+
"startup_time": datetime.now().isoformat(),
|
140
|
+
"function_calls": 0,
|
141
|
+
"api_requests": 0,
|
142
|
+
"errors": 0,
|
143
|
+
"warnings": 0
|
144
|
+
}
|
145
|
+
self.performance_metrics = {
|
146
|
+
"execution_times": [],
|
147
|
+
"last_error_time": None,
|
148
|
+
"peak_memory": 0
|
149
|
+
}
|
150
|
+
self._save_metrics()
|
151
|
+
return True
|
152
|
+
tracker = Tracker()
|
153
|
+
|
154
|
+
def record(event_type, data=None):
|
155
155
|
return tracker.record(event_type, data)
|
@@ -1,20 +1,20 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: vnai
|
3
|
-
Version: 2.1.
|
4
|
-
Summary: Vnstock Analytics Interface
|
5
|
-
Author-email: Vnstock Analytics Team <support@vnstocks.com>
|
6
|
-
License: proprietary
|
7
|
-
Project-URL: Homepage, https://vnstocks.com
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
9
|
-
Classifier: Operating System :: OS Independent
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
11
|
-
Classifier: Intended Audience :: Developers
|
12
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
13
|
-
Requires-Python: >=3.7
|
14
|
-
Description-Content-Type: text/markdown
|
15
|
-
Requires-Dist: requests>=2.25.0
|
16
|
-
Requires-Dist: psutil>=5.8.0
|
17
|
-
Provides-Extra: dev
|
18
|
-
Requires-Dist: pytest>=6.0.0; extra == "dev"
|
19
|
-
|
20
|
-
# VnAI
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: vnai
|
3
|
+
Version: 2.1.9
|
4
|
+
Summary: Vnstock Analytics Interface
|
5
|
+
Author-email: Vnstock Analytics Team <support@vnstocks.com>
|
6
|
+
License: proprietary
|
7
|
+
Project-URL: Homepage, https://vnstocks.com
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: Operating System :: OS Independent
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
11
|
+
Classifier: Intended Audience :: Developers
|
12
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
13
|
+
Requires-Python: >=3.7
|
14
|
+
Description-Content-Type: text/markdown
|
15
|
+
Requires-Dist: requests>=2.25.0
|
16
|
+
Requires-Dist: psutil>=5.8.0
|
17
|
+
Provides-Extra: dev
|
18
|
+
Requires-Dist: pytest>=6.0.0; extra == "dev"
|
19
|
+
|
20
|
+
# VnAI
|
@@ -0,0 +1,16 @@
|
|
1
|
+
vnai/__init__.py,sha256=oTfe5Hu8UUDUW3Gq84fqX4InkIfqIZTUqTv2Q28RB3c,5733
|
2
|
+
vnai/beam/__init__.py,sha256=h19ZEQFnWTvqed0mpTcuQf-sT9XifWhfVbaobTEs91Q,131
|
3
|
+
vnai/beam/metrics.py,sha256=2BmdJl7gB4rHwCN7G7WUMg_6rnlY3xfulBzU7usqNfE,6275
|
4
|
+
vnai/beam/pulse.py,sha256=xu7cStqdkCw8be_yVwfjGtqdy-stYC511oZOkT9j6hs,2485
|
5
|
+
vnai/beam/quota.py,sha256=0pgkCdARtojF-xNC0Y_VYYo4GO717F0MOexwNH2NdzY,14416
|
6
|
+
vnai/flow/__init__.py,sha256=9JepoOHS1xn0_ZrDyfft42g2cjhaka7xdG0velqmk-I,70
|
7
|
+
vnai/flow/queue.py,sha256=9dyMwxen1vCiFJ7wNZn-kzMY8DnB4xD575J1pPSWZLw,3223
|
8
|
+
vnai/flow/relay.py,sha256=7VUsiU1T272chBRCRR90Aodfh_PcUUAUlX3SPUtltFQ,12624
|
9
|
+
vnai/scope/__init__.py,sha256=gVvOMQ34V3Tm8_XmX4cRCrgKVfZ4XYQup79MWx6CWuM,197
|
10
|
+
vnai/scope/profile.py,sha256=RSk8w5h9rvamFozQOUrYcDSXssTF0ro70Qq-VfExQF0,21567
|
11
|
+
vnai/scope/promo.py,sha256=AcQDdzcIYCrTQ0Hqr0KVBCOJsBYQevp0T6emQlGlQ-E,13597
|
12
|
+
vnai/scope/state.py,sha256=ApzP6U0Hzp047-k3czL933soUXiZjpZSxXk7DKwf7yM,5389
|
13
|
+
vnai-2.1.9.dist-info/METADATA,sha256=RiB-4I-sviuL_7kRXBtEPsQyfLs15bJ_nEPHVC6qEbY,662
|
14
|
+
vnai-2.1.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
+
vnai-2.1.9.dist-info/top_level.txt,sha256=4zI0qZHePCwvgSqXl4420sBcd0VzZn4MEcRsAIFae3k,5
|
16
|
+
vnai-2.1.9.dist-info/RECORD,,
|
vnai-2.1.7.dist-info/RECORD
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
vnai/__init__.py,sha256=IPw89g9Ar7TnXHXq9YVU2Sa1EyCgP-udw7Qbfpi95UU,6226
|
2
|
-
vnai/beam/__init__.py,sha256=Of7ydx35u4gTOBCYXxDwTfDAZVyIpbds09dXX0hJh-w,133
|
3
|
-
vnai/beam/metrics.py,sha256=p0WzO1a5MvXm98KyyshLzB4FCk-5ERh7JN65IxVB0I0,6441
|
4
|
-
vnai/beam/pulse.py,sha256=WTdjJ8mr2fvtPEZcoyzVO9Nv8jt2QPCjOZjCh7CB4Ww,2563
|
5
|
-
vnai/beam/quota.py,sha256=6DQdA7qwft1VWsscjpxUGyA59PEGmUY2mnGomj2aDRE,14748
|
6
|
-
vnai/flow/__init__.py,sha256=d96OtNAJeYEYYW_3ZZXbGh8NWbVK3cd78lsub9m9--Q,82
|
7
|
-
vnai/flow/queue.py,sha256=LBuaiAdfaOfbOL_1oxapEKlNav7qGdUk8BQdfJTxMyA,3322
|
8
|
-
vnai/flow/relay.py,sha256=e7H_MSNm0AYwDeY0AeHCptl2vuD1NCRUvmsGWNmQK2c,13515
|
9
|
-
vnai/scope/__init__.py,sha256=VVFWdhAVGYJY-4CykgyhjsqoL17WlbRjVk3CZYAN7S4,200
|
10
|
-
vnai/scope/profile.py,sha256=R_xM5DyDEZ6ju9CwTAv_iXDHx4Dhqd7b1lCeAmlj-lc,22145
|
11
|
-
vnai/scope/promo.py,sha256=lnoZJL5smBc1SF49bkCMMCrgzv5NnrIIAMbSqyTGmYI,13003
|
12
|
-
vnai/scope/state.py,sha256=Y8eZNVtG31E7Jv-RtHdDLkRRKbfCK8czbbyKp65065k,5543
|
13
|
-
vnai-2.1.7.dist-info/METADATA,sha256=Gw9R_X7XNv055XKhXZeHKOhstdtfBT88greichRFK9w,682
|
14
|
-
vnai-2.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
-
vnai-2.1.7.dist-info/top_level.txt,sha256=4zI0qZHePCwvgSqXl4420sBcd0VzZn4MEcRsAIFae3k,5
|
16
|
-
vnai-2.1.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|