Skip to content

Commit

Permalink
Databricks and CoCalc Renderers (#1703)
Browse files Browse the repository at this point in the history
* Added CoCalc and Databricks renderers

* Update databricks renderer to search parent frames for displayHTML
function. Enable the renderer based on presence of an environment variable since
this displayHTML function search takes a bit of time and we don't want
to run it on import.
  • Loading branch information
jonmmease authored Aug 4, 2019
1 parent 22c495c commit d105f56
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 8 deletions.
100 changes: 92 additions & 8 deletions packages/python/plotly/plotly/io/_base_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,15 @@ def __init__(
post_script=None,
animation_opts=None,
include_plotlyjs=True,
html_directory="iframe_figures",
):

self.config = config
self.auto_play = auto_play
self.post_script = post_script
self.animation_opts = animation_opts
self.include_plotlyjs = include_plotlyjs
self.html_directory = html_directory

def to_mimebundle(self, fig_dict):
from plotly.io import write_html
Expand All @@ -559,15 +561,10 @@ def to_mimebundle(self, fig_dict):
iframe_height = str(525 + iframe_buffer) + "px"

# Build filename using ipython cell number
ip = IPython.get_ipython()
cell_number = list(ip.history_manager.get_tail(1))[0][1] + 1
dirname = "iframe_figures"
filename = "{dirname}/figure_{cell_number}.html".format(
dirname=dirname, cell_number=cell_number
)
filename = self.build_filename()

# Make directory for
os.makedirs(dirname, exist_ok=True)
os.makedirs(self.html_directory, exist_ok=True)

write_html(
fig_dict,
Expand Down Expand Up @@ -595,11 +592,38 @@ def to_mimebundle(self, fig_dict):
allowfullscreen
></iframe>
""".format(
width=iframe_width, height=iframe_height, src=filename
width=iframe_width, height=iframe_height, src=self.build_url(filename)
)

return {"text/html": iframe_html}

def build_filename(self):
ip = IPython.get_ipython()
cell_number = list(ip.history_manager.get_tail(1))[0][1] + 1
filename = "{dirname}/figure_{cell_number}.html".format(
dirname=self.html_directory, cell_number=cell_number
)
return filename

def build_url(self, filename):
return filename


class CoCalcRenderer(IFrameRenderer):

_render_count = 0

def build_filename(self):
filename = "{dirname}/figure_{render_count}.html".format(
dirname=self.html_directory, render_count=CoCalcRenderer._render_count
)

CoCalcRenderer._render_count += 1
return filename

def build_url(self, filename):
return "{filename}?fullscreen=kiosk".format(filename=filename)


class ExternalRenderer(BaseRenderer):
"""
Expand Down Expand Up @@ -707,6 +731,66 @@ def render(self, fig_dict):
open_html_in_browser(html, self.using, self.new, self.autoraise)


class DatabricksRenderer(ExternalRenderer):
def __init__(
self,
config=None,
auto_play=False,
post_script=None,
animation_opts=None,
include_plotlyjs="cdn",
):

self.config = config
self.auto_play = auto_play
self.post_script = post_script
self.animation_opts = animation_opts
self.include_plotlyjs = include_plotlyjs
self._displayHTML = None

@property
def displayHTML(self):
import inspect

if self._displayHTML is None:
for frame in inspect.getouterframes(inspect.currentframe()):
global_names = set(frame.frame.f_globals)
# Check for displayHTML plus a few others to reduce chance of a false
# hit.
if all(v in global_names for v in ["displayHTML", "display", "spark"]):
self._displayHTML = frame.frame.f_globals["displayHTML"]
break

if self._displayHTML is None:
raise EnvironmentError(
"""
Unable to detect the Databricks displayHTML function. The 'databricks' renderer is only
supported when called from within the Databricks notebook environment."""
)

return self._displayHTML

def render(self, fig_dict):
from plotly.io import to_html

html = to_html(
fig_dict,
config=self.config,
auto_play=self.auto_play,
include_plotlyjs=self.include_plotlyjs,
include_mathjax="cdn",
post_script=self.post_script,
full_html=True,
animation_opts=self.animation_opts,
default_width="100%",
default_height="100%",
validate=False,
)

# displayHTML is a Databricks notebook built-in function
self.displayHTML(html)


class SphinxGalleryRenderer(ExternalRenderer):
def render(self, fig_dict):
stack = inspect.stack()
Expand Down
11 changes: 11 additions & 0 deletions packages/python/plotly/plotly/io/_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
BrowserRenderer,
IFrameRenderer,
SphinxGalleryRenderer,
CoCalcRenderer,
DatabricksRenderer,
)
from plotly.io._utils import validate_coerce_fig_to_dict

Expand Down Expand Up @@ -406,6 +408,8 @@ def show(fig, renderer=None, validate=True, **kwargs):
renderers["kaggle"] = KaggleRenderer(config=config)
renderers["azure"] = AzureRenderer(config=config)
renderers["colab"] = ColabRenderer(config=config)
renderers["cocalc"] = CoCalcRenderer()
renderers["databricks"] = DatabricksRenderer()

# JSON
renderers["json"] = JsonRenderer()
Expand Down Expand Up @@ -475,6 +479,13 @@ def show(fig, renderer=None, validate=True, **kwargs):
if not default_renderer and "NTERACT_EXE" in os.environ:
default_renderer = "nteract"

# Check if we're running in CoCalc
if not default_renderer and "COCALC_PROJECT_ID" in os.environ:
default_renderer = "cocalc"

if not default_renderer and "DATABRICKS_RUNTIME_VERSION" in os.environ:
default_renderer = "databricks"

# Check if we're running in spyder and orca is installed
if not default_renderer and "SPYDER_ARGS" in os.environ:
try:
Expand Down

0 comments on commit d105f56

Please sign in to comment.