Repository: bokeh/bokeh

Issue:
Gallery examples loading all bundles
The gallery examples are not pruning the bundles down to the minimum necessary:

<img width="865" alt="Screen Shot 2020-06-13 at 4 34 45 PM" src="https://user-images.githubusercontent.com/1078448/84581230-e9a62900-ad93-11ea-89df-fc3a5c803ad5.png">



Discussion:
OK the proximate cause is because None is passed here:

https://github.com/bokeh/bokeh/blob/dc87bd4219374943b4dbac5a3a5f3ba48e8053ab/bokeh/embed/standalone.py#L100

Need to determine it that is for a reason or just an accident.


passing `models` instead of None solves the immediate issue here. @mattpap this was last changed in #9198 is there any reason not to pass `models` here?

Edit: noting there are specific tests to check that all 4 bundles are included, but definitely not clear why that should be necessary. 

Resolving patch:
diff --git a/bokeh/embed/standalone.py b/bokeh/embed/standalone.py
--- a/bokeh/embed/standalone.py
+++ b/bokeh/embed/standalone.py
@@ -97,7 +97,7 @@ def autoload_static(model: Union[Model, Document], resources: Resources, script_
     with OutputDocumentFor(models):
         (docs_json, [render_item]) = standalone_docs_json_and_render_items([model])
 
-    bundle = bundle_for_objs_and_resources(None, resources)
+    bundle = bundle_for_objs_and_resources(models, resources)
     bundle.add(Script(script_for_render_items(docs_json, [render_item])))
 
     (_, elementid) = list(render_item.roots.to_json().items())[0]


Test patch:
diff --git a/tests/unit/bokeh/embed/test_standalone.py b/tests/unit/bokeh/embed/test_standalone.py
--- a/tests/unit/bokeh/embed/test_standalone.py
+++ b/tests/unit/bokeh/embed/test_standalone.py
@@ -53,6 +53,15 @@ def test_plot() -> None:
     test_plot.circle([1, 2], [2, 3])
     return test_plot
 
+@pytest.fixture
+def test_plot_and_widget() -> None:
+    from bokeh.plotting import figure
+    from bokeh.layouts import column
+    from bokeh.models import Div
+    test_plot = figure(title="'foo'")
+    test_plot.circle([1, 2], [2, 3])
+    return column(Div(text="foo"), test_plot)
+
 PAGE = Template("""
 <!DOCTYPE html>
 <html lang="en">
@@ -81,6 +90,17 @@ def test_script_attrs(self, test_plot) -> None:
         js, tag = bes.autoload_static(test_plot, CDN, "some/path")
         html = bs4.BeautifulSoup(tag, "html.parser")
         scripts = html.findAll(name='script')
+        assert "bokeh-widgets" not in js
+        assert len(scripts) == 1
+        attrs = scripts[0].attrs
+        assert set(attrs) == set(['src', 'id'])
+        assert attrs['src'] == 'some/path'
+
+    def test_script_attrs_with_widgets(self, test_plot_and_widget) -> None:
+        js, tag = bes.autoload_static(test_plot_and_widget, CDN, "some/path")
+        html = bs4.BeautifulSoup(tag, "html.parser")
+        scripts = html.findAll(name='script')
+        assert "bokeh-widgets" in js
         assert len(scripts) == 1
         attrs = scripts[0].attrs
         assert set(attrs) == set(['src', 'id'])
@@ -102,7 +122,7 @@ def test_js_dev_cdn(self, version, monkeypatch, driver, test_file_path_and_url,
         driver.get(url)
 
         scripts = driver.find_elements_by_css_selector('head script')
-        assert len(scripts) == 4
+        assert len(scripts) == 1
         for script in scripts:
             assert script.get_attribute("crossorigin") == None
             assert script.get_attribute("integrity") == ""
@@ -124,7 +144,29 @@ def test_js_release_cdn(self, monkeypatch, driver, test_file_path_and_url, test_
         scripts = driver.find_elements_by_css_selector('head script')
         for x in scripts:
             print(x.get_attribute("src"))
-        assert len(scripts) == 4
+        assert len(scripts) == 1
+        for script in scripts:
+            assert script.get_attribute("crossorigin") == "anonymous"
+            assert script.get_attribute("integrity").startswith("sha384-")
+
+    @pytest.mark.selenium
+    def test_js_release_cdn_with_widgets(self, monkeypatch, driver, test_file_path_and_url, test_plot_and_widget) -> None:
+        monkeypatch.setattr(buv, "__version__", "2.0.0")
+        monkeypatch.setattr(resources, "__version__", "2.0.0")
+        js, tag = bes.autoload_static(test_plot_and_widget, CDN, "some/path")
+
+        page = PAGE.render(js=js, tag=tag)
+
+        path, url = test_file_path_and_url
+        with open(path, "w") as f:
+            f.write(page)
+
+        driver.get(url)
+
+        scripts = driver.find_elements_by_css_selector('head script')
+        for x in scripts:
+            print(x.get_attribute("src"))
+        assert len(scripts) == 2  # 2 to include widgets bundle
         for script in scripts:
             assert script.get_attribute("crossorigin") == "anonymous"
             assert script.get_attribute("integrity").startswith("sha384-")
@@ -146,7 +188,7 @@ def test_js_release_dev_cdn(self, monkeypatch, driver, test_file_path_and_url, t
         scripts = driver.find_elements_by_css_selector('head script')
         for x in scripts:
             print(x.get_attribute("src"))
-        assert len(scripts) == 4
+        assert len(scripts) == 1
         for script in scripts:
             assert script.get_attribute("crossorigin") == "anonymous"
             assert script.get_attribute("integrity").startswith("sha384-")
@@ -166,7 +208,7 @@ def test_js_release_server(self, monkeypatch, driver, test_file_path_and_url, te
         driver.get(url)
 
         scripts = driver.find_elements_by_css_selector('head script')
-        assert len(scripts) == 4
+        assert len(scripts) == 1
         for script in scripts:
             assert script.get_attribute("crossorigin") == None
             assert script.get_attribute("integrity") == ""