Browse Source

improve access to run config

Falko Schindler 1 năm trước cách đây
mục cha
commit
a0c753bf6c

+ 2 - 3
nicegui/app.py

@@ -8,7 +8,7 @@ from fastapi.responses import FileResponse, StreamingResponse
 from fastapi.staticfiles import StaticFiles
 
 from . import background_tasks, helpers
-from .app_config import AppConfig, RunConfig
+from .app_config import AppConfig
 from .client import Client
 from .logging import log
 from .native import NativeConfig
@@ -32,7 +32,6 @@ class App(FastAPI):
         self.storage = Storage()
         self.urls = ObservableSet()
         self._state: State = State.STOPPED
-        self._run_config: RunConfig
         self.config = AppConfig()
 
         self._startup_handlers: List[Union[Callable[..., Any], Awaitable]] = []
@@ -125,7 +124,7 @@ class App(FastAPI):
         This will programmatically stop the server.
         Only possible when auto-reload is disabled.
         """
-        if self._run_config.reload:
+        if self.config.reload:
             raise RuntimeError('calling shutdown() is not supported when auto-reload is enabled')
         if self.native.main_window:
             self.native.main_window.destroy()

+ 43 - 14
nicegui/app_config.py

@@ -6,20 +6,6 @@ from .dataclasses import KWONLY_SLOTS
 from .language import Language
 
 
-@dataclass(**KWONLY_SLOTS)
-class RunConfig:
-    reload: bool
-    title: str
-    viewport: str
-    favicon: Optional[Union[str, Path]]
-    dark: Optional[bool]
-    language: Language
-    binding_refresh_interval: float
-    reconnect_timeout: float
-    tailwind: bool
-    prod_js: bool
-
-
 @dataclass(**KWONLY_SLOTS)
 class AppConfig:
     endpoint_documentation: Literal['none', 'internal', 'page', 'all'] = 'none'
@@ -37,3 +23,46 @@ class AppConfig:
                 'skipHijack': False,
             },
         })
+
+    reload: bool = field(init=False)
+    title: str = field(init=False)
+    viewport: str = field(init=False)
+    favicon: Optional[Union[str, Path]] = field(init=False)
+    dark: Optional[bool] = field(init=False)
+    language: Language = field(init=False)
+    binding_refresh_interval: float = field(init=False)
+    reconnect_timeout: float = field(init=False)
+    tailwind: bool = field(init=False)
+    prod_js: bool = field(init=False)
+    _has_run_config: bool = False
+
+    def add_run_config(self,
+                       *,
+                       reload: bool,
+                       title: str,
+                       viewport: str,
+                       favicon: Optional[Union[str, Path]],
+                       dark: Optional[bool],
+                       language: Language,
+                       binding_refresh_interval: float,
+                       reconnect_timeout: float,
+                       tailwind: bool,
+                       prod_js: bool,
+                       ) -> None:
+        """Add the run config to the app config."""
+        self.reload = reload
+        self.title = title
+        self.viewport = viewport
+        self.favicon = favicon
+        self.dark = dark
+        self.language = language
+        self.binding_refresh_interval = binding_refresh_interval
+        self.reconnect_timeout = reconnect_timeout
+        self.tailwind = tailwind
+        self.prod_js = prod_js
+        self._has_run_config = True
+
+    @property
+    def has_run_config(self) -> bool:
+        """Return whether the run config has been added."""
+        return self._has_run_config

+ 1 - 1
nicegui/binding.py

@@ -37,7 +37,7 @@ async def refresh_loop() -> None:
     """Refresh all bindings in an endless loop."""
     while True:
         _refresh_step()
-        await asyncio.sleep(core.app._run_config.binding_refresh_interval)  # pylint: disable=protected-access
+        await asyncio.sleep(core.app.config.binding_refresh_interval)
 
 
 def _refresh_step() -> None:

+ 3 - 3
nicegui/client.py

@@ -118,8 +118,8 @@ class Client:
             'dark': str(self.page.resolve_dark()),
             'language': self.page.resolve_language(),
             'prefix': prefix,
-            'tailwind': core.app._run_config.tailwind,  # pylint: disable=protected-access
-            'prod_js': core.app._run_config.prod_js,  # pylint: disable=protected-access
+            'tailwind': core.app.config.tailwind,
+            'prod_js': core.app.config.prod_js,
             'socket_io_js_query_params': socket_io_js_query_params,
             'socket_io_js_extra_headers': core.app.config.socket_io_js_extra_headers,
             'socket_io_js_transports': core.app.config.socket_io_js_transports,
@@ -211,7 +211,7 @@ class Client:
             if self.page.reconnect_timeout is not None:
                 delay = self.page.reconnect_timeout
             else:
-                delay = core.app._run_config.reconnect_timeout  # pylint: disable=protected-access
+                delay = core.app.config.reconnect_timeout  # pylint: disable=protected-access
             await asyncio.sleep(delay)
             if not self.shared:
                 self.delete()

+ 4 - 5
nicegui/favicon.py

@@ -25,7 +25,7 @@ def create_favicon_route(path: str, favicon: Optional[Union[str, Path]]) -> None
 
 def get_favicon_url(page: page, prefix: str) -> str:
     """Return the URL of the favicon for a given page."""
-    favicon = page.favicon or core.app._run_config.favicon  # pylint: disable=protected-access
+    favicon = page.favicon or core.app.config.favicon
     if not favicon:
         return f'{prefix}/_nicegui/{__version__}/static/favicon.ico'
 
@@ -46,10 +46,9 @@ def get_favicon_url(page: page, prefix: str) -> str:
 
 def get_favicon_response() -> Response:
     """Return the FastAPI response for the global favicon."""
-    global_favicon = core.app._run_config.favicon  # pylint: disable=protected-access
-    if not global_favicon:
-        raise ValueError(f'invalid favicon: {global_favicon}')
-    favicon = str(global_favicon).strip()
+    if not core.app.config.favicon:
+        raise ValueError(f'invalid favicon: {core.app.config.favicon}')
+    favicon = str(core.app.config.favicon).strip()
 
     if _is_svg(favicon):
         return Response(favicon, media_type='image/svg+xml')

+ 6 - 7
nicegui/nicegui.py

@@ -79,9 +79,9 @@ def _get_component(key: str) -> FileResponse:
 def _startup() -> None:
     """Handle the startup event."""
     # NOTE ping interval and timeout need to be lower than the reconnect timeout, but can't be too low
-    sio.eio.ping_interval = max(app._run_config.reconnect_timeout * 0.8, 4)  # pylint: disable=protected-access
-    sio.eio.ping_timeout = max(app._run_config.reconnect_timeout * 0.4, 2)  # pylint: disable=protected-access
-    if not hasattr(app, '_run_config'):
+    sio.eio.ping_interval = max(app.config.reconnect_timeout * 0.8, 4)
+    sio.eio.ping_timeout = max(app.config.reconnect_timeout * 0.4, 2)
+    if not app.config.has_run_config:
         raise RuntimeError('\n\n'
                            'You must call ui.run() to start the server.\n'
                            'If ui.run() is behind a main guard\n'
@@ -89,10 +89,9 @@ def _startup() -> None:
                            'remove the guard or replace it with\n'
                            '   if __name__ in {"__main__", "__mp_main__"}:\n'
                            'to allow for multiprocessing.')
-    global_favicon = app._run_config.favicon  # pylint: disable=protected-access
-    if global_favicon:
-        if helpers.is_file(global_favicon):
-            app.add_route('/favicon.ico', lambda _: FileResponse(global_favicon))  # type: ignore
+    if core.app.config.favicon:
+        if helpers.is_file(core.app.config.favicon):
+            app.add_route('/favicon.ico', lambda _: FileResponse(core.app.config.favicon))  # type: ignore
         else:
             app.add_route('/favicon.ico', lambda _: favicon.get_favicon_response())
     else:

+ 4 - 4
nicegui/page.py

@@ -69,19 +69,19 @@ class page:
 
     def resolve_title(self) -> str:
         """Return the title of the page."""
-        return self.title if self.title is not None else core.app._run_config.title  # pylint: disable=protected-access
+        return self.title if self.title is not None else core.app.config.title
 
     def resolve_viewport(self) -> str:
         """Return the viewport of the page."""
-        return self.viewport if self.viewport is not None else core.app._run_config.viewport  # pylint: disable=protected-access
+        return self.viewport if self.viewport is not None else core.app.config.viewport
 
     def resolve_dark(self) -> Optional[bool]:
         """Return whether the page should use dark mode."""
-        return self.dark if self.dark is not ... else core.app._run_config.dark  # pylint: disable=protected-access
+        return self.dark if self.dark is not ... else core.app.config.dark
 
     def resolve_language(self) -> Optional[str]:
         """Return the language of the page."""
-        return self.language if self.language is not ... else core.app._run_config.language  # pylint: disable=protected-access
+        return self.language if self.language is not ... else core.app.config.language
 
     def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]:
         core.app.remove_route(self.path)  # NOTE make sure only the latest route definition is used

+ 2 - 3
nicegui/ui_run.py

@@ -12,7 +12,6 @@ from uvicorn.supervisors import ChangeReload, Multiprocess
 from . import air, core, helpers
 from . import native as native_module
 from . import welcome
-from .app_config import RunConfig
 from .client import Client
 from .language import Language
 from .logging import log
@@ -78,7 +77,7 @@ def run(*,
     :param storage_secret: secret key for browser-based storage (default: `None`, a value is required to enable ui.storage.individual and ui.storage.browser)
     :param kwargs: additional keyword arguments are passed to `uvicorn.run`    
     """
-    core.app._run_config = RunConfig(  # pylint: disable=protected-access
+    core.app.config.add_run_config(
         reload=reload,
         title=title,
         viewport=viewport,
@@ -110,7 +109,7 @@ def run(*,
 
     if reload and not hasattr(__main__, '__file__'):
         log.warning('auto-reloading is only supported when running from a file')
-        core.app._run_config.reload = reload = False  # pylint: disable=protected-access
+        core.app.config.reload = reload = False
 
     if fullscreen:
         native = True

+ 1 - 2
nicegui/ui_run_with.py

@@ -4,7 +4,6 @@ from typing import Optional, Union
 from fastapi import FastAPI
 
 from . import core, storage
-from .app_config import RunConfig
 from .language import Language
 
 
@@ -37,7 +36,7 @@ def run_with(
     :param prod_js: whether to use the production version of Vue and Quasar dependencies (default: `True`)
     :param storage_secret: secret key for browser-based storage (default: `None`, a value is required to enable ui.storage.individual and ui.storage.browser)
     """
-    core.app._run_config = RunConfig(  # pylint: disable=protected-access
+    core.app.config.add_run_config(
         reload=False,
         title=title,
         viewport=viewport,