bizyengine 1.2.55__py3-none-any.whl → 1.2.57__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.
@@ -1,34 +1,40 @@
1
- from .nodes_advanced_refluxcontrol import *
2
- from .nodes_cogview4 import *
3
- from .nodes_comfyui_detail_daemon import *
4
- from .nodes_comfyui_instantid import *
5
- from .nodes_comfyui_layerstyle_advance import *
6
- from .nodes_comfyui_pulid_flux import *
7
- from .nodes_controlnet import *
8
- from .nodes_custom_sampler import *
9
- from .nodes_dataset import *
10
- from .nodes_differential_diffusion import *
11
- from .nodes_flux import *
12
- from .nodes_gemini import *
13
- from .nodes_hunyuan3d import *
14
- from .nodes_image_utils import *
15
- from .nodes_ip2p import *
16
- from .nodes_ipadapter_plus.nodes_ipadapter_plus import *
17
- from .nodes_janus_pro import *
18
- from .nodes_kolors_mz import *
19
- from .nodes_model_advanced import *
20
- from .nodes_nunchaku import *
21
- from .nodes_reactor import *
22
- from .nodes_sam2 import *
23
- from .nodes_sd3 import *
24
- from .nodes_seedream import *
25
- from .nodes_segment_anything import *
26
- from .nodes_testing_utils import *
27
- from .nodes_trellis import *
28
- from .nodes_ultimatesdupscale import *
29
- from .nodes_upscale_model import *
30
- from .nodes_utils import *
31
- from .nodes_wan_api import *
32
- from .nodes_wan_i2v import *
33
- from .nodes_wan_video import *
34
- from .route_bizyair_tools import *
1
+ modules = [
2
+ ".nodes_advanced_refluxcontrol",
3
+ ".nodes_cogview4",
4
+ ".nodes_comfyui_detail_daemon",
5
+ ".nodes_comfyui_instantid",
6
+ ".nodes_comfyui_layerstyle_advance",
7
+ ".nodes_comfyui_pulid_flux",
8
+ ".nodes_controlnet",
9
+ ".nodes_custom_sampler",
10
+ ".nodes_dataset",
11
+ ".nodes_differential_diffusion",
12
+ ".nodes_flux",
13
+ ".nodes_gemini",
14
+ ".nodes_hunyuan3d",
15
+ ".nodes_image_utils",
16
+ ".nodes_ip2p",
17
+ ".nodes_ipadapter_plus.nodes_ipadapter_plus",
18
+ ".nodes_janus_pro",
19
+ ".nodes_kolors_mz",
20
+ ".nodes_model_advanced",
21
+ ".nodes_nunchaku",
22
+ ".nodes_reactor",
23
+ ".nodes_sam2",
24
+ ".nodes_sd3",
25
+ ".nodes_seedream",
26
+ ".nodes_segment_anything",
27
+ ".nodes_testing_utils",
28
+ ".nodes_trellis",
29
+ ".nodes_ultimatesdupscale",
30
+ ".nodes_upscale_model",
31
+ ".nodes_utils",
32
+ ".nodes_wan_api",
33
+ ".nodes_wan_i2v",
34
+ ".nodes_wan_video",
35
+ ".route_bizyair_tools",
36
+ ]
37
+ from bizyengine.core.common.utils import safe_star_import
38
+
39
+ for mod in modules:
40
+ safe_star_import(mod, package=__package__)
@@ -160,7 +160,7 @@ def send_request(
160
160
  req = urllib.request.Request(
161
161
  url, data=data, headers=headers, method=method, **kwargs
162
162
  )
163
- with urllib.request.urlopen(req) as response:
163
+ with urllib.request.urlopen(req, timeout=600) as response:
164
164
  response_data = response.read().decode("utf-8")
165
165
 
166
166
  except urllib.error.URLError as e:
@@ -252,7 +252,9 @@ async def async_send_request(
252
252
  ) -> dict:
253
253
  headers = kwargs.pop("headers") if "headers" in kwargs else _headers()
254
254
  try:
255
- async with aiohttp.ClientSession() as session:
255
+ async with aiohttp.ClientSession(
256
+ timeout=aiohttp.ClientTimeout(total=600)
257
+ ) as session:
256
258
  async with session.request(
257
259
  method, url, data=data, headers=headers, **kwargs
258
260
  ) as response:
@@ -1,7 +1,10 @@
1
1
  import copy
2
+ import importlib
2
3
  import json
3
4
  import os
4
- from typing import Any, List
5
+ import sys
6
+ import traceback
7
+ from typing import Any, List, Optional
5
8
 
6
9
  import torch
7
10
  import yaml
@@ -91,3 +94,29 @@ def load_config_file(file_path: str) -> dict:
91
94
  return _load_yaml_config(file_path)
92
95
  else:
93
96
  raise ValueError(f"Unsupported file extension: {file_path}")
97
+
98
+
99
+ def safe_star_import(module: str, package: Optional[str] = None) -> None:
100
+ """
101
+ 在模块级执行 from module import * (支持相对导入)
102
+ 失败时打印异常,不终止程序
103
+ :param module: 模块名,可带前导点,如 '.nodes_advanced_refluxcontrol'
104
+ :param package: 当前包名,如 'ui.nodes';若 module 为相对导入则必须传
105
+ """
106
+ try:
107
+ # 1. 导入模块(相对导入必须传 package)
108
+ mod = importlib.import_module(module, package=package)
109
+ # 2. 取 __all__ 或全部非下划线名字
110
+ names = getattr(mod, "__all__", None)
111
+ if names is None:
112
+ names = [k for k in mod.__dict__ if not k.startswith("_")]
113
+ # 3. 注入到调用者 globals
114
+ caller_globals = sys._getframe(1).f_globals
115
+ for name in names:
116
+ caller_globals[name] = getattr(mod, name)
117
+ except Exception as e:
118
+ print(
119
+ f"\033[92m[BizyAir]\033[0m safe_star_import {module} failed: {e}",
120
+ file=sys.stderr,
121
+ )
122
+ traceback.print_exc()
bizyengine/misc/llm.py CHANGED
@@ -381,22 +381,39 @@ class BizyAirJoyCaption2(BizyAirMiscBaseNode):
381
381
  )
