Browse Source

remove server from globals

Falko Schindler 1 year ago
parent
commit
b7756b2bf9
7 changed files with 51 additions and 34 deletions
  1. 2 0
      nicegui/__init__.py
  2. 2 1
      nicegui/app.py
  3. 0 2
      nicegui/globals.py
  4. 2 1
      nicegui/native_mode.py
  5. 6 28
      nicegui/run.py
  6. 37 0
      nicegui/server.py
  7. 2 2
      tests/screen.py

+ 2 - 0
nicegui/__init__.py

@@ -6,6 +6,7 @@ from .awaitable_response import AwaitableResponse
 from .client import Client
 from .client import Client
 from .logging import log
 from .logging import log
 from .nicegui import app
 from .nicegui import app
+from .server import Server
 from .tailwind import Tailwind
 from .tailwind import Tailwind
 from .version import __version__
 from .version import __version__
 
 
@@ -20,6 +21,7 @@ __all__ = [
     'log',
     'log',
     'optional_features',
     'optional_features',
     'run',
     'run',
+    'Server',
     'Tailwind',
     'Tailwind',
     'ui',
     'ui',
     '__version__',
     '__version__',

+ 2 - 1
nicegui/app.py

@@ -12,6 +12,7 @@ from .client import Client
 from .logging import log
 from .logging import log
 from .native import Native
 from .native import Native
 from .observables import ObservableSet
 from .observables import ObservableSet
+from .server import Server
 from .storage import Storage
 from .storage import Storage
 
 
 
 
@@ -126,7 +127,7 @@ class App(FastAPI):
         if self.native.main_window:
         if self.native.main_window:
             self.native.main_window.destroy()
             self.native.main_window.destroy()
         else:
         else:
-            globals.server.should_exit = True
+            Server.instance.should_exit = True
 
 
     def add_static_files(self, url_path: str, local_directory: Union[str, Path]) -> None:
     def add_static_files(self, url_path: str, local_directory: Union[str, Path]) -> None:
         """Add a directory of static files.
         """Add a directory of static files.

+ 0 - 2
nicegui/globals.py

@@ -5,7 +5,6 @@ from pathlib import Path
 from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Union
 from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Union
 
 
 from socketio import AsyncServer
 from socketio import AsyncServer
-from uvicorn import Server
 
 
 if TYPE_CHECKING:
 if TYPE_CHECKING:
     from .app import App
     from .app import App
@@ -13,7 +12,6 @@ if TYPE_CHECKING:
 
 
 app: App
 app: App
 sio: AsyncServer
 sio: AsyncServer
-server: Server
 loop: Optional[asyncio.AbstractEventLoop] = None
 loop: Optional[asyncio.AbstractEventLoop] = None
 ui_run_has_been_called: bool = False
 ui_run_has_been_called: bool = False
 
 

+ 2 - 1
nicegui/native_mode.py

@@ -13,6 +13,7 @@ from typing import Any, Callable, Dict, List, Tuple
 
 
 from . import globals, helpers, native, optional_features  # pylint: disable=redefined-builtin
 from . import globals, helpers, native, optional_features  # pylint: disable=redefined-builtin
 from .logging import log
 from .logging import log
+from .server import Server
 
 
 try:
 try:
     with warnings.catch_warnings():
     with warnings.catch_warnings():
@@ -97,7 +98,7 @@ def activate(host: str, port: int, title: str, width: int, height: int, fullscre
     def check_shutdown() -> None:
     def check_shutdown() -> None:
         while process.is_alive():
         while process.is_alive():
             time.sleep(0.1)
             time.sleep(0.1)
-        globals.server.should_exit = True
+        Server.instance.should_exit = True
         while not globals.app.is_stopped:
         while not globals.app.is_stopped:
             time.sleep(0.1)
             time.sleep(0.1)
         _thread.interrupt_main()
         _thread.interrupt_main()

+ 6 - 28
nicegui/run.py

@@ -1,47 +1,25 @@
 import multiprocessing
 import multiprocessing
 import os
 import os
-import socket
 import sys
 import sys
 from pathlib import Path
 from pathlib import Path
 from typing import Any, List, Literal, Optional, Tuple, Union
 from typing import Any, List, Literal, Optional, Tuple, Union
 
 
 import __main__
 import __main__
-import uvicorn
 from starlette.routing import Route
 from starlette.routing import Route
 from uvicorn.main import STARTUP_FAILURE
 from uvicorn.main import STARTUP_FAILURE
 from uvicorn.supervisors import ChangeReload, Multiprocess
 from uvicorn.supervisors import ChangeReload, Multiprocess
 
 
 from . import native_mode  # pylint: disable=redefined-builtin
 from . import native_mode  # pylint: disable=redefined-builtin
-from . import storage  # pylint: disable=redefined-builtin
 from . import air, globals, helpers  # pylint: disable=redefined-builtin
 from . import air, globals, helpers  # pylint: disable=redefined-builtin
 from . import native as native_module
 from . import native as native_module
 from .client import Client
 from .client import Client
 from .language import Language
 from .language import Language
 from .logging import log
 from .logging import log
+from .server import CustomServerConfig, Server
 
 
 APP_IMPORT_STRING = 'nicegui:app'
 APP_IMPORT_STRING = 'nicegui:app'
 
 
 
 
-class CustomServerConfig(uvicorn.Config):
-    storage_secret: Optional[str] = None
-    method_queue: Optional[multiprocessing.Queue] = None
-    response_queue: Optional[multiprocessing.Queue] = None
-
-
-class Server(uvicorn.Server):
-
-    def run(self, sockets: Optional[List[socket.socket]] = None) -> None:
-        globals.server = self
-        assert isinstance(self.config, CustomServerConfig)
-        if self.config.method_queue is not None and self.config.response_queue is not None:
-            native_module.method_queue = self.config.method_queue
-            native_module.response_queue = self.config.response_queue
-            globals.app.native.main_window = native_module.WindowProxy()
-
-        storage.set_storage_secret(self.config.storage_secret)
-        super().run(sockets=sockets)
-
-
 def run(*,
 def run(*,
         host: Optional[str] = None,
         host: Optional[str] = None,
         port: int = 8080,
         port: int = 8080,
@@ -171,7 +149,7 @@ def run(*,
     config.storage_secret = storage_secret
     config.storage_secret = storage_secret
     config.method_queue = native_module.method_queue if native else None
     config.method_queue = native_module.method_queue if native else None
     config.response_queue = native_module.response_queue if native else None
     config.response_queue = native_module.response_queue if native else None
-    globals.server = Server(config=config)
+    Server.create_singleton(config)
 
 
     if (reload or config.workers > 1) and not isinstance(config.app, str):
     if (reload or config.workers > 1) and not isinstance(config.app, str):
         log.warning('You must pass the application as an import string to enable "reload" or "workers".')
         log.warning('You must pass the application as an import string to enable "reload" or "workers".')
@@ -179,14 +157,14 @@ def run(*,
 
 
     if config.should_reload:
     if config.should_reload:
         sock = config.bind_socket()
         sock = config.bind_socket()
-        ChangeReload(config, target=globals.server.run, sockets=[sock]).run()
+        ChangeReload(config, target=Server.instance.run, sockets=[sock]).run()
     elif config.workers > 1:
     elif config.workers > 1:
         sock = config.bind_socket()
         sock = config.bind_socket()
-        Multiprocess(config, target=globals.server.run, sockets=[sock]).run()
+        Multiprocess(config, target=Server.instance.run, sockets=[sock]).run()
     else:
     else:
-        globals.server.run()
+        Server.instance.run()
     if config.uds:
     if config.uds:
         os.remove(config.uds)  # pragma: py-win32
         os.remove(config.uds)  # pragma: py-win32
 
 
-    if not globals.server.started and not config.should_reload and config.workers == 1:
+    if not Server.instance.started and not config.should_reload and config.workers == 1:
         sys.exit(STARTUP_FAILURE)
         sys.exit(STARTUP_FAILURE)

+ 37 - 0
nicegui/server.py

@@ -0,0 +1,37 @@
+from __future__ import annotations
+
+import multiprocessing
+import socket
+from typing import List, Optional
+
+import uvicorn
+
+from . import globals  # pylint: disable=redefined-builtin
+from . import storage  # pylint: disable=redefined-builtin
+from . import native as native_module
+
+
+class CustomServerConfig(uvicorn.Config):
+    storage_secret: Optional[str] = None
+    method_queue: Optional[multiprocessing.Queue] = None
+    response_queue: Optional[multiprocessing.Queue] = None
+
+
+class Server(uvicorn.Server):
+    instance: Server
+
+    @classmethod
+    def create_singleton(cls, config: CustomServerConfig) -> None:
+        """Create a singleton instance of the server."""
+        cls.instance = cls(config=config)
+
+    def run(self, sockets: Optional[List[socket.socket]] = None) -> None:
+        self.instance = self
+        assert isinstance(self.config, CustomServerConfig)
+        if self.config.method_queue is not None and self.config.response_queue is not None:
+            native_module.method_queue = self.config.method_queue
+            native_module.response_queue = self.config.response_queue
+            globals.app.native.main_window = native_module.WindowProxy()
+
+        storage.set_storage_secret(self.config.storage_secret)
+        super().run(sockets=sockets)

+ 2 - 2
tests/screen.py

@@ -12,7 +12,7 @@ from selenium.webdriver import ActionChains
 from selenium.webdriver.common.by import By
 from selenium.webdriver.common.by import By
 from selenium.webdriver.remote.webelement import WebElement
 from selenium.webdriver.remote.webelement import WebElement
 
 
-from nicegui import app, globals, ui  # pylint: disable=redefined-builtin
+from nicegui import Server, app, ui
 
 
 from .test_helpers import TEST_DIR
 from .test_helpers import TEST_DIR
 
 
@@ -49,7 +49,7 @@ class Screen:
         """Stop the webserver."""
         """Stop the webserver."""
         self.close()
         self.close()
         self.caplog.clear()
         self.caplog.clear()
-        globals.server.should_exit = True
+        Server.instance.should_exit = True
         if self.server_thread:
         if self.server_thread:
             self.server_thread.join()
             self.server_thread.join()