Browse Source

Merge pull request #2062 from nghia-vo/main

Enable customization of the welcome message
Falko Schindler 1 year ago
parent
commit
94f22ccb5a

+ 2 - 1
nicegui/air.py

@@ -56,7 +56,8 @@ class Air:
         @self.relay.on('ready')
         def _handle_ready(data: Dict[str, Any]) -> None:
             core.app.urls.add(data['device_url'])
-            print(f'NiceGUI is on air at {data["device_url"]}', flush=True)
+            if core.app.config.show_welcome_message:
+                print(f'NiceGUI is on air at {data["device_url"]}', flush=True)
 
         @self.relay.on('error')
         def _handleerror(data: Dict[str, Any]) -> None:

+ 3 - 0
nicegui/app/app_config.py

@@ -34,6 +34,7 @@ class AppConfig:
     reconnect_timeout: float = field(init=False)
     tailwind: bool = field(init=False)
     prod_js: bool = field(init=False)
+    show_welcome_message: bool = field(init=False)
     _has_run_config: bool = False
 
     def add_run_config(self,
@@ -48,6 +49,7 @@ class AppConfig:
                        reconnect_timeout: float,
                        tailwind: bool,
                        prod_js: bool,
+                       show_welcome_message: bool,
                        ) -> None:
         """Add the run config to the app config."""
         self.reload = reload
@@ -60,6 +62,7 @@ class AppConfig:
         self.reconnect_timeout = reconnect_timeout
         self.tailwind = tailwind
         self.prod_js = prod_js
+        self.show_welcome_message = show_welcome_message
         self._has_run_config = True
 
     @property

+ 5 - 4
nicegui/nicegui.py

@@ -11,7 +11,7 @@ from fastapi.responses import FileResponse, Response
 from fastapi.staticfiles import StaticFiles
 from fastapi_socketio import SocketManager
 
-from . import air, background_tasks, binding, core, favicon, helpers, json, outbox, run
+from . import air, background_tasks, binding, core, favicon, helpers, json, outbox, run, welcome
 from .app import App
 from .client import Client
 from .dependencies import js_components, libraries
@@ -26,7 +26,7 @@ from .version import __version__
 
 @asynccontextmanager
 async def _lifespan(_: App):
-    _startup()
+    await _startup()
     yield
     await _shutdown()
 
@@ -76,9 +76,8 @@ def _get_component(key: str) -> FileResponse:
     raise HTTPException(status_code=404, detail=f'component "{key}" not found')
 
 
-def _startup() -> None:
+async 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
     if not app.config.has_run_config:
         raise RuntimeError('\n\n'
                            'You must call ui.run() to start the server.\n'
@@ -87,6 +86,8 @@ def _startup() -> None:
                            'remove the guard or replace it with\n'
                            '   if __name__ in {"__main__", "__mp_main__"}:\n'
                            'to allow for multiprocessing.')
+    await welcome.collect_urls()
+    # 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.config.reconnect_timeout * 0.8, 4)
     sio.eio.ping_timeout = max(app.config.reconnect_timeout * 0.4, 2)
     if core.app.config.favicon:

+ 3 - 3
nicegui/ui_run.py

@@ -11,7 +11,6 @@ from uvicorn.supervisors import ChangeReload, Multiprocess
 
 from . import air, core, helpers
 from . import native as native_module
-from . import welcome
 from .client import Client
 from .language import Language
 from .logging import log
@@ -45,6 +44,7 @@ def run(*,
         prod_js: bool = True,
         endpoint_documentation: Literal['none', 'internal', 'page', 'all'] = 'none',
         storage_secret: Optional[str] = None,
+        show_welcome_message: bool = True,
         **kwargs: Any,
         ) -> None:
     """ui.run
@@ -76,6 +76,7 @@ def run(*,
     :param prod_js: whether to use the production version of Vue and Quasar dependencies (default: `True`)
     :param endpoint_documentation: control what endpoints appear in the autogenerated OpenAPI docs (default: 'none', options: 'none', 'internal', 'page', 'all')
     :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 show_welcome_message: whether to show the welcome message (default: `True`)
     :param kwargs: additional keyword arguments are passed to `uvicorn.run`    
     """
     core.app.config.add_run_config(
@@ -89,6 +90,7 @@ def run(*,
         reconnect_timeout=reconnect_timeout,
         tailwind=tailwind,
         prod_js=prod_js,
+        show_welcome_message=show_welcome_message,
     )
     core.app.config.endpoint_documentation = endpoint_documentation
 
@@ -103,8 +105,6 @@ def run(*,
     if on_air:
         air.instance = air.Air('' if on_air is True else on_air)
 
-    core.app.on_startup(welcome.print_message)
-
     if multiprocessing.current_process().name != 'MainProcess':
         return
 

+ 3 - 2
nicegui/ui_run_with.py

@@ -49,6 +49,7 @@ def run_with(
         reconnect_timeout=reconnect_timeout,
         tailwind=tailwind,
         prod_js=prod_js,
+        show_welcome_message=False,
     )
 
     storage.set_storage_secret(storage_secret)
@@ -58,9 +59,9 @@ def run_with(
 
     @asynccontextmanager
     async def lifespan_wrapper(app):
-        _startup()
+        await _startup()
         async with main_app_lifespan(app):
             yield
-        _shutdown()
+        await _shutdown()
 
     app.router.lifespan_context = lifespan_wrapper

+ 7 - 5
nicegui/welcome.py

@@ -13,15 +13,17 @@ def _get_all_ips() -> List[str]:
     return ips
 
 
-async def print_message() -> None:
+async def collect_urls() -> None:
     """Print a welcome message with URLs to access the NiceGUI app."""
-    print('NiceGUI ready to go ', end='', flush=True)
-    host = os.environ['NICEGUI_HOST']
-    port = os.environ['NICEGUI_PORT']
+    host = os.environ.get('NICEGUI_HOST')
+    port = os.environ.get('NICEGUI_PORT')
+    if not host or not port:
+        return
     ips = set((await run.io_bound(_get_all_ips)) if host == '0.0.0.0' else [])
     ips.discard('127.0.0.1')
     urls = [(f'http://{ip}:{port}' if port != '80' else f'http://{ip}') for ip in ['localhost'] + sorted(ips)]
     core.app.urls.update(urls)
     if len(urls) >= 2:
         urls[-1] = 'and ' + urls[-1]
-    print(f'on {", ".join(urls)}', flush=True)
+    if core.app.config.show_welcome_message:
+        print(f'NiceGUI ready to go on {", ".join(urls)}', flush=True)

+ 14 - 0
website/documentation/content/run_documentation.py

@@ -66,3 +66,17 @@ def svg_favicon():
     '''
 
     # ui.run(favicon=smiley)
+
+
+@doc.demo('Custom welcome message', '''
+    You can mute the default welcome message on the command line setting the `show_welcome_message` to `False`.
+    Instead you can print your own welcome message with a custom startup handler.
+''')
+def custom_welcome_message():
+    from nicegui import app
+
+    ui.label('App with custom welcome message')
+    #
+    # app.on_startup(lambda: print('Visit your app on one of these URLs:', app.urls))
+    #
+    # ui.run(show_welcome_message=False)