382
382
 
383
383
  try:
384
- if "result" in ret:
385
- ret = json.loads(ret["result"])
386
- if ret["type"] == "error":
387
- raise Exception(ret["message"])
384
+ if isinstance(ret, dict) and "result" in ret:
385
+ if isinstance(ret["result"], str):
386
+ ret = json.loads(ret["result"])
387
+
388
+ if not isinstance(ret, dict):
389
+ raise ValueError(
390
+ f"Response is not a dictionary after processing: {ret}"
391
+ )
392
+
393
+ if ret.get("type") == "error":
394
+ error_message = ret.get("message", "Unknown error from API")
395
+ raise Exception(f"API returned an error: {error_message}")
396
+
397
+ msg = ret["data"]
398
+ if not isinstance(msg, dict) or msg.get("type") not in (
399
+ "comfyair",
400
+ "bizyair",
401
+ ):
402
+ raise Exception(f"Unexpected response type: {msg}")
403
+
404
+ caption = msg["data"]
405
+ return (caption,)
406
+
407
+ except json.JSONDecodeError as e:
408
+ raise Exception(f"Failed to parse JSON response: {ret}. Error: {e}")
409
+ except (KeyError, TypeError) as e:
410
+ raise Exception(
411
+ f"Invalid response format, missing key or wrong type. Response: {ret}. Error: {e}"
412
+ )
388
413
  except Exception as e:
389
- raise Exception(f"Unexpected response: {ret} {e=}")
390
-
391
- msg = ret["data"]
392
- if msg["type"] not in (
393
- "comfyair",
394
- "bizyair",
395
- ):
396
- raise Exception(f"Unexpected response type: {msg}")
397
-
398
- caption = msg["data"]
399
- return (caption,)
414
+ raise Exception(
415
+ f"An unexpected error occurred while processing the response: {ret}. Error: {e}"
416
+ )
400
417
 
401
418
 
402
419
  class BizyAirJoyCaption3(BizyAirJoyCaption2):
bizyengine/misc/utils.py CHANGED
@@ -1,14 +1,21 @@
1
+ import asyncio
1
2
  import base64
3
+ import concurrent.futures
2
4
  import json
5
+ import logging
3
6
  import os
4
7
  import pickle
8
+ import re
9
+ import threading
10
+ import time
5
11
  import urllib.parse
