nbdev icon indicating copy to clipboard operation
nbdev copied to clipboard

evaluating ipywidget code block in nbdev_preview does not result in output

Open tylere opened this issue 3 years ago • 3 comments

(This is a follow up to the Nbdev v2 & Jupyter Widgets discussion started on the nbdev forum.)

I am trying to get ipywidget output to render in nbdev_preview, with an eventual goal of getting it to render on GitHub pages. I am using (hopefully correctly) the master versions of nbdev, quarto, fastcore, execnb.

To reproduce:

Clone the test repository

https://github.com/tylere/test-evaluate-code-3

Setup a Local Environment setup

conda create -n test-evaluate-code-3 -c conda-forge python=3.10 gh jupyterlab jupyterlab-git ipywidgets ipyleaflet
conda activate test-evaluate-code-3
cd test-evaluate-code-3
# Install fastai dependencies
pip install -e ../../fastai/fastcore/
pip install -e ../../fastai/execnb/
pip install -e ../../fastai/nbdev/
nbdev_new
nbdev_install_hooks
# Install dev version of quarto
# https://github.com/quarto-dev/quarto-cli#development-version
ln -s /Users/tylere/Documents/GitHub/quarto-dev/quarto-cli/package/dist/bin/quarto /Users/tylere/miniconda3/envs/test-evaluate-code-3/bin/quarto
pip install -e '.[dev]'

Prerelease dependency versions

(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/fastcore && git pull && git log -1)
Already up to date.
commit 0ee5b7f52a6b8d81691046d73555d56a25fbafac (HEAD -> master, origin/master, origin/HEAD)
Merge: f7e81b8 8fdfd81
Author: Jeremy Howard <[email protected]>
Date:   Mon Sep 12 08:59:13 2022 +1000

    Merge pull request #486 from seeM/fix-http-exceptions
    
    fix: error in IPython while handling `HTTP4xxClientError`
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/execnb && git pull && git log -1)
Already up to date.
commit 25f3a2f94eb0ea5b9c88303dfd6b9130caa7a029 (HEAD -> master, tag: 0.1.3, origin/master, origin/HEAD)
Author: Jeremy Howard <[email protected]>
Date:   Sat Sep 3 13:13:53 2022 +1000

    release
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/nbdev && git pull && git log -1)
Already up to date.
commit 8b354dbed937005b500197431cc43c85cdf37d09 (HEAD -> master, origin/master, origin/HEAD)
Merge: 98fa120 6699aee
Author: Hamel Husain <[email protected]>
Date:   Sun Sep 11 20:27:55 2022 -0700

    Merge pull request #1039 from fastai/nb-add
    
    refactor best practices intro
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/nbdev && git pull && git log -1)
Already up to date.
commit 8b354dbed937005b500197431cc43c85cdf37d09 (HEAD -> master, origin/master, origin/HEAD)
Merge: 98fa120 6699aee
Author: Hamel Husain <[email protected]>
Date:   Sun Sep 11 20:27:55 2022 -0700

    Merge pull request #1039 from fastai/nb-add
    
    refactor best practices intro
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../quarto-dev/quarto-cli/ && git pull && git log -1)
Already up to date.
commit cb5343c248387e7e0c46b5e90c72479d0615a59b (HEAD -> main, tag: v1.2.95, origin/main, origin/HEAD)
Author: Charles Teague <[email protected]>
Date:   Mon Sep 12 13:44:01 2022 -0400

    Pass meta to shortcodes without messing with it
    
    Fixes #2407 (part 1 - pass meta through cleanly)

View the output in JupyterLab

Screen Shot 2022-09-12 at 1 43 35 PM

Preview the output

nbdev_preview Note that the datetime printout rendered correctly, but the two ipywidgets do not render.

Screen Shot 2022-09-12 at 1 43 38 PM

Clues

The nbdev_preview output warns "Malformed Jupyter Output Display Data found"

(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ nbdev_preview
Check file:///Users/tylere/Documents/GitHub/quarto-dev/quarto-cli/src/quarto.ts
Preparing to preview
[1/1] 01_test_ipywidget_evaluate.ipynb

Starting python3 kernel...Done

Executing '01_test_ipywidget_evaluate.ipynb'
  Cell 1/6...Done
  Cell 2/6...Done
  Cell 3/6...Done
  Cell 4/6...Done
  Cell 5/6...Done
  Cell 6/6...Done

WARNING: Malformed Jupyter Output Display Data found:
WARNING: {"model_id":"1149bbef449c4481bf183fb503c7079d","version_major":2,"version_minor":0}
WARNING: Malformed Jupyter Output Display Data found:
WARNING: {"model_id":"a4ac7997ebed4a8b969b5827cb3af393","version_major":2,"version_minor":0}

Watching files for changes
Browse at http://localhost:3000/01_test_ipywidget_evaluate.html
GET: /01_test_ipywidget_evaluate.html

tylere avatar Sep 12 '22 20:09 tylere

I'm having the same issue with ipywidget-enabled tqdm progress bars. nbdev_preview throws WARNING: Malformed Jupyter Output Display Data found: and no progress bars can be seen in the quarto output, even though they are fine in the notebook.

rxavier avatar Sep 13 '22 05:09 rxavier

I'm having the same issue with ipywidget-enabled tqdm progress bars. nbdev_preview throws WARNING: Malformed Jupyter Output Display Data found: and no progress bars can be seen in the quarto output, even though they are fine in the notebook.

Please open a new issue with full details to repro your problem -- adding to an existing issue means we don't have the info we need to help, and your issue won't be tracked separately.

jph00 avatar Sep 14 '22 23:09 jph00

Discussion on forum https://forums.fast.ai/t/nbdev-v2-jupyter-widgets/98259

jph00 avatar Sep 15 '22 00:09 jph00

I've reproduced this with a tiny example in quarto (no nbdev), tracking in the quarto repo:

  • https://github.com/quarto-dev/quarto-cli/issues/2445

seeM avatar Sep 15 '22 01:09 seeM

@tylere the upstream quarto issue is fixed in prerelease now - can you see if that helps?

jph00 avatar Sep 15 '22 22:09 jph00

Wahoo! I now see the widget output in the preview!

drawing

and they now show up on GitHub Pages:

drawing

For completeness, here is the current versions of the libraries:

(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/fastcore && git pull && git log -1)
Already up to date.
commit ac83d6be6229478dc516415407379ac8c534ece0 (HEAD -> master, tag: 1.5.27, origin/master, origin/HEAD)
Author: Jeremy Howard <[email protected]>
Date:   Fri Sep 16 05:46:33 2022 +1000

    release
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/ghapi && git pull && git log -1)
Already up to date.
commit 9dceb6c0d7a240bb2b936ea17acf36de698e645a (HEAD -> master, tag: 1.0.3, origin/master, origin/HEAD)
Author: Jeremy Howard <[email protected]>
Date:   Tue Sep 13 12:26:00 2022 +1000

    release
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/execnb && git pull && git log -1)
Already up to date.
commit 25f3a2f94eb0ea5b9c88303dfd6b9130caa7a029 (HEAD -> master, tag: 0.1.3, origin/master, origin/HEAD)
Author: Jeremy Howard <[email protected]>
Date:   Sat Sep 3 13:13:53 2022 +1000

    release
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../fastai/nbdev && git pull && git log -1)
Already up to date.
commit b5019418d58140e4d6f3af4c3d62043335f3ef06 (HEAD -> master, tag: 2.3.3, origin/master, origin/HEAD)
Author: Jeremy Howard <[email protected]>
Date:   Fri Sep 16 10:21:34 2022 +1000

    release
(test-evaluate-code-3) tylere-macbookpro5:test-evaluate-code-3 tylere$ (cd ../../quarto-dev/quarto-cli/ && git pull && git log -1)
Already up to date.
commit 603e94485339497e2d0f232a1acfaf3895a8feeb (HEAD -> main, origin/main, origin/HEAD)
Author: Charles Teague <[email protected]>
Date:   Thu Sep 15 17:16:10 2022 -0400

    only cleanup cached css file if it exists

Thank you! I think it is fine to close this now.

tylere avatar Sep 16 '22 02:09 tylere

Yay! :D

jph00 avatar Sep 16 '22 04:09 jph00

