vnai 2.0.1__py3-none-any.whl → 2.0.2__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/scope/promo.py CHANGED
@@ -1,146 +1,55 @@
1
- # vnai/scope/promo.py
2
- # Content display mechanism for various environments
3
-
1
+ _G='init'
2
+ _F='simple'
3
+ _E='markdown'
4
+ _D=True
5
+ _C=None
6
+ _B='terminal'
7
+ _A='html'
4
8
  import requests
5
9
  from datetime import datetime
6
- import random
7
- import threading
8
- import time
9
- import urllib.parse
10
-
10
+ import random,threading,time,urllib.parse
11
11
  class ContentManager:
12
- """Manages content display across different environments"""
13
-
14
- _instance = None
15
- _lock = threading.Lock()
16
-
17
- def __new__(cls):
18
- with cls._lock:
19
- if cls._instance is None:
20
- cls._instance = super(ContentManager, cls).__new__(cls)
21
- cls._instance._initialize()
22
- return cls._instance
23
-
24
- def _initialize(self):
25
- """Initialize content manager"""
26
- self.last_display = 0
27
- self.display_interval = 24 * 3600 # Once per day by default
28
- self.content_base_url = "https://vnstock-beam.hf.space/content-delivery"
29
- self.target_url = "https://vnstocks.com/lp-khoa-hoc-python-chung-khoan"
30
- self.image_url = "https://vnstocks.com/img/trang-chu-vnstock-python-api-phan-tich-giao-dich-chung-khoan.jpg"
31
-
32
- # Start periodic display thread
33
- self._start_periodic_display()
34
-
35
- def _start_periodic_display(self):
36
- """Start thread for occasional content display"""
37
- def periodic_display():
38
- while True:
39
- # Sleep for a random time between 2-6 hours
40
- sleep_time = random.randint(2 * 3600, 6 * 3600)
41
- time.sleep(sleep_time)
42
-
43
- # Only show if enough time has passed since last display
44
- current_time = time.time()
45
- if current_time - self.last_display >= self.display_interval:
46
- self.present_content(context="periodic")
47
-
48
- # Start thread as daemon so it doesn't prevent program exit
49
- thread = threading.Thread(target=periodic_display, daemon=True)
50
- thread.start()
51
-
52
- def fetch_remote_content(self, context="init", html=True):
53
- """
54
- Fetch content from remote source
55
-
56
- Args:
57
- context (str): Context of the content request (init, loop, periodic, etc.)
58
- html (bool): Whether to request HTML content (True) or plain text (False)
59
- """
60
- try:
61
- # Build the URL with query parameters
62
- params = {
63
- "context": context,
64
- "html": "true" if html else "false"
65
- }
66
- url = f"{self.content_base_url}?{urllib.parse.urlencode(params)}"
67
-
68
- response = requests.get(url, timeout=3)
69
- if response.status_code == 200:
70
- return response.text
71
- return None
72
- except:
73
- return None
74
-
75
- def present_content(self, environment=None, context="init"):
76
- """
77
- Present content appropriate for the environment and context
78
-
79
- Args:
80
- environment (str): The display environment (jupyter, terminal, etc.)
81
- context (str): The context for content (init, loop, periodic)
82
- """
83
- # Update last display time
84
- self.last_display = time.time()
85
-
86
- # Get environment if not provided
87
- if environment is None:
88
- try:
89
- from vnai.scope.profile import inspector
90
- environment = inspector.examine().get("environment", "unknown")
91
- except:
92
- environment = "unknown"
93
-
94
- # Try to fetch remote content based on context and environment
95
- if environment == "jupyter":
96
- remote_content = self.fetch_remote_content(context=context, html=True)
97
- else:
98
- remote_content = self.fetch_remote_content(context=context, html=False)
99
-
100
- # Generate fallback content based on context
101
- fallback_content = self._generate_fallback_content(context)
102
-
103
- # Display based on environment
104
- if environment == "jupyter":
105
- try:
106
- from IPython.display import display, HTML, Markdown
107
- if remote_content:
108
- # Use remote content if available
109
- display(HTML(remote_content))
110
- else:
111
- # Try markdown version first
112
- try:
113
- display(Markdown(fallback_content["markdown"]))
114
- except:
115
- # Fall back to HTML if markdown fails
116
- display(HTML(fallback_content["html"]))
117
- except:
118
- # If IPython display fails, do nothing
119
- pass
120
-
121
- elif environment == "terminal":
122
- if remote_content:
123
- print(remote_content)
124
- else:
125
- print(fallback_content["terminal"])
126
-
127
- else:
128
- # Simple text version for other environments
129
- print(fallback_content["simple"])
130
-
131
- def _generate_fallback_content(self, context):
132
- """Generate appropriate fallback content based on context"""
133
- fallback = {
134
- "html": "",
135
- "markdown": "",
136
- "terminal": "",
137
- "simple": ""
138
- }
139
-
140
- if context == "loop":
141
-
142
- # Content for rate limit exceeded scenario
143
- fallback["html"] = f"""
12
+ _instance=_C;_lock=threading.Lock()
13
+ def __new__(A):
14
+ with A._lock:
15
+ if A._instance is _C:A._instance=super(ContentManager,A).__new__(A);A._instance._initialize()
16
+ return A._instance
17
+ def _initialize(A):A.last_display=0;A.display_interval=86400;A.content_base_url='https://vnstock-beam.hf.space/content-delivery';A.target_url='https://vnstocks.com/lp-khoa-hoc-python-chung-khoan';A.image_url='https://vnstocks.com/img/trang-chu-vnstock-python-api-phan-tich-giao-dich-chung-khoan.jpg';A._start_periodic_display()
18
+ def _start_periodic_display(A):
19
+ def B():
20
+ while _D:
21
+ B=random.randint(7200,21600);time.sleep(B);C=time.time()
22
+ if C-A.last_display>=A.display_interval:A.present_content(context='periodic')
23
+ C=threading.Thread(target=B,daemon=_D);C.start()
24
+ def fetch_remote_content(B,context=_G,html=_D):
25
+ try:
26
+ C={'context':context,_A:'true'if html else'false'};D=f"{B.content_base_url}?{urllib.parse.urlencode(C)}";A=requests.get(D,timeout=3)
27
+ if A.status_code==200:return A.text
28
+ return
29
+ except:return
30
+ def present_content(C,environment=_C,context=_G):
31
+ I='jupyter';H='unknown';E=context;A=environment;C.last_display=time.time()
32
+ if A is _C:
33
+ try:from vnai.scope.profile import inspector as J;A=J.examine().get('environment',H)
34
+ except:A=H
35
+ if A==I:B=C.fetch_remote_content(context=E,html=_D)
36
+ else:B=C.fetch_remote_content(context=E,html=False)
37
+ D=C._generate_fallback_content(E)
38
+ if A==I:
39
+ try:
40
+ from IPython.display import display as F,HTML as G,Markdown as K
41
+ if B:F(G(B))
42
+ else:
43
+ try:F(K(D[_E]))
44
+ except:F(G(D[_A]))
45
+ except:pass
46
+ elif A==_B:
47
+ if B:print(B)
48
+ else:print(D[_B])
49
+ else:print(D[_F])
50
+ def _generate_fallback_content(B,context):
51
+ A={_A:'',_E:'',_B:'',_F:''}
52
+ if context=='loop':A[_A]=f'''
144
53
  <div style="border: 1px solid #e74c3c; padding: 15px; border-radius: 5px; margin: 10px 0;">
145
54
  <h3 style="color: #e74c3c;">⚠️ Bạn đang sử dụng vòng lặp với quá nhiều requests</h3>
146
55
  <p>Để tránh bị giới hạn tốc độ và tối ưu hiệu suất:</p>
@@ -150,36 +59,8 @@ class ContentManager:
150
59
  <li>Tham gia gói tài trợ <a href="https://vnstocks.com/insiders-program" style="color: #3498db;">Vnstock Insider</a> để tăng 5X giới hạn API</li>
151
60
  </ul>
152
61
  </div>
153
- """
154
-
155
- fallback["markdown"] = """
156
- ## ⚠️ Bạn đang sử dụng vòng lặp với quá nhiều requests
157
-
158
- Để tránh bị giới hạn tốc độ và tối ưu hiệu suất:
159
- * Thêm thời gian chờ giữa các lần gọi API
160
- * Sử dụng xử lý theo batch thay vì lặp liên tục
161
- * Tham gia gói tài trợ [Vnstock Insider](https://vnstocks.com/insiders-program) để tăng 5X giới hạn API
162
- """
163
-
164
- fallback["terminal"] = """
165
- ╔═════════════════════════════════════════════════════════════════╗
166
- ║ ║
167
- ║ 🚫 ĐANG BỊ CHẶN BỞI GIỚI HẠN API? GIẢI PHÁP Ở ĐÂY! ║
168
- ║ ║
169
- ║ ✓ Tăng ngay 500% tốc độ gọi API - Không còn lỗi RateLimit ║
170
- ║ ✓ Tiết kiệm 85% thời gian chờ đợi giữa các request ║
171
- ║ ║
172
- ║ ➤ NÂNG CẤP NGAY VỚI GÓI TÀI TRỢ VNSTOCK: ║
173
- ║ https://vnstocks.com/insiders-program ║
174
- ║ ║
175
- ╚═════════════════════════════════════════════════════════════════╝
176
- """
177
-
178
- fallback["simple"] = "🚫 Đang bị giới hạn API? Tăng tốc độ gọi API lên 500% với gói Vnstock Insider: https://vnstocks.com/insiders-program"
179
-
180
- else: # init or periodic or default
181
- # General welcome content
182
- fallback["html"] = f"""
62
+ ''';A[_E]='\n## ⚠️ Bạn đang sử dụng vòng lặp với quá nhiều requests\n\nĐể tránh bị giới hạn tốc độ và tối ưu hiệu suất:\n* Thêm thời gian chờ giữa các lần gọi API\n* Sử dụng xử lý theo batch thay vì lặp liên tục\n* Tham gia gói tài trợ [Vnstock Insider](https://vnstocks.com/insiders-program) để tăng 5X giới hạn API\n ';A[_B]='\n╔═════════════════════════════════════════════════════════════════╗\n║ ║\n║ 🚫 ĐANG BỊ CHẶN BỞI GIỚI HẠN API? GIẢI PHÁP Ở ĐÂY! ║\n║ ║\n║ ✓ Tăng ngay 500% tốc độ gọi API - Không còn lỗi RateLimit ║\n║ ✓ Tiết kiệm 85% thời gian chờ đợi giữa các request ║\n║ ║\n║ ➤ NÂNG CẤP NGAY VỚI GÓI TÀI TRỢ VNSTOCK: ║\n║ https://vnstocks.com/insiders-program ║\n║ ║\n╚═════════════════════════════════════════════════════════════════╝\n ';A[_F]='🚫 Đang bị giới hạn API? Tăng tốc độ gọi API lên 500% với gói Vnstock Insider: https://vnstocks.com/insiders-program'
63
+ else:A[_A]=f'''
183
64
  <div style="border: 1px solid #3498db; padding: 15px; border-radius: 5px; margin: 10px 0;">
184
65
  <h3 style="color: #3498db;">👋 Chào mừng bạn đến với Vnstock!</h3>
185
66
  <p>Cảm ơn bạn đã sử dụng thư viện phân tích chứng khoán #1 tại Việt Nam cho Python</p>
@@ -189,48 +70,7 @@ class ContentManager:
189
70
  </ul>
190
71
  <p>Khám phá các tính năng mới nhất và tham gia cộng đồng để nhận hỗ trợ.</p>
191
72
  </div>
192
- """
193
-
194
- fallback["markdown"] = """
195
- ## 👋 Chào mừng bạn đến với Vnstock!
196
-
197
- Cảm ơn bạn đã sử dụng package phân tích chứng khoán #1 tại Việt Nam
198
-
199
- * Tài liệu: [vnstocks.com/docs](https://vnstocks.com/docs)
200
- * Cộng đồng: [vnstocks.com/community](https://vnstocks.com/community)
201
-
202
- Khám phá các tính năng mới nhất và tham gia cộng đồng để nhận hỗ trợ.
203
- """
204
-
205
- fallback["terminal"] = """
206
- ╔══════════════════════════════════════════════════════════╗
207
- ║ ║
208
- ║ 👋 Chào mừng bạn đến với Vnstock! ║
209
- ║ ║
210
- ║ Cảm ơn bạn đã sử dụng package phân tích ║
211
- ║ chứng khoán #1 tại Việt Nam ║
212
- ║ ║
213
- ║ ✓ Tài liệu: https://vnstocks.com/docs ║
214
- ║ ✓ Cộng đồng: https://vnstocks.com/community ║
215
- ║ ║
216
- ║ Khám phá các tính năng mới nhất và tham gia ║
217
- ║ cộng đồng để nhận hỗ trợ. ║
218
- ║ ║
219
- ╚══════════════════════════════════════════════════════════╝
220
- """
221
-
222
- fallback["simple"] = "👋 Chào mừng bạn đến với Vnstock! Tài liệu: https://vnstocks.com/docs | Cộng đồng: https://vnstocks.com/community"
223
-
224
- return fallback
225
-
226
- # Create singleton instance
227
- manager = ContentManager()
228
-
229
- def present(context="init"):
230
- """
231
- Public API to present content
232
-
233
- Args:
234
- context (str): Context for content presentation (init, loop, periodic)
235
- """
236
- return manager.present_content(context=context)
73
+ ''';A[_E]='\n## 👋 Chào mừng bạn đến với Vnstock!\n\nCảm ơn bạn đã sử dụng package phân tích chứng khoán #1 tại Việt Nam\n\n* Tài liệu: [vnstocks.com/docs](https://vnstocks.com/docs)\n* Cộng đồng: [vnstocks.com/community](https://vnstocks.com/community)\n\nKhám phá các tính năng mới nhất và tham gia cộng đồng để nhận hỗ trợ.\n ';A[_B]='\n╔══════════════════════════════════════════════════════════╗\n║ ║\n║ 👋 Chào mừng bạn đến với Vnstock! ║\n║ ║\n║ Cảm ơn bạn đã sử dụng package phân tích ║\n║ chứng khoán #1 tại Việt Nam ║\n║ ║\n║ ✓ Tài liệu: https://vnstocks.com/docs ║\n║ ✓ Cộng đồng: https://vnstocks.com/community ║\n║ ║\n║ Khám phá các tính năng mới nhất và tham gia ║\n║ cộng đồng để nhận hỗ trợ. ║\n║ ║\n╚══════════════════════════════════════════════════════════╝\n ';A[_F]='👋 Chào mừng bạn đến với Vnstock! Tài liệu: https://vnstocks.com/docs | Cộng đồng: https://vnstocks.com/community'
74
+ return A
75
+ manager=ContentManager()
76
+ def present(context=_G):return manager.present_content(context=context)
vnai/scope/state.py CHANGED
@@ -1,223 +1,74 @@
1
- # vnai/scope/state.py
2
- # System state tracking
3
-
4
- import time
5
- import threading
6
- import json
7
- import os
1
+ _L='minimal'
2
+ _K='warnings'
3
+ _J='api_requests'
4
+ _I='last_error_time'
5
+ _H='startup_time'
6
+ _G='standard'
7
+ _F='function_calls'
8
+ _E='peak_memory'
9
+ _D='errors'
10
+ _C=True
11
+ _B=None
12
+ _A='execution_times'
13
+ import time,threading,json,os
8
14
  from datetime import datetime
9
15
  from pathlib import Path
10
-
11
16
  class Tracker:
12
- """Tracks system state and performance metrics"""
13
-
14
- _instance = None
15
- _lock = threading.Lock()
16
-
17
- def __new__(cls):
18
- with cls._lock:
19
- if cls._instance is None:
20
- cls._instance = super(Tracker, cls).__new__(cls)
21
- cls._instance._initialize()
22
- return cls._instance
23
-
24
- def _initialize(self):
25
- """Initialize tracker"""
26
- self.metrics = {
27
- "startup_time": datetime.now().isoformat(),
28
- "function_calls": 0,
29
- "api_requests": 0,
30
- "errors": 0,
31
- "warnings": 0
32
- }
33
-
34
- self.performance_metrics = {
35
- "execution_times": [],
36
- "last_error_time": None,
37
- "peak_memory": 0
38
- }
39
-
40
- self.privacy_level = "standard"
41
-
42
- # Setup data directory
43
- self.home_dir = Path.home()
44
- self.project_dir = self.home_dir / ".vnstock"
45
- self.project_dir.mkdir(exist_ok=True)
46
- self.data_dir = self.project_dir / 'data'
47
- self.data_dir.mkdir(exist_ok=True)
48
- self.metrics_path = self.data_dir / "usage_metrics.json"
49
- self.privacy_config_path = self.project_dir / 'config' / "privacy.json"
50
-
51
- # Create config directory if it doesn't exist
52
- os.makedirs(os.path.dirname(self.privacy_config_path), exist_ok=True)
53
-
54
- # Load existing metrics
55
- self._load_metrics()
56
-
57
- # Load privacy settings
58
- self._load_privacy_settings()
59
-
60
- # Start background metrics collector
61
- self._start_background_collector()
62
-
63
- def _load_metrics(self):
64
- """Load metrics from file"""
65
- if self.metrics_path.exists():
66
- try:
67
- with open(self.metrics_path, 'r') as f:
68
- stored_metrics = json.load(f)
69
-
70
- # Update metrics with stored values
71
- for key, value in stored_metrics.items():
72
- if key in self.metrics:
73
- self.metrics[key] = value
74
- except:
75
- pass
76
-
77
- def _save_metrics(self):
78
- """Save metrics to file"""
79
- try:
80
- with open(self.metrics_path, 'w') as f:
81
- json.dump(self.metrics, f)
82
- except:
83
- pass
84
-
85
- def _load_privacy_settings(self):
86
- """Load privacy settings"""
87
- if self.privacy_config_path.exists():
88
- try:
89
- with open(self.privacy_config_path, 'r') as f:
90
- settings = json.load(f)
91
- self.privacy_level = settings.get("level", "standard")
92
- except:
93
- pass
94
-
95
- def setup_privacy(self, level=None):
96
- """Configure privacy level for data collection"""
97
- privacy_levels = {
98
- "minimal": "Essential system data only",
99
- "standard": "Performance metrics and errors",
100
- "enhanced": "Detailed operation analytics"
101
- }
102
-
103
- if level is None:
104
- # Default level
105
- level = "standard"
106
-
107
- if level not in privacy_levels:
108
- raise ValueError(f"Invalid privacy level: {level}. Choose from {', '.join(privacy_levels.keys())}")
109
-
110
- # Store preference
111
- self.privacy_level = level
112
-
113
- # Store in configuration file
114
- with open(self.privacy_config_path, "w") as f:
115
- json.dump({"level": level}, f)
116
-
117
- return level
118
-
119
- def get_privacy_level(self):
120
- """Get current privacy level"""
121
- return self.privacy_level
122
-
123
- def _start_background_collector(self):
124
- """Start background metrics collection"""
125
- def collect_metrics():
126
- while True:
127
- try:
128
- import psutil
129
-
130
- # Update peak memory
131
- current_process = psutil.Process()
132
- memory_info = current_process.memory_info()
133
- memory_usage = memory_info.rss / (1024 * 1024) # MB
134
-
135
- if memory_usage > self.performance_metrics["peak_memory"]:
136
- self.performance_metrics["peak_memory"] = memory_usage
137
-
138
- # Save metrics periodically
139
- self._save_metrics()
140
-
141
- except:
142
- pass
143
-
144
- time.sleep(300) # Run every 5 minutes
145
-
146
- # Start thread
147
- thread = threading.Thread(target=collect_metrics, daemon=True)
148
- thread.start()
149
-
150
- def record(self, event_type, data=None):
151
- """Record an event"""
152
- # Check privacy level
153
- if self.privacy_level == "minimal" and event_type != "errors":
154
- # In minimal mode, only track errors
155
- return True
156
-
157
- # Update counts
158
- if event_type in self.metrics:
159
- self.metrics[event_type] += 1
160
- else:
161
- self.metrics[event_type] = 1
162
-
163
- # Special handling for errors
164
- if event_type == "errors":
165
- self.performance_metrics["last_error_time"] = datetime.now().isoformat()
166
-
167
- # Special handling for function calls with timing data
168
- if event_type == "function_calls" and data and "execution_time" in data:
169
- # Keep up to 100 latest execution times
170
- self.performance_metrics["execution_times"].append(data["execution_time"])
171
- if len(self.performance_metrics["execution_times"]) > 100:
172
- self.performance_metrics["execution_times"] = self.performance_metrics["execution_times"][-100:]
173
-
174
- # Save if metrics change significantly
175
- if self.metrics["function_calls"] % 100 == 0 or event_type == "errors":
176
- self._save_metrics()
177
-
178
- return True
179
-
180
- def get_metrics(self):
181
- """Get current metrics"""
182
- # Calculate derived metrics
183
- avg_execution_time = 0
184
- if self.performance_metrics["execution_times"]:
185
- avg_execution_time = sum(self.performance_metrics["execution_times"]) / len(self.performance_metrics["execution_times"])
186
-
187
- # Add derived metrics to output
188
- output = self.metrics.copy()
189
- output.update({
190
- "avg_execution_time": avg_execution_time,
191
- "peak_memory_mb": self.performance_metrics["peak_memory"],
192
- "uptime": (datetime.now() - datetime.fromisoformat(self.metrics["startup_time"])).total_seconds(),
193
- "privacy_level": self.privacy_level
194
- })
195
-
196
- return output
197
-
198
- def reset(self):
199
- """Reset metrics"""
200
- self.metrics = {
201
- "startup_time": datetime.now().isoformat(),
202
- "function_calls": 0,
203
- "api_requests": 0,
204
- "errors": 0,
205
- "warnings": 0
206
- }
207
-
208
- self.performance_metrics = {
209
- "execution_times": [],
210
- "last_error_time": None,
211
- "peak_memory": 0
212
- }
213
-
214
- self._save_metrics()
215
- return True
216
-
217
- # Create singleton instance
218
- tracker = Tracker()
219
-
220
-
221
- def record(event_type, data=None):
222
- """Record an event"""
223
- return tracker.record(event_type, data)
17
+ _instance=_B;_lock=threading.Lock()
18
+ def __new__(A):
19
+ with A._lock:
20
+ if A._instance is _B:A._instance=super(Tracker,A).__new__(A);A._instance._initialize()
21
+ return A._instance
22
+ def _initialize(A):A.metrics={_H:datetime.now().isoformat(),_F:0,_J:0,_D:0,_K:0};A.performance_metrics={_A:[],_I:_B,_E:0};A.privacy_level=_G;A.home_dir=Path.home();A.project_dir=A.home_dir/'.vnstock';A.project_dir.mkdir(exist_ok=_C);A.data_dir=A.project_dir/'data';A.data_dir.mkdir(exist_ok=_C);A.metrics_path=A.data_dir/'usage_metrics.json';A.privacy_config_path=A.project_dir/'config'/'privacy.json';os.makedirs(os.path.dirname(A.privacy_config_path),exist_ok=_C);A._load_metrics();A._load_privacy_settings();A._start_background_collector()
23
+ def _load_metrics(A):
24
+ if A.metrics_path.exists():
25
+ try:
26
+ with open(A.metrics_path,'r')as C:D=json.load(C)
27
+ for(B,E)in D.items():
28
+ if B in A.metrics:A.metrics[B]=E
29
+ except:pass
30
+ def _save_metrics(A):
31
+ try:
32
+ with open(A.metrics_path,'w')as B:json.dump(A.metrics,B)
33
+ except:pass
34
+ def _load_privacy_settings(A):
35
+ if A.privacy_config_path.exists():
36
+ try:
37
+ with open(A.privacy_config_path,'r')as B:C=json.load(B);A.privacy_level=C.get('level',_G)
38
+ except:pass
39
+ def setup_privacy(B,level=_B):
40
+ A=level;C={_L:'Essential system data only',_G:'Performance metrics and errors','enhanced':'Detailed operation analytics'}
41
+ if A is _B:A=_G
42
+ if A not in C:raise ValueError(f"Invalid privacy level: {A}. Choose from {', '.join(C.keys())}")
43
+ B.privacy_level=A
44
+ with open(B.privacy_config_path,'w')as D:json.dump({'level':A},D)
45
+ return A
46
+ def get_privacy_level(A):return A.privacy_level
47
+ def _start_background_collector(A):
48
+ def B():
49
+ while _C:
50
+ try:
51
+ import psutil as C;D=C.Process();E=D.memory_info();B=E.rss/1048576
52
+ if B>A.performance_metrics[_E]:A.performance_metrics[_E]=B
53
+ A._save_metrics()
54
+ except:pass
55
+ time.sleep(300)
56
+ C=threading.Thread(target=B,daemon=_C);C.start()
57
+ def record(A,event_type,data=_B):
58
+ D='execution_time';C=data;B=event_type
59
+ if A.privacy_level==_L and B!=_D:return _C
60
+ if B in A.metrics:A.metrics[B]+=1
61
+ else:A.metrics[B]=1
62
+ if B==_D:A.performance_metrics[_I]=datetime.now().isoformat()
63
+ if B==_F and C and D in C:
64
+ A.performance_metrics[_A].append(C[D])
65
+ if len(A.performance_metrics[_A])>100:A.performance_metrics[_A]=A.performance_metrics[_A][-100:]
66
+ if A.metrics[_F]%100==0 or B==_D:A._save_metrics()
67
+ return _C
68
+ def get_metrics(A):
69
+ B=0
70
+ if A.performance_metrics[_A]:B=sum(A.performance_metrics[_A])/len(A.performance_metrics[_A])
71
+ C=A.metrics.copy();C.update({'avg_execution_time':B,'peak_memory_mb':A.performance_metrics[_E],'uptime':(datetime.now()-datetime.fromisoformat(A.metrics[_H])).total_seconds(),'privacy_level':A.privacy_level});return C
72
+ def reset(A):A.metrics={_H:datetime.now().isoformat(),_F:0,_J:0,_D:0,_K:0};A.performance_metrics={_A:[],_I:_B,_E:0};A._save_metrics();return _C
73
+ tracker=Tracker()
74
+ def record(event_type,data=_B):return tracker.record(event_type,data)
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vnai
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: System optimization and resource management toolkit
5
5
  Home-page: https://github.com/yourusername/vnai
6
6
  Author: Your Name
7
7
  Author-email: your.email@example.com
8
+ License: MIT
8
9
  Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Developers
@@ -24,6 +24,7 @@ Dynamic: classifier
24
24
  Dynamic: description
25
25
  Dynamic: description-content-type
26
26
  Dynamic: home-page
27
+ Dynamic: license
27
28
  Dynamic: provides-extra
28
29
  Dynamic: requires-dist
29
30
  Dynamic: requires-python
@@ -0,0 +1,16 @@
1
+ vnai/__init__.py,sha256=iS0LLz-J9MnC1m3aLPBPGfc7B36t2v4YX5lK4pRoiEU,4791
2
+ vnai/beam/__init__.py,sha256=MG_4FkhQZyuKeaoQQh-KaULhxcGu370lGR6FVV5blU4,129
3
+ vnai/beam/metrics.py,sha256=nVKoe0SJg0TNCPvAOaE99ZyBJ9Tw5WSRydyAObH8FrA,2709
4
+ vnai/beam/pulse.py,sha256=5e21Ky6rVKD57bf8BzSA2lGzwHhohansoQzggrnEpIE,1580
5
+ vnai/beam/quota.py,sha256=zJWONvtd4pxYGDtdalrXHj1yBDasEzoQpMkENN38a70,7364
6
+ vnai/flow/__init__.py,sha256=BURTo8cXicmqqTbeB0qfXwVole0oGDVp_UxRSeh4qfA,80
7
+ vnai/flow/queue.py,sha256=pvC_HSjctR62Uzt4b3h3EANJXmrkKBm3iiNVIrlTnJA,1912
8
+ vnai/flow/relay.py,sha256=RU-paE3HVkgodPmNlAI8fAoVUcwufegY1WmsGL-sWpY,6676
9
+ vnai/scope/__init__.py,sha256=o7N7JjgSqIfQeDojgnxzV9gthEWL3YxxljnvRO9AXkQ,196
10
+ vnai/scope/profile.py,sha256=BHgX2yUQOMoJeUp_AaUWuc635bT1AJfw-FShNVRPikw,14985
11
+ vnai/scope/promo.py,sha256=5Q8VQszYdUaHt-3VPQrZsnxSSYgaXYG-oXnGridBM7U,7167
12
+ vnai/scope/state.py,sha256=JkVwJv8l_-ef201I_O1PHqFyp8KJ3VWyfmZnCltH18c,3283
13
+ vnai-2.0.2.dist-info/METADATA,sha256=_jz71GfABM6GmUKnPCwZ4vc2iSwJEQOphpbozgitdDw,1017
14
+ vnai-2.0.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
15
+ vnai-2.0.2.dist-info/top_level.txt,sha256=4zI0qZHePCwvgSqXl4420sBcd0VzZn4MEcRsAIFae3k,5
16
+ vnai-2.0.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.1)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,16 +0,0 @@
1
- vnai/__init__.py,sha256=iqCNvUVrP6JVFk5jBnCLpVyZdBSZkcfkzu64JNEijis,8895
2
- vnai/beam/__init__.py,sha256=xKb_iu9aAPXCulI7dENrvqVIhelSD1mIqKE9Go3GAHw,200
3
- vnai/beam/metrics.py,sha256=xVmVw93yhKeWzRZJurmrD9mWur16HyLJl_p1XqMwW_w,7187
4
- vnai/beam/pulse.py,sha256=jp1YwjLaMhne2nYhM5PofveDsdrSp2YtewQ2jjE78Is,3470
5
- vnai/beam/quota.py,sha256=I2rUC3z5s5ni9yTU8Vj7mpMA2uPGMT64s9PwbJUsr7s,20798
6
- vnai/flow/__init__.py,sha256=K3OeabzAWGrdPgTAOlDqrJh2y9aQW2pgLZg8tblN3ho,147
7
- vnai/flow/queue.py,sha256=b9YKUbiXDZRC3fVgEnA77EO0EMXAi8eCoBkHnAUI5Sc,4162
8
- vnai/flow/relay.py,sha256=RtIPRZ3BlQd-XgTbisJg0iC1HqikAjHGyyo8aTj_fUw,15766
9
- vnai/scope/__init__.py,sha256=overJZ_UiEfBRNcSieE1GPU_9X3oS4C5l6JeBaFFVxk,267
10
- vnai/scope/profile.py,sha256=xKEqDAaeZvRZMn1YK8qS6ILz7DRYxRkd_IJxLm7O-cs,30738
11
- vnai/scope/promo.py,sha256=bIVok3eW3GXGGu-OdDeMggrvC_JfpT6blYVJuj35k7s,11031
12
- vnai/scope/state.py,sha256=LlcZNKBy2mcAnD765BO2Tlv3Zzbak2TOEz4RUPMCFZ8,7490
13
- vnai-2.0.1.dist-info/METADATA,sha256=9gyeWPMPAoIUmQPeeyow2USwrGO3Ir8Q3ivMNalh40o,1038
14
- vnai-2.0.1.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
15
- vnai-2.0.1.dist-info/top_level.txt,sha256=4zI0qZHePCwvgSqXl4420sBcd0VzZn4MEcRsAIFae3k,5
16
- vnai-2.0.1.dist-info/RECORD,,