Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC: Add interactive notebooks to pages in the "Usage Examples" section #741

Open
wants to merge 34 commits into
base: main
Choose a base branch
from

Conversation

agriyakhetarpal
Copy link
Collaborator

@agriyakhetarpal agriyakhetarpal commented May 9, 2024

Description

The Usage Examples section, following #728 and as requested in #737 (comment), is rendered interactive through the changes in this PR through the use of jupyterlite-sphinx and Markdown-based notebooks that are executed by MyST-NB. Please read below for a granular overview of all of these details:

Which issue does this PR solve/reference?

Addresses a part of #706

Key changes made

  1. All .rst based files under doc/source/regression converted to Markdown and reformatted as notebooks
  2. Jupytext frontmatter added to all of the notebooks so that they can be executed at the time of building the documentation
  3. Code cells that raise an error marked with cell-based tags
  4. MyST-NB is configured in conf.py
  5. NotebookLite directive used from jupyterlite-sphinx to run the notebooks under WASM in the same tab (and something like Add the option to open JupyterLite window in new tab jupyterlite/jupyterlite-sphinx#165 can be added for this directive as well)
  6. A custom, minimal Sphinx extension added to execute the Jupytext CLI before the sources and toctrees are read, and to selectively ignore the .ipynb-based notebooks that get generated during the process in order to keep the documentation build warning-free. Generating them at build time is for the NotebookLite directive to be able to access them and load them, since the NotebookLite directive currently does not load .md files or notebook files in other formats.
    i. I imagine this will be helpful for DOC: stats: Convert sampling tutorial to MyST-md scipy/scipy#20303 as well where it is required to load the notebooks in an interactive manner under a specific folder. The notebooks are not executed by Jupytext at the time of conversion, and therefore, based on past experiments, it takes ~10 seconds to convert 30 or so notebooks.

Additional context

This is just a pilot run of how notebook-based examples can be configured for Sphinx-based documentation websites, so there are a few corner cases that I have noticed so far:

  1. The styling of the NotebookLite directive can be improved because it takes way too much of the screen's space, perhaps through a user-provided option in conf.py just like how the TryExamples directive can be configured.
  2. References to the API for a package (in this case, public classes and methods for PyWavelets) are not linked to when running the notebook in its inline frame, because the notebook is not running under Sphinx and cannot access Sphinx's generated HTML pages. This can be worked around via better writing the notebooks by exploring other ways to reference pages and sections from the API (say, by adding Markdown-based headings or links, etc.).

A brief to-do list

Besides the points mentioned above, smaller tasks can be looked into:

  • Hide reST-based syntax (at least the irrelevant top parts of each page) using MyST
  • Improve the styling in other ways
  • Provide a button to download notebooks (both .md and .ipynb)

@agriyakhetarpal
Copy link
Collaborator Author

agriyakhetarpal commented May 9, 2024

Quite strange. The documentation is building without any problems locally...

Edit: I can reproduce locally if I delete a few of the previously generated files – this is coming from jupyterlite-sphinx. I think that Read the Docs is using a cached version of the documentation and is not purging the files properly, or it isn't allowing the subprocess to execute at the config-inited builder hook.

Edit, again: they were failing because the jupytext command was failing silently and was not converting any notebooks. Removing the hardcoded path fixed it.

@agriyakhetarpal agriyakhetarpal force-pushed the make-usage-examples-section-interactive branch 4 times, most recently from 8b4fcc8 to 4d1dcf0 Compare May 9, 2024 20:10
doc/source/conf.py Outdated Show resolved Hide resolved
doc/source/conf.py Outdated Show resolved Hide resolved
doc/source/conf.py Show resolved Hide resolved
doc/source/conf.py Outdated Show resolved Hide resolved
doc/source/regression/dwt-idwt.md Outdated Show resolved Hide resolved
@agriyakhetarpal
Copy link
Collaborator Author

agriyakhetarpal commented Jun 1, 2024

I added a basic extension to clean up the generated IPython notebooks in 6bc9c60 using nbformat, works quite well. I am now exploring a method to add the directives based on #741 (comment) automatically – it requires some configuration but I feel that it can be achieved at the source-read event before the Markdown files are processed.

@agriyakhetarpal agriyakhetarpal force-pushed the make-usage-examples-section-interactive branch from 18b4b2c to 21e0158 Compare June 4, 2024 15:01
@agriyakhetarpal
Copy link
Collaborator Author

Processing Markdown programmatically doesn't bear good fruit – it would have been easier if we used IPyNB, and we don't plan to. I would suggest that we should merge this for now, @rgommers.

The issue with Markdown was that there isn't a clean way to add both the Jupytext frontmatter and the notebook directives and that requires some obtrusive, prone-to-failure file manipulation by processing the contents as a string (we can keep the notebook directives at the bottom and the frontmatter intact, but it's easier to provide the download buttons at the top of the page rather than at the bottom).

doc/source/conf.py Outdated Show resolved Hide resolved
Comment on lines +379 to +380
# nb_execution_allow_errors = True
# nb_execution_show_tb = True
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what to do with these configuration values, probably best to remove them since both default to True?

Suggested change
# nb_execution_allow_errors = True
# nb_execution_show_tb = True

@agriyakhetarpal
Copy link
Collaborator Author

agriyakhetarpal commented Jun 4, 2024

Weird, the local docs build and RTD both produce cleaner downloadable notebooks, but the NotebookLite directive on RTD doesn't have the cleaner notebooks (they still have the Sphinx directives). This does not happen locally. I think RTD has some caching troubles, because I removed the redundant module headings from the notebooks (such as (reg-dwt-idwt)= and so on), but they are still there on RTD.

Local build An interactive notebook on the PyWavelets interactive docs page for discrete wavelets transforms and their inverse counterparts, built locally
Read the Docs An interactive notebook on the PyWavelets interactive docs page for discrete wavelets transforms and their inverse counterparts, built and hosted on RTD

Edit: some notebooks are as expected, and some don't.

Edit 2: this is most likely the case of a cached build or some updates that don't trickle down the RTD, the logs say that all the notebooks are converted. I can't reproduce locally, and I feel that the issue will go away automatically on a fresh build.

@agriyakhetarpal
Copy link
Collaborator Author

I had a revelation just now and I think 07a0926 should fix the synchronisation issue for good – the RTD build is just buggy for some reason or the other and the local documentation builds where the issue doesn't arise can be trusted upon. Ready for review and further proceedings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants