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 8aea9b6
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
36 changes: 36 additions & 0 deletions panel/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,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 +79,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 +118,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 +142,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 +154,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 +166,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 +178,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 +190,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 8aea9b6

Please sign in to comment.