Parcourir la source

use custom uvicorn Server which provides message_queue
neccessary for pywebview when running as subprocess with reload=True

Rodja Trappe il y a 2 ans
Parent
commit
23f9dd9ed8
3 fichiers modifiés avec 22 ajouts et 18 suppressions
  1. 3 7
      nicegui/native.py
  2. 4 8
      nicegui/native_mode.py
  3. 15 3
      nicegui/run.py

+ 3 - 7
nicegui/native.py

@@ -8,8 +8,7 @@ import webview
 
 from .helpers import KWONLY_SLOTS
 
-q_in = Queue()
-q_out = Queue()
+queue = Queue()
 
 
 def create_proxy(cls):
@@ -24,14 +23,11 @@ def create_proxy(cls):
             if name.startswith('__'):
                 super().__setattr__(name, value)
                 return
-
-            print(f"Attribute set: {name} = {value}")
-            q_in.put(('some_method', (42,), {}))
-            # result = q_out.get()
+            queue.put((name, (value,), {}))
 
     def mock_method(name):
         def wrapper(*args, **kwargs):
-            print(f"Method called: {name}")
+            queue.put((name, args[1:], kwargs))  # NOTE args[1:] to skip self
         return wrapper
 
     for name, attr in inspect.getmembers(cls):

+ 4 - 8
nicegui/native_mode.py

@@ -21,7 +21,7 @@ except ModuleNotFoundError:
 
 
 def open_window(host: str, port: int, title: str, width: int, height: int, fullscreen: bool,
-                q_in: multiprocessing.Queue, q_out: multiprocessing.Queue) -> None:
+                message_queue: multiprocessing.Queue) -> None:
     while not helpers.is_port_open(host, port):
         time.sleep(0.1)
 
@@ -35,15 +35,12 @@ def open_window(host: str, port: int, title: str, width: int, height: int, fulls
         def process_bridge():
             time.sleep(1)
             while True:
-                print('getting', flush=True)
                 try:
-                    result = q_in.get(block=False)
-                    print(result, flush=True)
+                    result = message_queue.get(block=False)
+                    print(f'received {result}', flush=True)
                 except queue.Empty:
                     print('empty', flush=True)
                     time.sleep(1)
-                # result = getattr(window, method_name)(*args, **kwargs)
-                # q_out.put(result)
         t = Thread(target=process_bridge)
         t.start()
 
@@ -65,11 +62,10 @@ def activate(host: str, port: int, title: str, width: int, height: int, fullscre
     multiprocessing.freeze_support()
     process = multiprocessing.Process(
         target=open_window,
-        args=(host, port, title, width, height, fullscreen, native.q_in, native.q_out),
+        args=(host, port, title, width, height, fullscreen, native.queue),
         daemon=False
     )
     process.start()
-    native.q_in.put(('some_method', (42,), {}))
 
     Thread(target=check_shutdown, daemon=True).start()
 

+ 15 - 3
nicegui/run.py

@@ -9,10 +9,22 @@ import uvicorn
 from uvicorn.main import STARTUP_FAILURE
 from uvicorn.supervisors import ChangeReload, Multiprocess
 
-from . import globals, helpers, native_mode
+from . import globals, helpers
+from . import native as app_native
+from . import native_mode
 from .language import Language
 
 
+class Server(uvicorn.Server):
+    def __init__(self, config):
+        super().__init__(config)
+
+    def run(self, sockets=None):
+        globals.server = self
+        app_native.queue = self.config.native_queue
+        super().run(sockets=sockets)
+
+
 def run(*,
         host: Optional[str] = None,
         port: int = 8080,
@@ -115,8 +127,8 @@ def run(*,
         log_level=uvicorn_logging_level,
         **kwargs,
     )
-    globals.server = uvicorn.Server(config=config)
-
+    config.native_queue = app_native.queue
+    globals.server = Server(config=config)
     if (reload or config.workers > 1) and not isinstance(config.app, str):
         logging.warning('You must pass the application as an import string to enable "reload" or "workers".')
         sys.exit(1)