@danhachuel/thunderbolt 0.5.55 → 0.5.56

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.5.55",
3
+ "version": "0.5.56",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "license": "MIT",
6
6
  "main": "scripts/cli.mjs",
@@ -1,9 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import asyncio
3
4
  import io
5
+ import logging
4
6
  import os
5
7
  import signal
6
8
  import sys
9
+ import time
7
10
 
8
11
  # Este ficheiro é o primeiro módulo Python executado pelo launcher. As
9
12
  # variáveis e os streams precisam de ser corrigidos antes de qualquer import
@@ -14,6 +17,12 @@ os.environ["PYTHONLEGACYWINDOWSSTDIO"] = "1"
14
17
  os.environ["CLICK_NO_WIN_CONSOLE"] = "1"
15
18
 
16
19
 
20
+ # O shutdown do Streamlit pode emitir tracebacks assíncronos depois de SIGINT.
21
+ # Estes níveis só afectam a saída de encerramento, não os logs da aplicação.
22
+ logging.getLogger("uvicorn").setLevel(logging.CRITICAL)
23
+ logging.getLogger("streamlit").setLevel(logging.CRITICAL)
24
+
25
+
17
26
  def _utf8_stream(stream: object) -> object:
18
27
  if os.name != "nt":
19
28
  return stream
@@ -30,10 +39,26 @@ sys.stdout = _utf8_stream(sys.stdout)
30
39
  sys.stderr = _utf8_stream(sys.stderr)
31
40
 
32
41
 
42
+ _shutdown_started = False
43
+
44
+
33
45
  def _custom_sigint_handler(signum: int, frame: object) -> None:
34
- """Encerrar sem executar ``server.stop``/Click do handler do Streamlit."""
46
+ """Parar o loop, dar uma pequena janela de drenagem e sair sem traceback."""
47
+ global _shutdown_started
48
+ if _shutdown_started:
49
+ return
50
+ _shutdown_started = True
35
51
  print("\nEncerrando servidor...", file=sys.stderr, flush=True)
36
- raise SystemExit(0)
52
+ try:
53
+ loop = asyncio.get_running_loop()
54
+ except RuntimeError:
55
+ loop = None
56
+ if loop is not None and not loop.is_closed():
57
+ loop.call_soon_threadsafe(loop.stop)
58
+ # O processo pai (cli.mjs) encerra proxy e workers quando o filho termina.
59
+ # os._exit evita que callbacks tardios do Streamlit imprimam tracebacks.
60
+ time.sleep(0.5)
61
+ os._exit(0)
37
62
 
38
63
 
39
64
  _original_signal = signal.signal