6
12
  import urllib.request
7
13
  import zlib
8
- from typing import List, Tuple, Union
14
+ from typing import Callable, Dict, Generic, List, Optional, Tuple, TypeVar, Union
9
15
 
10
16
  import numpy as np
11
17
 
18
+ from bizyengine.bizy_server.api_client import APIClient
12
19
  from bizyengine.core import pop_api_key_and_prompt_id
13
20
  from bizyengine.core.common import client
14
21
  from bizyengine.core.common.env_var import BIZYAIR_SERVER_ADDRESS
@@ -36,7 +43,7 @@ def send_post_request(api_url, payload, headers):
36
43
  try:
37
44
  data = json.dumps(payload).encode("utf-8")
38
45
  req = urllib.request.Request(api_url, data=data, headers=headers, method="POST")
39
- with urllib.request.urlopen(req) as response:
46
+ with urllib.request.urlopen(req, timeout=600) as response:
40
47
  response_data = response.read().decode("utf-8")
41
48
  return response_data
42
49
  except urllib.error.URLError as e:
@@ -143,6 +150,18 @@ def get_llm_response(
143
150
  extra_data = pop_api_key_and_prompt_id(kwargs)
144
151
  headers = client.headers(api_key=extra_data["api_key"])
145
152
 
153
+ # 如果model已不可用,选择第一个可用model
154
+ if _MODELS_CACHE.get("llm_models") is None:
155
+ cache_models(extra_data["api_key"])
156
+ llm_models = _MODELS_CACHE.get("llm_models")
157
+ if llm_models is None:
158
+ logging.warning(f"No LLM models available, keeping the original model {model}")
159
+ elif model not in llm_models:
160
+ logging.warning(
161
+ f"Model {model} is not available, using the first available model {llm_models[0]}"
162
+ )
163
+ model = llm_models[0]
164
+
146
165
  payload = {
147
166
  "model": model,
148
167
  "messages": [
@@ -183,6 +202,18 @@ def get_vlm_response(
183
202
  extra_data = pop_api_key_and_prompt_id(kwargs)
184
203
  headers = client.headers(api_key=extra_data["api_key"])
185
204
 
205
+ # 如果model已不可用,选择第一个可用model
206
+ if _MODELS_CACHE.get("vlm_models") is None:
207
+ cache_models(extra_data["api_key"])
208
+ vlm_models = _MODELS_CACHE.get("vlm_models")
209
+ if vlm_models is None:
210
+ logging.warning(f"No VLM models available, keeping the original model {model}")
211
+ elif model not in vlm_models:
212
+ logging.warning(
213
+ f"Model {model} is not available, using the first available model {vlm_models[0]}"
214
+ )
215
+ model = vlm_models[0]
216
+
186
217
  messages = [
187
218
  {
188
219
  "role": "system",
@@ -230,3 +261,149 @@ def get_vlm_response(
230
261
  callback=None,
231
262
  )
232
263
  return response
264
+
265
+
266
+ K = TypeVar("K")
267
+ V = TypeVar("V")
268
+ R = TypeVar("R")
269
+
270
+
271
+ class TTLCache(Generic[K, V]):
272
+ """线程安全 TTL 内存缓存(仅依赖标准库)"""
273
+
274
+ def __init__(self, ttl_sec: float):
275
+ self.ttl = ttl_sec
276
+ self._data: Dict[K, tuple[V, float]] = {}
277
+ self._lock = threading.RLock()
278
+ self._stop_evt = threading.Event()
279
+ # 后台清扫线程
280
+ self._cleaner = threading.Thread(target=self._cleanup, daemon=True)
281
+ self._cleaner.start()
282
+
283
+ # ---------- 公共 API ----------
284
+ def set(self, key: K, value: V) -> None:
285
+ """写入/刷新键值"""
286
+ with self._lock:
287
+ self._data[key] = (value, time.time() + self.ttl)
288
+
289
+ def get(self, key: K) -> Optional[V]:
290
+ """读取键值;不存在或已过期返回 None"""
291
+ with self._lock:
292
+ val, expire = self._data.get(key, (None, 0))
293
+ if val is None or time.time() > expire:
294
+ self._data.pop(key, None)
295
+ return None
296
+ return val
297
+
298
+ def delete(self, key: K) -> None:
299
+ """手动删除"""
300
+ with self._lock:
301
+ self._data.pop(key, None)
302
+
303
+ def stop(self):
304
+ """停止后台线程(程序退出前调用)"""
305
+ self._stop_evt.set()
306
+ self._cleaner.join(timeout=self.ttl + 1)
307
+
308
+ # ---------- 内部 ----------
309
+ def _cleanup(self):
310
+ """周期清扫过期键"""
311
+ while not self._stop_evt.wait(self.ttl / 2):
312
+ with self._lock:
313
+ now = time.time()
314
+ for key, (_, expire) in list(self._data.items()):
315
+ if now > expire:
316
+ self._data.pop(key, None)
317
+
318
+
319
+ class SingleFlight(Generic[R]):
320
+ """Python 版 singleflight.Group(线程安全)"""
321
+
322
+ def __init__(self):
323
+ self._lock = threading.Lock()
324
+ self._call_map: dict[str, SingleFlight._Call[R]] = {}
325
+
326
+ class _Call(Generic[R]):
327
+ __slots__ = ("mu", "done", "result", "err", "waiters")
328
+
329
+ def __init__(self):
330
+ self.mu = threading.Lock()
331
+ self.done = False
332
+ self.result: Optional[R] = None
333
+ self.err: Optional[BaseException] = None
334
+ self.waiters = 0
335
+
336
+ def do(
337
+ self, key: str, fn: Callable[[], R]
338
+ ) -> tuple[R, bool, Optional[BaseException]]:
339
+ """
340
+ 返回值: (result, shared?, exception)
341
+ shared=True 表示本次未真正执行 fn,复用了别人结果
342
+ """
343
+ with self._lock:
344
+ call = self._call_map.get(key)
345
+ if call is None: # 我是第一个
346
+ call = self._Call[R]()
347
+ call.waiters = 1
348
+ self._call_map[key] = call
349
+ first = True
350
+ else: # 已有并发请求
351
+ call.waiters += 1
352
+ first = False
353
+
354
+ if first: # 只有第一个真正执行
355
+ try:
356
+ result = fn()
357
+ with call.mu:
358
+ call.result = result
359
+ call.done = True
360
+ except BaseException as e:
361
+ with call.mu:
362
+ call.err = e
363
+ call.done = True
364
+ raise
365
+ finally: # 把自己从 map 摘掉
366
+ with self._lock:
367
+ if call.waiters == 0:
368
+ self._call_map.pop(key, None)
369
+ else: # 其它人阻塞等待
370
+ with call.mu:
371
+ while not call.done:
372
+ call.mu.wait()
373
+ # 读取结果
374
+ with call.mu:
375
+ if call.err is not None:
376
+ return call.result, True, call.err
377
+ return call.result, True, None
378
+
379
+
380
+ _MODELS_CACHE = TTLCache[str, list[str]](ttl_sec=600)
381
+ _SF = SingleFlight[None]()
382
+
383
+
384
+ def cache_models(request_api_key: str):
385
+ # TODO: 效果待验证,目前节点只会被ComfyUI串行执行,所以不会出现竞争
386
+ _SF.do("_cache_models", lambda: _cache_models(request_api_key))
387
+
388
+
389
+ def _cache_models(request_api_key: str):
390
+ # ① 开一条新线程专门跑协程 - 应该不需要在prompt那层上锁,因为并发只有1
391
+ with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
392
+ api_client = APIClient()
393
+ all_models = pool.submit(
394
+ asyncio.run, api_client.fetch_all_llm_models(request_api_key)
395
+ ).result()
396
+ if len(all_models) == 0:
397
+ return
398
+ llm_models = [
399
+ model
400
+ for model in all_models
401
+ if not (re.search(r"\d+(\.\d+)?v", model.lower()) or "vl" in model.lower())
402
+ ]
403
+ vlm_models = [
404
+ model
405
+ for model in all_models
406
+ if re.search(r"\d+(\.\d+)?v", model.lower()) or "vl" in model.lower()
407
+ ]
408
+ _MODELS_CACHE.set("llm_models", llm_models)
409
+ _MODELS_CACHE.set("vlm_models", vlm_models)
bizyengine/version.txt CHANGED
@@ -1 +1 @@
1
- 1.2.55
1
+ 1.2.57
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bizyengine
3
- Version: 1.2.55
3
+ Version: 1.2.57
4
4
  Summary: [a/BizyAir](https://github.com/siliconflow/BizyAir) Comfy Nodes that can run in any environment.
5
5
  Author-email: SiliconFlow <yaochi@siliconflow.cn>
6
6
  Project-URL: Repository, https://github.com/siliconflow/BizyAir
@@ -1,5 +1,5 @@
1
1
  bizyengine/__init__.py,sha256=GP9V-JM07fz7uv_qTB43QEA2rKdrVJxi5I7LRnn_3ZQ,914
2
- bizyengine/version.txt,sha256=hhQr61vio--euFMt34QKJLejnKYdRuaYW5ZVVyNMlM4,7
2
+ bizyengine/version.txt,sha256=txvxJYLvzIKQ52dHqmS8wu-ETqexjhrTKOe0yuriLUE,7
3
3
  bizyengine/bizy_server/__init__.py,sha256=SP9oSblnPo4KQyh7yOGD26YCskFAcQHAZy04nQBNRIw,200
4
4
  bizyengine/bizy_server/api_client.py,sha256=Z7G5IjaEqSJkF6nLLw2R3bpgBAOi5ClQiUbel6NMXmE,43932
5
5
  bizyengine/bizy_server/errno.py,sha256=RIyvegX3lzpx_1L1q2XVvu3on0kvYgKiUQ8U3ZtyF68,16823
@@ -10,7 +10,7 @@ bizyengine/bizy_server/resp.py,sha256=iOFT5Ud7VJBP2uqkojJIgc3y2ifMjjEXoj0ewneL9l
10
10
  bizyengine/bizy_server/server.py,sha256=isOzHDk2kD6WjdlemeOA7j_xLnZ2vat_NvE1I0bsOFw,57490
11
11
  bizyengine/bizy_server/stream_response.py,sha256=H2XHqlVRtQMhgdztAuG7l8-iV_Pm42u2x6WJ0gNVIW0,9654
12
12
  bizyengine/bizy_server/utils.py,sha256=Kkn-AATZcdaDhg8Rg_EJW6aKqkyiSE2EYmuyOhUwXso,3863
13
- bizyengine/bizyair_extras/__init__.py,sha256=8WBnjvNTDOJoME-lWMUmr51WRqW4UJHCnq1KoUVpVWk,1151
13
+ bizyengine/bizyair_extras/__init__.py,sha256=ZeUPmpn_6aVM9luC-k2jAl017RP2ihYtlLRLKrofryE,1053
14
14
  bizyengine/bizyair_extras/nodes_advanced_refluxcontrol.py,sha256=cecfjrtnjJAty9aNkhz8BlmHUC1NImkFlUDiA0COEa4,2242
15
15
  bizyengine/bizyair_extras/nodes_cogview4.py,sha256=Ni0TDOycczyDhYPvSR68TxGV_wE2uhaxd8MIj-J4-3o,2031
16
16
  bizyengine/bizyair_extras/nodes_comfyui_detail_daemon.py,sha256=i71it24tiGvZ3h-XFWISr4CpZszUtPuz3UrZARYluLk,6169
@@ -75,9 +75,9 @@ bizyengine/core/commands/servers/model_server.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
75
75
  bizyengine/core/commands/servers/prompt_server.py,sha256=e8JhtKRM8nw0kQwe2Ofl-zQtiVqQdbbWRxOqkFmSclM,10873
76
76
  bizyengine/core/common/__init__.py,sha256=GicZw6YeAZk1PsKmFDt9dm1F75zPUlpia9Q_ki5vW1Y,179
77
77
  bizyengine/core/common/caching.py,sha256=hRNsSrfNxgc1zzvBzLVjMY0iMkKqA0TBCr-iYhEpzik,6946
78
- bizyengine/core/common/client.py,sha256=gk8hfw8sjbJJM7zgz5-54YiC25PHibuT1UtgKFTAhO4,10625
78
+ bizyengine/core/common/client.py,sha256=5ZdbmNHNfkNgEvND34wTN9BLHyoe-HcWk_L1G6XmVRw,10700
79
79
  bizyengine/core/common/env_var.py,sha256=1EAW3gOXY2bKouCqrGa583vTJRdDasQ1IsFTnzDg7Dk,3450
80
- bizyengine/core/common/utils.py,sha256=bm-XmSPy83AyjD0v5EfWp6jiO6_5p7rkZ_HQAuVmgmo,3086
80
+ bizyengine/core/common/utils.py,sha256=Jxk4tCURbUhjYBFuHTiQgeUo2w13TYj4upnPTKNNucM,4215
81
81
  bizyengine/core/configs/conf.py,sha256=D_UWG9SSJnK5EhbrfNFryJQ8hUwwdvhOGlq1TielwpI,3830
82
82
  bizyengine/core/configs/models.json,sha256=v-PpSxNuexSPAVlZbXJyn934cfzoaTC76whFSidaRks,3301
83
83
  bizyengine/core/configs/models.yaml,sha256=9yWbx99700yQXd0AdKI19puUhR4I5mmPoSeZ2xaduGM,11854
@@ -86,7 +86,7 @@ bizyengine/core/path_utils/path_manager.py,sha256=tRVAcpsYvfWD-tK7khLvNCZayB0wpU
86
86
  bizyengine/core/path_utils/utils.py,sha256=kQfPQjGU27qF9iyzRxLSRg5cMsd-VixuCUldART7cgY,2394
87
87
  bizyengine/misc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
88
  bizyengine/misc/auth.py,sha256=DwKy4en1a58RgO5TRdE0EMjjEjlxmerNHAOMNVZRacE,2672
89
- bizyengine/misc/llm.py,sha256=d0GEnY7CzDZ9AokBkOsshZ-KC7KpR_VzEcBvHTfwVoc,13528
89
+ bizyengine/misc/llm.py,sha256=hQlu0Plmbi5to6vKT9JvR0RMCA-BZhYe1qLDfOIQrXQ,14339
90
90
  bizyengine/misc/mzkolors.py,sha256=xjJZ5Ct5Wh3WxSOK-ojX7a_fPvl_hA8qWIDKFUwBuvk,2827
91
91
  bizyengine/misc/nodes.py,sha256=DnHqxurkhSrsFie9a0aupKA05NUA_E5IZxq19HDzMCk,44723
92
92
  bizyengine/misc/nodes_controlnet_aux.py,sha256=w7rASZmnBqhZCalDd7oVPjJpx6b31sPFxqlo3aWoAHc,16399
@@ -94,8 +94,8 @@ bizyengine/misc/nodes_controlnet_union_sdxl.py,sha256=fYyu_XMY7mcX1Ad9x30q1tYB8m
94
94
  bizyengine/misc/route_sam.py,sha256=-bMIR2QalfnszipGxSxvDAHGJa5gPSrjkYPb5baaRg4,1561
95
95
  bizyengine/misc/segment_anything.py,sha256=wNKYwlYPMszfwj23524geFZJjZaG4eye65SGaUnh77I,8941
96
96
  bizyengine/misc/supernode.py,sha256=STN9gaxfTSErH8OiHeZa47d8z-G9S0I7fXuJvHQOBFM,4532
97
- bizyengine/misc/utils.py,sha256=CKduySGSMNGlJMImHyZmN-giABY5VUaB88f6Kq-HAV0,6831
98
- bizyengine-1.2.55.dist-info/METADATA,sha256=Sk5fsuDIXdpXOa-yfWzWjOICOiGbK6OHRycSPU6Guo0,734
99
- bizyengine-1.2.55.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
100
- bizyengine-1.2.55.dist-info/top_level.txt,sha256=2zapzqxX-we5cRyJkGf9bd5JinRtXp3-_uDI-xCAnc0,11
101
- bizyengine-1.2.55.dist-info/RECORD,,
97
+ bizyengine/misc/utils.py,sha256=hLGARJ2fkckGBm6_noC38hGT4b6OXUA4dx68eCdTbzc,12913
98
+ bizyengine-1.2.57.dist-info/METADATA,sha256=lgy5VTeQLkdhZzQc8xxX7-uJtTicw0XqR9gZQuYTvGM,734
99
+ bizyengine-1.2.57.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
100
+ bizyengine-1.2.57.dist-info/top_level.txt,sha256=2zapzqxX-we5cRyJkGf9bd5JinRtXp3-_uDI-xCAnc0,11
101
+ bizyengine-1.2.57.dist-info/RECORD,,