vnai 2.1.9__py3-none-any.whl → 2.3.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.
vnai/scope/promo.py CHANGED
@@ -1,10 +1,12 @@
1
1
  import logging
2
2
  import requests
3
- from datetime import datetime
3
+ import json
4
+ from datetime import datetime, timedelta
4
5
  import random
5
6
  import threading
6
7
  import time
7
8
  import urllib.parse
9
+ from pathlib import Path
8
10
  _vnii_check_attempted = False
9
11
 
10
12
  class AdCategory:
@@ -19,10 +21,8 @@ class AdCategory:
19
21
  SECURITY = 8
20
22
  MAINTENANCE = 9
21
23
  WARNING = 10
22
- try:
23
- from vnii import lc_init
24
- except ImportError:
25
- lc_init = None
24
+ API_KEY_CHECKER_AVAILABLE = None
25
+ api_key_checker = None
26
26
  logger = logging.getLogger(__name__)
27
27
  if not logger.hasHandlers():
28
28
  handler = logging.StreamHandler()
@@ -46,85 +46,127 @@ class ContentManager:
46
46
  self.is_paid_user = None
47
47
  self.license_checked = False
48
48
  self._debug = debug
49
- global _vnii_check_attempted
50
- if _vnii_check_attempted:
51
- return
52
- _vnii_check_attempted = True
53
- import sys
54
- import importlib
55
- try:
56
- import importlib.metadata
57
- VNII_LATEST_VERSION ="0.1.1"
58
- VNII_URL =f"https://github.com/vnstock-hq/licensing/releases/download/vnii-{VNII_LATEST_VERSION}/vnii-{VNII_LATEST_VERSION}.tar.gz"
59
- import subprocess
49
+ global API_KEY_CHECKER_AVAILABLE, api_key_checker
50
+ if API_KEY_CHECKER_AVAILABLE is None:
60
51
  try:
