Repository: holoviz/panel

Issue:
Make panelite notebook installs specific to the packages that are imported
All over the place generic `micropip.install`s are made. An example is shown below

![image](https://user-images.githubusercontent.com/42288570/208231789-867ff792-6f2b-45d9-8768-94cf6347385b.png)

This slows down the notebook when loading. It might also lead some newbies to think that these `install`s are needed.

Please make the installs specific.

## Additional Context

If you tell me this would be beneficial @philippjfr I would try to find the time to clean up. Right now my guess is you did it this way due to not having enough time to specialize the installs across all notebooks?




Discussion:
After looking at the panel code I believe its the code below that has to be improved such that the imports depends on the notebook

![image](https://user-images.githubusercontent.com/42288570/208232063-2dab48b6-4afb-4d3b-993f-7bd68a724cc0.png)
My recommendation would be to make this specific by including it in the notebook.

Currently it takes 28 secs for me to `piplite.install` the `Notifications.ipynb` notebook. Something that makes the notebook almost not useful. And if you have a slow internet connection or device its even worse.

![image](https://user-images.githubusercontent.com/42288570/216773960-8f624fdb-58e2-4067-a979-a33e5838e5d1.png)

I would recommend making the notebooks specific. Something like

![image](https://user-images.githubusercontent.com/42288570/216774235-f22dfda5-f904-459e-8b20-b5683cde5b64.png)

This takes less than 3 secs on my laptop, which is very usable.
Would you accept a PR with a change like this across notebooks @philippjfr ? I would also clean up the existing code that adds the big, generel `piplite.install`.

UPDATE: I DON'T THINK THIS IS A GOOD IDEA. I WOULD RECOMMEND DEFINING A LIST SPECIFIC LIST OF REQUIREMENTS THAT WE CAN PREPEND WHEN BUILDING PANELITE.
If you have a good solution for this problem i would to see a PR yes.

Resolving patch:
diff --git a/scripts/generate_panelite_content.py b/scripts/generate_panelite_content.py
--- a/scripts/generate_panelite_content.py
+++ b/scripts/generate_panelite_content.py
@@ -14,34 +14,79 @@
 EXAMPLES_DIR = PANEL_BASE / 'examples'
 
 # Add piplite command to notebooks
-DEPENDENCIES = [repr(d) for d in ['panel', 'pyodide-http', 'altair', 'hvplot', 'matplotlib', 'plotly', 'pydeck', 'scikit-learn']]
-
-nbs = list(EXAMPLES_DIR.glob('*/*/*.ipynb')) + list(EXAMPLES_DIR.glob('*/*.*'))
-install = nbformat.v4.new_code_cell(source=f"import piplite\nawait piplite.install([{', '.join(DEPENDENCIES)}])")
-del install['id']
-
-for nb in nbs:
-    nbpath = pathlib.Path(nb)
-    out = (PANEL_BASE / 'lite/files') / nbpath.relative_to(EXAMPLES_DIR)
-    out.parent.mkdir(parents=True, exist_ok=True)
-    if nb.suffix == '.ipynb':
-        with open(nb, encoding='utf-8') as fin:
-            nb = nbformat.read(fin, 4)
-            nb['cells'].insert(0, install)
-        with open(out, 'w', encoding='utf-8') as fout:
-            nbformat.write(nb, fout)
-    elif not nb.is_dir():
-        shutil.copyfile(nb, out)
-
-# Copy assets
-shutil.copytree(
-    EXAMPLES_DIR / 'assets',
-    PANEL_BASE / 'lite' / 'files' / 'assets',
-    dirs_exist_ok=True
-)
-
-# Download sampledata
-def download():
+DEFAULT_DEPENDENCIES = ['panel', 'pyodide-http', 'altair', 'hvplot', 'matplotlib', 'plotly', 'pydeck', 'scikit-learn']
+with open(PANEL_BASE/"scripts"/"panelite_dependencies.json", "r", encoding="utf8") as file:
+    DEPENDENCIES = json.load(file)
+DEPENDENCY_NOT_IMPORTABLE = [
+    "streamz", # https://github.com/python-streamz/streamz/issues/467,
+    "vtk", # https://gitlab.kitware.com/vtk/vtk/-/issues/18806
+]
+NOTEBOOK_ISSUES = {
+    "Getting_Started.ipynb": ["https://github.com/holoviz/panel/issues/4416"],
+    "reference/panes/DataFrame.ipynb": ["https://github.com/python-streamz/streamz/issues/467"],
+    "reference/panes/HoloViews.ipynb": ["https://github.com/holoviz/panel/issues/4393"],
+    "reference/panes/IPyWidget.ipynb": ["https://github.com/holoviz/panel/issues/4394", "https://github.com/widgetti/ipyvolume/issues/427"],
+    "reference/panes/Matplotlib.ipynb": ["https://github.com/holoviz/panel/issues/4394"],
+    "reference/panes/Param.ipynb": ["https://github.com/holoviz/panel/issues/4393"],
+    "reference/panes/Reacton.ipynb": ["https://github.com/holoviz/panel/issues/4394"],
+    "reference/panes/Str.ipynb": ["https://github.com/holoviz/panel/issues/4396"],
+    "reference/panes/Streamz.ipynb": ["https://github.com/python-streamz/streamz/issues/467"],
+    "reference/panes/VTK.ipynb": ["https://gitlab.kitware.com/vtk/vtk/-/issues/18806"],
+    "reference/panes/VTKVolume.ipynb": ["https://gitlab.kitware.com/vtk/vtk/-/issues/18806"],
+    "reference/widgets/CrossSelector.ipynb": ["https://github.com/holoviz/panel/issues/4398"],
+    "reference/widgets/Debugger.ipynb": ["https://github.com/holoviz/panel/issues/4399"],
+    "reference/widgets/EditableIntSlider.ipynb": ["https://github.com/holoviz/panel/issues/4400"],
+    "reference/widgets/FileDownload.ipynb": ["https://github.com/holoviz/panel/issues/4401"],
+    "reference/widgets/IntRangeSlider.ipynb": ["https://github.com/holoviz/panel/issues/4402"],
+    "reference/widgets/MultiChoice.ipynb": ["https://github.com/holoviz/panel/issues/4403"],
+    "reference/widgets/RangeSlider.ipynb": ["https://github.com/holoviz/panel/issues/4402"],
+    "reference/widgets/SpeechToText.ipynb": ["https://github.com/holoviz/panel/issues/4404"],
+    "reference/widgets/Terminal.ipynb": ["https://github.com/holoviz/panel/issues/4407"],
+    "gallery/components/VuePdbInput.ipynb": ["https://github.com/holoviz/panel/issues/4417"],
+}
+
+def _get_dependencies(nbpath: pathlib.Path):
+    key = str(nbpath).split("examples/")[-1]
+    dependencies = DEPENDENCIES.get(key, DEFAULT_DEPENDENCIES)
+    dependencies = [repr(d) for d in dependencies if not d in DEPENDENCY_NOT_IMPORTABLE]
+    return dependencies
+
+
+def _to_source(dependencies):
+    return f"import piplite\nawait piplite.install([{', '.join(dependencies)}])"
+
+
+def _get_install_code_cell(nbpath: pathlib.Path):
+    dependencies = _get_dependencies(nbpath)
+    source = _to_source(dependencies)
+    install = nbformat.v4.new_code_cell(source=source)
+    del install['id']
+    return install
+
+def copy_examples():
+    nbs = list(EXAMPLES_DIR.glob('*/*/*.ipynb')) + list(EXAMPLES_DIR.glob('*/*.*'))
+    for nb in nbs:
+        nbpath = pathlib.Path(nb)
+        out = (PANEL_BASE / 'lite/files') / nbpath.relative_to(EXAMPLES_DIR)
+        out.parent.mkdir(parents=True, exist_ok=True)
+        if nb.suffix == '.ipynb':
+            with open(nb, encoding='utf-8') as fin:
+                nb = nbformat.read(fin, 4)
+                install = _get_install_code_cell(nbpath)
+                nb['cells'].insert(0, install)
+            with open(out, 'w', encoding='utf-8') as fout:
+                nbformat.write(nb, fout)
+        elif not nb.is_dir():
+            shutil.copyfile(nb, out)
+
+def copy_assets():
+    shutil.copytree(
+        EXAMPLES_DIR / 'assets',
+        PANEL_BASE / 'lite' / 'files' / 'assets',
+        dirs_exist_ok=True
+    )
+
+def download_sample_data():
     """
     Download larger data sets for various Bokeh examples.
     """
@@ -71,4 +116,7 @@ def download():
                 print(f"Re-fetching {filename!r} (checksum mismatch)")
         _download_file(s3, filename, data_dir, progress=False)
 
-download()
+if __name__=="__main__":
+    copy_examples()
+    copy_assets()
+    download_sample_data()


Test patch: