From cfc753961c3df118d2cb1c9f518a2f88a2efe2f8 Mon Sep 17 00:00:00 2001 From: maximlt Date: Tue, 25 Oct 2022 09:26:31 +0200 Subject: [PATCH 1/2] silence EMPTY_LAYOUT bokeh warnings --- panel/command/serve.py | 8 ++++++++ panel/io/server.py | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/panel/command/serve.py b/panel/command/serve.py index 42791a7a06..ffbb1becad 100644 --- a/panel/command/serve.py +++ b/panel/command/serve.py @@ -19,6 +19,8 @@ from bokeh.application.handlers.function import FunctionHandler from bokeh.command.subcommands.serve import Serve as _BkServe from bokeh.command.util import build_single_handler_applications +from bokeh.core.validation import silence +from bokeh.core.validation.warnings import EMPTY_LAYOUT from bokeh.server.contexts import ApplicationContext from tornado.ioloop import PeriodicCallback from tornado.web import StaticFileHandler @@ -490,3 +492,9 @@ def customize_kwargs(self, args, server_kwargs): kwargs['cookie_secret'] = config.cookie_secret return kwargs + + def invoke(self, args): + # Empty layout are valid and the Bokeh warning is silenced as usually + # not relevant to Panel users. + silence(EMPTY_LAYOUT, True) + super().invoke(args) diff --git a/panel/io/server.py b/panel/io/server.py index 2c42fa3777..a8a3a4280d 100644 --- a/panel/io/server.py +++ b/panel/io/server.py @@ -41,6 +41,8 @@ from bokeh.application.handlers.function import FunctionHandler from bokeh.command.util import build_single_handler_application from bokeh.core.templates import AUTOLOAD_JS +from bokeh.core.validation import silence +from bokeh.core.validation.warnings import EMPTY_LAYOUT from bokeh.embed.bundle import Script from bokeh.embed.elements import ( html_page_for_render_items, script_for_render_items, @@ -682,6 +684,9 @@ def serve( kwargs: dict Additional keyword arguments to pass to Server instance """ + # Empty layout are valid and the Bokeh warning is silenced as usually + # not relevant to Panel users. + silence(EMPTY_LAYOUT, True) kwargs = dict(kwargs, **dict( port=port, address=address, websocket_origin=websocket_origin, loop=loop, show=show, start=start, title=title, verbose=verbose, From f5b5e6ca6f0467d1e6004d18547725a4cf2b73f2 Mon Sep 17 00:00:00 2001 From: maximlt Date: Tue, 25 Oct 2022 09:27:45 +0200 Subject: [PATCH 2/2] add a test --- panel/tests/test_server.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/panel/tests/test_server.py b/panel/tests/test_server.py index 373541fcc2..db267d345d 100644 --- a/panel/tests/test_server.py +++ b/panel/tests/test_server.py @@ -1,5 +1,6 @@ import asyncio import datetime as dt +import logging import os import pathlib import time @@ -911,3 +912,30 @@ def app(): time.sleep(0.5) assert len(exceptions) == 1 + + +def test_server_no_warning_empty_layout(port, caplog): + + bk_logger = logging.getLogger('bokeh') + old_level = bk_logger.level + old_propagate = bk_logger.propagate + try: + # Test pretty dependent on how Bokeh sets up its logging system + bk_logger.propagate = True + bk_logger.setLevel(logging.WARNING) + + app = Row() + + serve(app, port=port, threaded=True, show=False) + + # Wait for server to start + time.sleep(1) + requests.get(f"http://localhost:{port}") + time.sleep(1) + + for rec in caplog.records: + if rec.levelname == 'WARNING': + assert 'EMPTY_LAYOUT' not in rec.message + finally: + bk_logger.setLevel(old_level) + bk_logger.propagate = old_propagate