1import functools 2import warnings 3from distutils.version import LooseVersion 4 5import bokeh 6from bokeh.application import Application 7from bokeh.application.handlers.function import FunctionHandler 8from bokeh.server.server import BokehTornado 9 10try: 11 from bokeh.server.util import create_hosts_allowlist 12except ImportError: 13 from bokeh.server.util import create_hosts_whitelist as create_hosts_allowlist 14 15import dask 16 17if LooseVersion(bokeh.__version__) < LooseVersion("1.0.0"): 18 warnings.warn( 19 "\nDask needs bokeh >= 1.0 for the dashboard." 20 "\nContinuing without the dashboard." 21 ) 22 raise ImportError("Dask needs bokeh >= 1.0") 23 24 25def BokehApplication(applications, server, prefix="/", template_variables={}): 26 prefix = "/" + prefix.strip("/") + "/" if prefix else "/" 27 28 extra = {"prefix": prefix, **template_variables} 29 30 funcs = {k: functools.partial(v, server, extra) for k, v in applications.items()} 31 apps = {k: Application(FunctionHandler(v)) for k, v in funcs.items()} 32 33 kwargs = dask.config.get("distributed.scheduler.dashboard.bokeh-application").copy() 34 extra_websocket_origins = create_hosts_allowlist( 35 kwargs.pop("allow_websocket_origin"), server.http_server.port 36 ) 37 38 return BokehTornado( 39 apps, 40 prefix=prefix, 41 use_index=False, 42 extra_websocket_origins=extra_websocket_origins, 43 **kwargs, 44 ) 45