Repository: altair-viz/altair
Pull request #1822 (2019-11-29 15:18:37)

V4: make HTML renderer the default
This makes the html renderer the default. I have tested this in Jupyter Notebook, JupyterLab, nbconvert, and nbviewer. It should also work properly in hosted notebooks like zeppelin, colab, kaggle, and databricks.

The former default renderer now can be enabled using ``alt.renderers.enable('mimetype')`` (or equivalently, ``'jupyterlab'`` or ``'nteract'``.


Patch:
diff --git a/altair/vegalite/v4/display.py b/altair/vegalite/v4/display.py
index 75fceec4..a3a6a0ff 100644
--- a/altair/vegalite/v4/display.py
+++ b/altair/vegalite/v4/display.py
@@ -40,7 +40,7 @@ renderers = RendererRegistry(entry_point_group=ENTRY_POINT_GROUP)
 here = os.path.dirname(os.path.realpath(__file__))
 
 
-def default_renderer(spec, **metadata):
+def mimetype_renderer(spec, **metadata):
     return default_renderer_base(spec, VEGALITE_MIME_TYPE, DEFAULT_DISPLAY,
                                  **metadata)
 
@@ -66,40 +66,22 @@ def svg_renderer(spec, **metadata):
                               vegalite_version=VEGALITE_VERSION,
                               **metadata)
 
-colab_renderer = HTMLRenderer(mode='vega-lite',
-                              fullhtml=True, requirejs=False,
-                              output_div='altair-viz',
-                              vega_version=VEGA_VERSION,
-                              vegaembed_version=VEGAEMBED_VERSION,
-                              vegalite_version=VEGALITE_VERSION)
-
-zeppelin_renderer = HTMLRenderer(mode='vega-lite',
-                                fullhtml=True, requirejs=False,
-                                vega_version=VEGA_VERSION,
-                                vegaembed_version=VEGAEMBED_VERSION,
-                                vegalite_version=VEGALITE_VERSION)
-
-kaggle_renderer = HTMLRenderer(mode='vega-lite',
-                               fullhtml=False, requirejs=True,
-                               vega_version=VEGA_VERSION,
-                               vegaembed_version=VEGAEMBED_VERSION,
-                               vegalite_version=VEGALITE_VERSION)
-
 html_renderer = HTMLRenderer(mode='vega-lite', template='universal',
                              vega_version=VEGA_VERSION,
                              vegaembed_version=VEGAEMBED_VERSION,
                              vegalite_version=VEGALITE_VERSION)
 
-renderers.register('default', default_renderer)
+renderers.register('default', html_renderer)
 renderers.register('html', html_renderer)
-renderers.register('jupyterlab', default_renderer)
-renderers.register('nteract', default_renderer)
-renderers.register('colab', colab_renderer)
-renderers.register('kaggle', kaggle_renderer)
+renderers.register('colab', html_renderer)
+renderers.register('kaggle', html_renderer)
+renderers.register('zeppelin', html_renderer)
+renderers.register('mimetype', mimetype_renderer)
+renderers.register('jupyterlab', mimetype_renderer)
+renderers.register('nteract', mimetype_renderer)
 renderers.register('json', json_renderer)
 renderers.register('png', png_renderer)
 renderers.register('svg', svg_renderer)
-renderers.register('zeppelin', zeppelin_renderer)
 renderers.enable('default')
 
 


Test patch:
diff --git a/altair/vegalite/v4/tests/test_renderers.py b/altair/vegalite/v4/tests/test_renderers.py
index 0abd27ca..3ddaa1a2 100644
--- a/altair/vegalite/v4/tests/test_renderers.py
+++ b/altair/vegalite/v4/tests/test_renderers.py
@@ -1,85 +1,67 @@
 """Tests of various renderers"""
 
 import json
-import re
 
 import pytest
 
 import altair.vegalite.v4 as alt
 
 
-def _extract_embedOpt(html):
-    """Extract an embedOpt definition from an html string.
-
-    Note: this is very brittle, but works for the specific test in this file.
-    """
-    result = re.search(r"embedOpt\s+=\s+(?P<embedOpt>\{.*?\})", html)
-    if not result:
-        return None
-    else:
-        return json.loads(result.groupdict()['embedOpt'])
-
-
 @pytest.fixture
 def chart():
     return alt.Chart('data.csv').mark_point()
 
 