61
- old_version = importlib.metadata.version("vnii")
62
- if old_version != VNII_LATEST_VERSION:
63
- try:
64
- subprocess.check_call([
65
- sys.executable,"-m","pip","install",f"vnii@{VNII_URL}","--quiet"
66
- ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
67
- importlib.invalidate_caches()
68
- if"vnii" in sys.modules:
69
- importlib.reload(sys.modules["vnii"])
70
- else:
71
- import vnii
72
- new_version = importlib.metadata.version("vnii")
73
- except Exception as e:
74
- logger.error(f"Lỗi khi cài đặt vnii: {e}")
75
- pass
76
- except importlib.metadata.PackageNotFoundError:
77
- self.is_paid_user = False
78
- return
52
+ from vnai.scope.lc_integration import api_key_checker as _checker
53
+ api_key_checker = _checker
54
+ API_KEY_CHECKER_AVAILABLE = True
55
+ except ImportError:
56
+ API_KEY_CHECKER_AVAILABLE = False
57
+ api_key_checker = None
58
+ self.last_display = 0
59
+ self.display_interval = 24 * 3600
60
+ self.content_base_url ="https://hq.vnstocks.com/content-delivery"
61
+ self.target_url ="https://vnstocks.com/lp-khoa-hoc-python-chung-khoan"
62
+ self.image_url = (
63
+ "https://vnstocks.com/img/trang-chu-vnstock-python-api-phan-tich-giao-dich-chung-khoan.jpg"
64
+ )
65
+ self.vnstock_dir = Path.home() /".vnstock"
66
+ self.message_cache_file = self.vnstock_dir /"message_cache.json"
67
+ self.message_cache = {}
68
+ self._load_message_cache()
69
+ self._start_periodic_display()
70
+
71
+ def _load_message_cache(self) -> None:
72
+ try:
73
+ if self.message_cache_file.exists():
74
+ with open(self.message_cache_file,'r') as f:
75
+ self.message_cache = json.load(f)
76
+ else:
77
+ self.message_cache = {}
79
78
  except Exception as e:
80
- logger.error(f"Lỗi khi kiểm tra/cài đặt vnii: {e}")
81
- user_msg = (
82
- "Không thể tự động cài đặt/cập nhật vnii. "
83
- "Vui lòng liên hệ admin hoặc hỗ trợ kỹ thuật của Vnstock để được trợ giúp. "
84
- f"Chi tiết lỗi: {e}"
85
- )
86
- logger.error(user_msg)
79
+ logger.debug(f"Failed to load message cache: {e}")
80
+ self.message_cache = {}
81
+
82
+ def _save_message_cache(self) -> None:
83
+ try:
84
+ self.vnstock_dir.mkdir(exist_ok=True)
85
+ with open(self.message_cache_file,'w') as f:
86
+ json.dump(self.message_cache, f, indent=2)
87
+ except Exception as e:
88
+ logger.debug(f"Failed to save message cache: {e}")
89
+
90
+ def should_show_promotional_for_rate_limit(self, tier: str) -> bool:
91
+ if tier !="free":
92
+ return False
93
+ last_promo = self.message_cache.get("last_promotional_message")
94
+ if last_promo:
87
95
  try:
88
- print(user_msg)
89
- except Exception:
90
- pass
91
- self.is_paid_user = False
96
+ last_time = datetime.fromisoformat(last_promo)
97
+ now = datetime.now()
98
+ if (now - last_time).total_seconds() < 86400:
99
+ return False
100
+ except Exception as e:
101
+ logger.debug(f"Error parsing last promotional time: {e}")
102
+ session_start = self.message_cache.get("session_start")
103
+ if session_start:
104
+ try:
105
+ start_time = datetime.fromisoformat(session_start)
106
+ now = datetime.now()
107
+ if (now - start_time).total_seconds() < 300:
108
+ return False
109
+ except Exception as e:
110
+ logger.debug(f"Error parsing session start time: {e}")
111
+ else:
112
+ self.message_cache["session_start"] = datetime.now().isoformat()
113
+ self._save_message_cache()
114
+ return False
115
+ return True
116
+
117
+ def mark_promotional_shown(self) -> None:
118
+ self.message_cache["last_promotional_message"] = datetime.now().isoformat()
119
+ self._save_message_cache()
120
+
121
+ def _check_license_status(self):
122
+ if self.license_checked:
92
123
  return
93
- if lc_init is not None:
124
+ if API_KEY_CHECKER_AVAILABLE and api_key_checker:
94
125
  try:
95
- license_info = lc_init(repo_name='vnstock', debug=self._debug)
96
- status = license_info.get('status','').lower()
126
+ result = api_key_checker.check_license_with_vnii()
97
127
  if self._debug:
98
- logger.info(f"License check result: {status}")
99
- if'recognized and verified' in status:
100
- self.is_paid_user = True
128
+ logger.info(f"API key check result: {result}")
129
+ valid_statuses = [
130
+ 'verified',
131
+ 'cached',
132
+ 'device_limit_exceeded'
133
+ ]
134
+ if result.get('status') in valid_statuses:
135
+ self.is_paid_user = result.get('is_paid', False)
136
+ self.license_checked = True
101
137
  if self._debug:
102
- logger.info("Detected paid user (license recognized and verified).")
138
+ status_msg = (
139
+ "Detected paid user"
140
+ if self.is_paid_user
141
+ else"Detected free user"
142
+ )
143
+ logger.info(f"{status_msg} via API key")
103
144
  else:
104
145
  self.is_paid_user = False
146
+ self.license_checked = True
105
147
  if self._debug:
106
- logger.info("Detected free user (license not recognized/verified).")
107
- self.license_checked = True
148
+ logger.info(
149
+ f"No valid license: {result.get('status')}"
150
+ )
108
151
  except Exception as e:
109
152
  if self._debug:
110
- logger.error(f"Lỗi khi kiểm tra license với lc_init: {e}")
111
- self.is_paid_user = None
153
+ logger.error(f"Error checking license via API key: {e}")
154
+ self.is_paid_user = False
155
+ self.license_checked = True
112
156
  else:
113
157
  if self._debug:
114
- logger.warning("Không tìm thấy package vnii. Không xác định được trạng thái paid user.")
115
- self.is_paid_user = None
116
- self.last_display = 0
117
- self.display_interval = 24 * 3600
118
- self.content_base_url ="https://hq.vnstocks.com/content-delivery"
119
- self.target_url ="https://vnstocks.com/lp-khoa-hoc-python-chung-khoan"
120
- self.image_url = (
121
- "https://vnstocks.com/img/trang-chu-vnstock-python-api-phan-tich-giao-dich-chung-khoan.jpg"
122
- )
123
- self._start_periodic_display()
158
+ logger.warning(
159
+ "API key checker not available. "
160
+ "Cannot determine paid user status."
161
+ )
162
+ self.is_paid_user = False
163
+ self.license_checked = True
124
164
 
125
165
  def _start_periodic_display(self):
126
166
  def periodic_display():
127
167
  while True:
168
+ if not self.license_checked:
169
+ self._check_license_status()
128
170
  if self.is_paid_user:
129
171
  break
130
172
  sleep_time = random.randint(2 * 3600, 6 * 3600)
@@ -138,16 +180,10 @@ f"Chi tiết lỗi: {e}"
138
180
  thread.start()
139
181
 
140
182
  def fetch_remote_content(self, context: str ="init", html: bool = True) -> str:
183
+ if not self.license_checked:
184
+ self._check_license_status()
141
185
  if self.is_paid_user:
142
186
  return""
143
- """
144
- Fetch promotional content from remote service with context and format flag.
145
- Args:
146
- context: usage context (e.g., "init", "periodic", "loop").
147
- html: if True, request HTML; otherwise plain text.
148
- Returns:
149
- The content string on HTTP 200, or None on failure.
150
- """
151
187
  try:
152
188
  params = {"context": context,"html":"true" if html else"false"}
153
189
  url =f"{self.content_base_url}?{urllib.parse.urlencode(params)}"
@@ -161,17 +197,18 @@ f"Chi tiết lỗi: {e}"
161
197
  return None
162
198
 
163
199
  def present_content(self, context: str ="init", ad_category: int = AdCategory.FREE) -> None:
164
- environment = None
165
- if getattr(self,'is_paid_user', False) and ad_category == AdCategory.FREE:
200
+ if not self.license_checked:
201
+ self._check_license_status()
202
+ if self.is_paid_user and ad_category == AdCategory.FREE:
166
203
  return
167
204
  self.last_display = time.time()
168
- if environment is None:
169
- try:
170
- from vnai.scope.profile import inspector
171
- environment = inspector.examine().get("environment","unknown")
172
- except Exception as e:
173
- logger.error(f"Không detect được environment: {e}")
174
- environment ="unknown"
205
+ environment = None
206
+ try:
207
+ from vnai.scope.profile import inspector
208
+ environment = inspector.examine().get("environment","unknown")
209
+ except Exception as e:
210
+ logger.error(f"Không detect được environment: {e}")
211
+ environment ="unknown"
175
212
  remote_content = self.fetch_remote_content(
176
213
  context=context, html=(environment =="jupyter")
177
214
  )
@@ -221,26 +258,26 @@ f"""
221
258
  * Tham gia gói tài trợ [Vnstock Insider](https://vnstocks.com/insiders-program) để tăng 5X giới hạn API
222
259
  """
223
260
  )
224
- fallback["terminal"] = (
225
- """
226
- ╔═════════════════════════════════════════════════════════════════╗
227
- ║ ║
228
- ║ 🚫 ĐANG BỊ CHẶN BỞI GIỚI HẠN API? GIẢI PHÁP Ở ĐÂY! ║
229
- ║ ║
230
- ║ ✓ Tăng ngay 500% tốc độ gọi API - Không còn lỗi RateLimit ║
231
- ║ ✓ Tiết kiệm 85% thời gian chờ đợi giữa các request ║
232
- ║ ║
233
- ║ ➤ NÂNG CẤP NGAY VỚI GÓI TÀI TRỢ VNSTOCK: ║
234
- ║ https://vnstocks.com/insiders-program ║
235
- ║ ║
236
- ╚═════════════════════════════════════════════════════════════════╝
237
- """
238
- )
239
- fallback["simple"] = (
240
- "🚫 Đang bị giới hạn API? Tăng tốc độ gọi API lên 500% với gói "
241
- "Vnstock Insider: https://vnstocks.com/insiders-program"
242
- )
261
+ fallback["terminal"] = get_promotional_message("terminal")
262
+ fallback["simple"] = get_promotional_message("simple")
243
263
  else:
264
+ from vnai.beam.auth import authenticator
265
+ tier = authenticator.get_tier()
266
+ period_limit_info =""
267
+ if tier =='guest':
268
+ period_limit_info = (
269
+ "<p style='color: #e67e22; margin-top: 10px;'>"
270
+ "<strong>📊 Phiên bản cộng đồng:</strong> Báo cáo tài chính được giới hạn tối đa <strong>4 kỳ</strong> để minh hoạ thuật toán. "
271
+ "Để truy cập đầy đủ, vui lòng <a href='https://vnstocks.com/insiders-program' style='color: #e67e22;'>tham gia gói thành viên tài trợ dự án</a>."
272
+ "</p>"
273
+ )
274
+ elif tier =='free':
275
+ period_limit_info = (
276
+ "<p style='color: #e67e22; margin-top: 10px;'>"
277
+ "<strong>📊 Phiên bản cộng đồng:</strong> Báo cáo tài chính được giới hạn tối đa <strong>8 kỳ</strong> để minh hoạ thuật toán. "
278
+ "Để truy cập đầy đủ, vui lòng <a href='https://vnstocks.com/insiders-program' style='color: #e67e22;'>tham gia gói thành viên tài trợ dự án</a>."
279
+ "</p>"
280
+ )
244
281
  fallback["html"] = (
245
282
  f"""
246
283
  <div style="border: 1px solid #3498db; padding: 15px; border-radius: 5px; margin: 10px 0;">
@@ -251,20 +288,31 @@ f"""
251
288
  <li>Cộng đồng: <a href="https://www.facebook.com/groups/vnstock.official" style="color: #3498db;">vnstocks.com/community</a></li>
252
289
  </ul>
253
290
  <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>
291
+ {period_limit_info}
254
292
  </div>
255
293
  """
256
294
  )
295
+ period_limit_markdown =""
296
+ if tier =='guest':
297
+ period_limit_markdown ="\n**📊 Phiên bản cộng đồng:** Báo cáo tài chính được giới hạn tối đa **4 kỳ** để minh hoạ thuật toán. Để truy cập đầy đủ, vui lòng [tham gia gói thành viên tài trợ dự án](https://vnstocks.com/insiders-program)."
298
+ elif tier =='free':
299
+ period_limit_markdown ="\n**📊 Phiên bản cộng đồng:** Báo cáo tài chính được giới hạn tối đa **8 kỳ** để minh hoạ thuật toán. Để truy cập đầy đủ, vui lòng [tham gia gói thành viên tài trợ dự án](https://vnstocks.com/insiders-program)."
257
300
  fallback["markdown"] = (
258
- """
301
+ f"""
259
302
  ## 👋 Chào mừng bạn đến với Vnstock!
260
303
  Cảm ơn bạn đã sử dụng package phân tích chứng khoán #1 tại Việt Nam
261
304
  * Tài liệu: [Sổ tay hướng dẫn](https://vnstocks.com/docs)
262
305
  * Cộng đồng: [Nhóm Facebook](https://facebook.com/groups/vnstock.official)
263
- Khám phá các tính năng mới nhất và tham gia cộng đồng để nhận hỗ trợ.
306
+ Khám phá các tính năng mới nhất và tham gia cộng đồng để nhận hỗ trợ.{period_limit_markdown}
264
307
  """
265
308
  )
309
+ period_limit_terminal =""
310
+ if tier =='guest':
311
+ period_limit_terminal ="\n║ 📊 Báo cáo tài chính: Giới hạn 4 kỳ (phiên bản cộng đồng) ║\n║ Nâng cấp: https://vnstocks.com/insiders-program ║"
312
+ elif tier =='free':
313
+ period_limit_terminal ="\n║ 📊 Báo cáo tài chính: Giới hạn 8 kỳ (phiên bản cộng đồng) ║\n║ Nâng cấp: https://vnstocks.com/insiders-program ║"
266
314
  fallback["terminal"] = (
267
- """
315
+ f"""
268
316
  ╔════════════════════════════════════════════════════════════╗
269
317
  ║ ║
270
318
  ║ 👋 Chào mừng bạn đến với Vnstock! ║
@@ -273,7 +321,7 @@ Khám phá các tính năng mới nhất và tham gia cộng đồng để nhậ
273
321
  ║ chứng khoán #1 tại Việt Nam ║
274
322
  ║ ║
275
323
  ║ ✓ Tài liệu: https://vnstocks.com/docs ║
276
- ║ ✓ Cộng đồng: https://facebook.com/groups/vnstock.official ║
324
+ ║ ✓ Cộng đồng: https://facebook.com/groups/vnstock.official ║{period_limit_terminal}
277
325
  ║ ║
278
326
  ║ Khám phá các tính năng mới nhất và tham gia ║
279
327
  ║ cộng đồng để nhận hỗ trợ. ║
@@ -281,13 +329,61 @@ Khám phá các tính năng mới nhất và tham gia cộng đồng để nhậ
281
329
  ╚════════════════════════════════════════════════════════════╝
282
330
  """
283
331
  )
332
+ period_limit_simple =""
333
+ if tier =='guest':
334
+ period_limit_simple =" | 📊 Báo cáo tài chính: Giới hạn 4 kỳ"
335
+ elif tier =='free':
336
+ period_limit_simple =" | 📊 Báo cáo tài chính: Giới hạn 8 kỳ"
284
337
  fallback["simple"] = (
285
338
  "👋 Chào mừng bạn đến với Vnstock! "
286
339
  "Tài liệu: https://vnstocks.com/onboard | "
287
340
  "Cộng đồng: https://facebook.com/groups/vnstock.official"
341
+ f"{period_limit_simple}"
288
342
  )
289
343
  return fallback
290
344
  manager = ContentManager()
291
345
 
292
346
  def present(context: str ="init", ad_category: int = AdCategory.FREE) -> None:
293
- manager.present_content(context=context, ad_category=ad_category)
347
+ manager.present_content(context=context, ad_category=ad_category)
348
+
349
+ def get_promotional_message(format_type: str ="terminal") -> str:
350
+ if format_type =="terminal":
351
+ return"""
352
+ ╔═════════════════════════════════════════════════════════════════╗
353
+ ║ ║
354
+ ║ 🚫 ĐANG BỊ CHẶN BỞI GIỚI HẠN API? GIẢI PHÁP Ở ĐÂY! ║
355
+ ║ ║
356
+ ║ ✓ Tăng ngay 10X tốc độ gọi API - Không còn lỗi RateLimit ║
357
+ ║ ✓ Tiết kiệm 85% thời gian chờ đợi giữa các request ║
358
+ ║ ║
359
+ ║ ➤ NÂNG CẤP NGAY VỚI GÓI TÀI TRỢ VNSTOCK: ║
360
+ ║ https://vnstocks.com/insiders-program ║
361
+ ║ ║
362
+ ╚═════════════════════════════════════════════════════════════════╝
363
+ """
364
+ elif format_type =="simple":
365
+ return (
366
+ "🚫 Đang bị giới hạn API? Tăng tốc độ gọi API lên 10X với gói "
367
+ "Vnstock Insider: https://vnstocks.com/insiders-program"
368
+ )
369
+ elif format_type =="html":
370
+ return"""
371
+ <div style="border: 2px solid #e74c3c; padding: 15px; border-radius: 5px; margin: 10px 0; background-color: #fadbd8;">
372
+ <h3 style="color: #c0392b; margin-top: 0;">🚫 ĐANG BỊ CHẶN BỞI GIỚI HẠN API?</h3>
373
+ <p><strong>✓ Tăng ngay 10X tốc độ gọi API - Không còn lỗi RateLimit</strong></p>
374
+ <p><strong>✓ Tiết kiệm 85% thời gian chờ đợi giữa các request</strong></p>
375
+ <p style="margin-bottom: 0;">
376
+ <a href="https://vnstocks.com/insiders-program" style="color: #c0392b; font-weight: bold;">
377
+ ➤ NÂNG CẤP NGAY VỚI GÓI TÀI TRỢ VNSTOCK
378
+ </a>
379
+ </p>
380
+ </div>
381
+ """
382
+ else:
383
+ return get_promotional_message("terminal")
384
+
385
+ def should_show_promotional_for_rate_limit(tier: str) -> bool:
386
+ return manager.should_show_promotional_for_rate_limit(tier)
387
+
388
+ def mark_promotional_shown() -> None:
389
+ manager.mark_promotional_shown()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vnai
3
- Version: 2.1.9
3
+ Version: 2.3.7
4
4
  Summary: Vnstock Analytics Interface
5
5
  Author-email: Vnstock Analytics Team <support@vnstocks.com>
6
6
  License: proprietary
@@ -10,10 +10,11 @@ Classifier: Operating System :: OS Independent
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
- Requires-Python: >=3.7
13
+ Requires-Python: >=3.10
14
14
  Description-Content-Type: text/markdown
15
15
  Requires-Dist: requests>=2.25.0
16
16
  Requires-Dist: psutil>=5.8.0
17
+ Requires-Dist: cffi>=1.17.1
17
18
  Provides-Extra: dev
18
19
  Requires-Dist: pytest>=6.0.0; extra == "dev"
19
20
 
@@ -0,0 +1,23 @@
1
+ vnai/__init__.py,sha256=LjSVIZnlr88sAYTKLTaycLGyPrAwXDtYIBxRPhziWQA,11389
2
+ vnai/beam/__init__.py,sha256=P9URuUI3H8PAKWo0OSAbwT5Tv3r1ANoGhv3ZQCFopv4,949
3
+ vnai/beam/auth.py,sha256=o22q4mHngFtt4_BLn1ytkhIeX-CcqslXqk0AZAr-ygU,11958
4
+ vnai/beam/fundamental.py,sha256=sqKutOsnDCRL_h7fAMZw3uAFIFEL5jDq-BN9u1OgQkg,7674
5
+ vnai/beam/metrics.py,sha256=2BmdJl7gB4rHwCN7G7WUMg_6rnlY3xfulBzU7usqNfE,6275
6
+ vnai/beam/patching.py,sha256=Kd-Q-73C97xEUUa9bnZcmCr2rWCpnof6lX5Fg_hd8jM,10322
7
+ vnai/beam/pulse.py,sha256=xu7cStqdkCw8be_yVwfjGtqdy-stYC511oZOkT9j6hs,2485
8
+ vnai/beam/quota.py,sha256=_dmsDhB0PGCA0W044sWvLGK9p9r60KePdxRvVZv6mjE,17035
9
+ vnai/beam/sync.py,sha256=Pfr4CziIoWwebPt0p6nTvsLlIqZuXebMcuIyTNzTk_I,3497
10
+ vnai/flow/__init__.py,sha256=9JepoOHS1xn0_ZrDyfft42g2cjhaka7xdG0velqmk-I,70
11
+ vnai/flow/queue.py,sha256=9dyMwxen1vCiFJ7wNZn-kzMY8DnB4xD575J1pPSWZLw,3223
12
+ vnai/flow/relay.py,sha256=I76uSJXnMOZs77x-pdnsuDy7vSdGh2lp4QBSGJ1_9gY,12791
13
+ vnai/scope/__init__.py,sha256=mOPU5J0y3PgmTT9IVG9geYNQASADpu8Lc-GPvA5mDQ4,376
14
+ vnai/scope/device.py,sha256=qnWTQ0MvUBsZDo0lYEx7lbyRmQX0XuTNAYd30AbS5J4,10825
15
+ vnai/scope/lc_integration.py,sha256=M2XfNIHeMT5maLACPmQFv601AF1Kx-sYw6FiOKGL9oU,12101
16
+ vnai/scope/license.py,sha256=Su10AeGAn6n-XYVTZoW3f2jOqp0tNAoR4Ixqr8Q12NU,6852
17
+ vnai/scope/profile.py,sha256=b4rruVF3m2D_vzimmgVmjNkdjTF_2ci1xeEh40WHWlk,22439
18
+ vnai/scope/promo.py,sha256=k7jaGLXl1U5nW3Ut-tg3qEAVJ0k_zMZ1qY4kzqPRB-0,18517
19
+ vnai/scope/state.py,sha256=ApzP6U0Hzp047-k3czL933soUXiZjpZSxXk7DKwf7yM,5389
20
+ vnai-2.3.7.dist-info/METADATA,sha256=1xTTK6p2emi3NBCLR0Jywo5KXr51RVQNWKG4_xkriDQ,691
21
+ vnai-2.3.7.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
22
+ vnai-2.3.7.dist-info/top_level.txt,sha256=4zI0qZHePCwvgSqXl4420sBcd0VzZn4MEcRsAIFae3k,5
23
+ vnai-2.3.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,16 +0,0 @@
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,,