Skip to content

Commit

Permalink
Add support for jupyter_bokeh ipywidget rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Nov 6, 2019
1 parent 49caacf commit b0a4669
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
37 changes: 37 additions & 0 deletions panel/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import sys

from contextlib import contextmanager
from six import string_types

import param

Expand All @@ -27,6 +28,19 @@
_PATH = os.path.abspath(os.path.dirname(__file__))
_CSS_FILES = glob.glob(os.path.join(_PATH, '_styles', '*.css'))

def validate_config(config, parameter, value):
"""
Validates parameter setting on a hidden config parameter.
"""
orig = getattr(config, parameter)
try:
setattr(config, parameter, value)
except Exception as e:
raise e
finally:
setattr(config, parameter, orig)


class _config(param.Parameterized):
"""
Holds global configuration options for Panel. The options can be
Expand Down Expand Up @@ -66,6 +80,11 @@ class _config(param.Parameterized):
_embed_load_path = param.String(default=None, doc="""
Where to load json files for embedded state.""")

_jupyter_ext = param.ObjectSelector(
default='default', objects=['default', 'ipywidgets'], doc="""
Whether to render output in Jupyter with the default Jupyter
extension or use the jupyter_bokeh ipywidget model.""")

_inline = param.Boolean(default=True, allow_None=True, doc="""
Whether to inline JS and CSS resources.
If disabled, resources are loaded from CDN if one is available.""")
Expand Down Expand Up @@ -100,8 +119,21 @@ def embed(self):

@embed.setter
def embed(self, value):
validate_config(self, '_embed', value)
self._embed_ = value

@property
def jupyter_ext(self):
if self._jupyter_ext_ is not None:
return self._jupyter_ext_
else:
return os.environ.get('PANEL_JUPYTER_EXT', _config._jupyter_ext)

@jupyter_ext.setter
def jupyter_ext(self, value):
validate_config(self, '_jupyter_ext', value)
self._jupyter_ext_ = value

@property
def embed_json(self):
if self._embed_json_ is not None:
Expand All @@ -111,6 +143,7 @@ def embed_json(self):

@embed_json.setter
def embed_json(self, value):
validate_config(self, '_embed_json', value)
self._embed_json_ = value

@property
Expand All @@ -122,6 +155,7 @@ def embed_json_prefix(self):

@embed_json_prefix.setter
def embed_json_prefix(self, value):
validate_config(self, '_embed_json_prefix', value)
self._embed_json_prefix_ = value

@property
Expand All @@ -133,6 +167,7 @@ def embed_save_path(self):

@embed_save_path.setter
def embed_save_path(self, value):
validate_config(self, '_embed_save_path', value)
self._embed_save_path_ = value

@property
Expand All @@ -144,6 +179,7 @@ def embed_load_path(self):

@embed_load_path.setter
def embed_load_path(self, value):
validate_config(self, '_embed_load_path', value)
self._embed_load_path_ = value

@property
Expand All @@ -155,6 +191,7 @@ def inline(self):

@inline.setter
def inline(self, value):
validate_config(self, '_inline', value)
self._inline_ = value


Expand Down
31 changes: 31 additions & 0 deletions panel/viewable.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,25 @@ def _repr_mimebundle_(self, include=None, exclude=None):
if not loaded and 'holoviews' in sys.modules:
import holoviews as hv
loaded = hv.extension._loaded

if config.jupyter_ext == 'ipywidgets':
ipywidget = self.ipywidget()
plaintext = repr(ipywidget)
if len(plaintext) > 110:
plaintext = plaintext[:110] + '…'
data = {
'text/plain': plaintext,
}
if ipywidget._view_name is not None:
data['application/vnd.jupyter.widget-view+json'] = {
'version_major': 2,
'version_minor': 0,
'model_id': ipywidget._model_id
}
if ipywidget._view_name is not None:
ipywidget._handle_displayed()
return data, {}

if not loaded:
self.param.warning('Displaying Panel objects in the notebook '
'requires the panel extension to be loaded. '
Expand Down Expand Up @@ -421,6 +440,18 @@ def get_root(self, doc=None, comm=None):
state._views[ref] = (self, root, doc, comm)
return root

def ipywidget(self):
"""
Creates a root model from the Panel object and wraps it in
a jupyter_bokeh ipywidget BokehModel.
Returns
-------
Returns an ipywidget model which renders the Panel object.
"""
from jupyter_bokeh import BokehModel
return BokehModel(self.get_root())

def save(self, filename, title=None, resources=None, template=None,
template_variables=None, embed=False, max_states=1000,
max_opts=3, embed_json=False, json_prefix='', save_path='./',
Expand Down

0 comments on commit b0a4669

Please sign in to comment.