-def test_colab_renderer_embed_options(chart):
+def test_html_renderer_embed_options(chart, renderer='html'):
     """Test that embed_options in renderer metadata are correctly manifest in html"""
-    def assert_actions_true(chart):
-        bundle = chart._repr_mimebundle_(None, None)
-        embedOpt = _extract_embedOpt(bundle['text/html'])
-        assert embedOpt == {'actions': True, 'mode': 'vega-lite'}
-
-    def assert_actions_false(chart):
-        bundle = chart._repr_mimebundle_(None, None)
-        embedOpt = _extract_embedOpt(bundle['text/html'])
-        assert embedOpt == {'actions': False, 'mode': 'vega-lite'}
+    # Short of parsing the javascript, it's difficult to parse out the
+    # actions. So we use string matching
 
-    with alt.renderers.enable('colab', embed_options=dict(actions=False)):
-        assert_actions_false(chart)
+    def assert_has_options(chart, **opts):
+        html = chart._repr_mimebundle_(None, None)['text/html']
+        for key, val in opts.items():
+            assert json.dumps({key: val})[1:-1] in html
 
-    with alt.renderers.enable('colab'):
-        with alt.renderers.enable(embed_options=dict(actions=True)):
-            assert_actions_true(chart)
+    with alt.renderers.enable(renderer):
+        assert_has_options(chart, mode='vega-lite')
 
-        with alt.renderers.set_embed_options(actions=False):
-            assert_actions_false(chart)
+        with alt.renderers.enable(embed_options=dict(actions={"export": True})):
+            assert_has_options(chart, mode='vega-lite', actions={'export': True})
 
         with alt.renderers.set_embed_options(actions=True):
-            assert_actions_true(chart)
+            assert_has_options(chart, mode='vega-lite', actions=True)
 
 
-def test_default_renderer_embed_options(chart, renderer='default'):
+def test_mimetype_renderer_embed_options(chart, renderer='mimetype'):
     # check that metadata is passed appropriately
     mimetype = alt.display.VEGALITE_MIME_TYPE
     spec = chart.to_dict()
-    with alt.renderers.enable(renderer, embed_options=dict(actions=False)):
-        bundle, metadata = chart._repr_mimebundle_(None, None)
-        assert set(bundle.keys()) == {mimetype, 'text/plain'}
-        assert bundle[mimetype] == spec
-        assert metadata == {mimetype: {'embed_options': {'actions': False}}}
-
-    # Sanity check: no metadata specified
     with alt.renderers.enable(renderer):
+        # Sanity check: no metadata specified
         bundle, metadata = chart._repr_mimebundle_(None, None)
         assert bundle[mimetype] == spec
         assert metadata == {}
+        with alt.renderers.set_embed_options(actions=False):
+            bundle, metadata = chart._repr_mimebundle_(None, None)
+            assert set(bundle.keys()) == {mimetype, 'text/plain'}
+            assert bundle[mimetype] == spec
+            assert metadata == {mimetype: {'embed_options': {'actions': False}}}
+
 
 
 def test_json_renderer_embed_options(chart, renderer='json'):
     """Test that embed_options in renderer metadata are correctly manifest in html"""
     mimetype = 'application/json'
     spec = chart.to_dict()
-    with alt.renderers.enable('json', option='foo'):
-        bundle, metadata = chart._repr_mimebundle_(None, None)
-        assert set(bundle.keys()) == {mimetype, 'text/plain'}
-        assert bundle[mimetype] == spec
-        assert metadata == {mimetype: {'option': 'foo'}}
-
-    # Sanity check: no options specified
     with alt.renderers.enable(renderer):
+        # Sanity check: no options specified
         bundle, metadata = chart._repr_mimebundle_(None, None)
         assert bundle[mimetype] == spec
         assert metadata == {}
+
+        with alt.renderers.enable(option='foo'):
+            bundle, metadata = chart._repr_mimebundle_(None, None)
+            assert set(bundle.keys()) == {mimetype, 'text/plain'}
+            assert bundle[mimetype] == spec
+            assert metadata == {mimetype: {'option': 'foo'}}
+