Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide Viewer baseclass #2045

Merged
merged 5 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions panel/pane/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def panel(obj, **kwargs):
"""
if isinstance(obj, Viewable):
return obj
elif hasattr(obj, '__panel__'):
return panel(obj.__panel__())
if kwargs.get('name', False) is None:
kwargs.pop('name')
pane = PaneBase.get_pane_type(obj, **kwargs)(obj, **kwargs)
Expand Down
9 changes: 5 additions & 4 deletions panel/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .widgets import Button, Select
from .param import Param
from .util import param_reprs
from .viewable import Viewer


class PipelineError(RuntimeError):
Expand Down Expand Up @@ -102,7 +103,7 @@ def get_breadths(node, graph, depth=0, breadths=None):



class Pipeline(param.Parameterized):
class Pipeline(Viewer):
"""
A Pipeline represents a directed graph of stages, which each
return a panel object to render. A pipeline therefore represents
Expand Down Expand Up @@ -222,6 +223,9 @@ def __init__(self, stages=[], graph={}, **params):
self.add_stage(name, stage, **kwargs)
self.define_graph(graph)

def __panel__(self):
return self.layout

def _validate(self, stage):
if any(stage is s for n, (s, kw) in self._stages.items()):
raise ValueError('Stage %s is already in pipeline' % stage)
Expand Down Expand Up @@ -527,9 +531,6 @@ def tap_renderer(plot, element):
)
return plot

def _repr_mimebundle_(self, include=None, exclude=None):
return self.layout._repr_mimebundle_(include, exclude)

#----------------------------------------------------------------
# Public API
#----------------------------------------------------------------
Expand Down
32 changes: 32 additions & 0 deletions panel/viewable.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,3 +769,35 @@ def server_doc(self, doc=None, title=None, location=True):
add_to_doc(model, doc)
if location: self._add_location(doc, location, model)
return doc


class Viewer(param.Parameterized):
"""
A baseclass for custom components that behave like a Panel object.
By implementing __panel__ method an instance of this class will
behave like the returned Panel component when placed in a layout,
render itself in a notebook and provide show and servable methods.
"""

def __panel__(self):
"""
Subclasses should return a Panel component to be rendered.
"""
raise NotImplementedError

def servable(self, title=None, location=True):
return self.__panel__().servable(title, location)

servable.__doc__ = ServableMixin.servable.__doc__

def show(self, title=None, port=0, address=None, websocket_origin=None,
threaded=False, verbose=True, open=True, location=True, **kwargs):
return self.__panel__().show(
title, port, address, websocket_origin, threaded,
verbose, open, location, **kwargs
)

show.__doc__ = ServableMixin.show.__doc__

def _repr_mimebundle_(self, include=None, exclude=None):
return self.__panel__._repr_mimebundle_(include, exclude)