Skip to content

Commit

Permalink
Merge pull request #2062 from nghia-vo/main
Browse files Browse the repository at this point in the history
Enable customization of the welcome message
  • Loading branch information
falkoschindler authored Dec 4, 2023
2 parents 3aae365 + e7c3d0c commit 94f22cc
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 15 deletions.
3 changes: 2 additions & 1 deletion nicegui/air.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ async def _handle_http(data: Dict[str, Any]) -> Dict[str, Any]:
@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:
Expand Down
3 changes: 3 additions & 0 deletions nicegui/app/app_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -48,6 +49,7 @@ def add_run_config(self,
reconnect_timeout: float,
tailwind: bool,
prod_js: bool,
show_welcome_message: bool,
) -> None:
"""Add the run config to the app config."""
self.reload = reload
Expand All @@ -60,6 +62,7 @@ def add_run_config(self,
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
Expand Down
9 changes: 5 additions & 4 deletions nicegui/nicegui.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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
Expand All @@ -26,7 +26,7 @@

@asynccontextmanager
async def _lifespan(_: App):
_startup()
await _startup()
yield
await _shutdown()

Expand Down Expand Up @@ -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'
Expand All @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions nicegui/ui_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -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

Expand All @@ -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

Expand Down
5 changes: 3 additions & 2 deletions nicegui/ui_run_with.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
12 changes: 7 additions & 5 deletions nicegui/welcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 14 additions & 0 deletions website/documentation/content/run_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 94f22cc

Please sign in to comment.