Looks like I was celebrating too soon... While the widget rendering works on the simple index page/notebook, rendering does not work in notebooks that define a module.

Example repo: https://github.com/tylere/test-evaluate-code-4

Here is the error I receive:

(test-evaluate-code-4) tylere-macbookpro5:test-evaluate-code-4 tylere$ nbdev_preview
NB: From v1.2 `_quarto.yml` is no longer auto-updated. Please remove the `custom_quarto_yml` line from `settings.ini`
Preparing to preview
[1/1] 00_core.ipynb

Starting python3 kernel...Done

Executing '00_core.ipynb'
  Cell 1/1...ERROR: 

An error occurred while executing the following cell:
------------------
show_doc(foo)
------------------

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [1], line 1
----> 1 show_doc(foo)

NameError: name 'show_doc' is not defined
NameError: name 'show_doc' is not defined

Here are the library versions used:

deps/execnb/
0e4c476 (HEAD -> master, origin/master, origin/HEAD) fix CI
deps/fastcore/
2ccab20 (HEAD -> master, origin/master, origin/HEAD) bump
deps/ghapi/
70fa621 (HEAD -> master, origin/master, origin/HEAD) CHANGELOG.md
deps/nbdev/
d26ce6e (HEAD -> master, origin/master, origin/HEAD) Merge pull request #1096 from fastai/migrate-fix
deps/quarto-cli/
97531040b (HEAD, tag: v1.2.131, origin/main, origin/HEAD, main) Merge pull request #2486 from jkseppan/author-localization-fix

tylere avatar Sep 19 '22 05:09 tylere

IIUC this is a bit of confusion between nbdev and Quarto's processors. When generating documentation, nbdev pre-processes the notebook before Quarto processes it. You can see the nbdev-processed version in the _proc folder -- useful for debugging.

In this case: nbdev removes#|exported cells, adds show_doc(...) cells, and removes #|hide cells. Since the from nbdev.showdoc import * cell has #|hide it's removed and show_doc isn't available when Quarto tries to then execute the notebook.

I'm not yet sure about the best solution.. Maybe nbdev could mark the cell as eval: false after execnb runs show_doc. @hamelsmu @jph00 what do you think?


BTW, why is the execute: true needed in the first place? Is it to ensure that the widget state gets added to the notebook? Maybe a better solution is to enable nbdev to do that in its own processing rather than deferring to Quarto.

seeM avatar Sep 19 '22 05:09 seeM

BTW, why is the execute: true needed in the first place? Is it to ensure that the widget state gets added to the notebook?

I think it is needed... at least I don't know how to get the widgets to render correctly without it. But I would be happy to be corrected.

According to the Quarto docs Output Options, the code block directives should override the frontmatter instructions. So maybe a solution is for nbdev to generate appropriate cell directives (#|execute:false ?) for all cells you want to ensure that quarto should not execute (like those containing show_doc()).

tylere avatar Sep 19 '22 19:09 tylere

I think it is needed... at least I don't know how to get the widgets to render correctly without it. But I would be happy to be corrected.

My understanding is that it shouldn't be needed if you save the widget state, either with classic notebook's menu item, or lab's auto-save feature.

jph00 avatar Sep 19 '22 21:09 jph00

With JupyterLab's "Save Widget State Automatically" enabled, the UI does save the widget state, but then nbdev's default "Jupyter hook" behavior strips the widget state.

If I set jupyter_hooks = False in settings.ini, the widget state is stored in the ipynb file, and nbdev_preview displays the widget output. Good, but I'm guessing I'll miss out on the beneficial parts of the Jupyter hooks.

I can customize the notebook cleaning by setting allowed_metadata_keys = widgets, and the widget state persists. Which seems like a good solution.

tylere avatar Sep 20 '22 21:09 tylere

Super! BTW that cleaning thing we've filed as a bug: #1069 . cc @seeM

jph00 avatar Sep 20 '22 22:09 jph00

#1069 is now fixed in latest master.

seeM avatar Sep 21 '22 02:09 seeM

This is currently labeled as "waiting for response" but I think that can be removed now.

tylere avatar Oct 25 '22 22:10 tylere