Add JupyterLite-powered interactive galleries to the scikit-image documentation#7644
Add JupyterLite-powered interactive galleries to the scikit-image documentation#7644agriyakhetarpal wants to merge 59 commits intoscikit-image:mainfrom
scikit-image documentation#7644Conversation
|
There seems to be a bug where I cannot correctly build the "API reference" section of the documentation on a local build – I have just the I noticed another bug with |
c20c730 to
843a8be
Compare
|
I'm sorry, @lesteve – I should have checked that you've had an open PR to do this via #6974 before I started working on this initiative further. How would you want me to proceed? I am happy to either pull in the relevant commits from that branch I haven't implemented here and to grant you authorship as appropriate, or step back and let you finish that one. Now that |
|
@agriyakhetarpal no worries and thanks for all the work you are doing on the Pyodide/interactive documentation front! Feel free to do whatever is simpler for you! I am more than happy for #6974 to be closed and you taking over this work. |
@agriyakhetarpal, I've seen that locally when I installed skimage in editable mode with |
|
I proposed a fix in #7647 to make apigen.py work with editable hooks. |
|
@lesteve, I was able to move the CORS proxy handling to a import re
import skimage.data._registry
new_registry_urls = {
k: re.sub(
r'https://gitlab.com/(.+)/-/raw(.+)',
r'https://cdn.statically.io/gl/\1\2',
url
)
for k, url in skimage.data._registry.registry_urls.items()
}
skimage.data._registry.registry_urls = new_registry_urls
""".splitlines()
)with smaller code, as import skimage.data
skimage.data.patch_cors()It seems to work quite well. You can try it out here: "Segment human cells (in mitosis)" example — skimage 0.25.3rc0.dev0 documentation Of course, we can't realistically test all example notebooks, as we discussed. However, I don't think there's a reason why this shouldn't work for any other cases besides this one. The PR is ready for another look! |
|
@agriyakhetarpal Let me know if you want me to take a look at this. I wasn't sure of its current status. |
@stefanv, thanks! It's ready for review. |
|
Hi @stefanv, I hope it is okay to ping you again here – this PR stands ready for review. @lesteve recently noted in my contemporary PRs to I'm now applying mostly the same code as scikit-learn/scikit-learn#31085, which requires #7440 to be merged so that the nightly WASM wheels for In particular, this PR also applies a patch to Thank you for your time! I'm also happy to hop on to another one of scikit-image's community calls to interact with you and the rest of the scikit-image core developers, similar to our previous discussions on #7470 (I'm waiting to get this change addressed before I proceed to work on that!). |
stefanv
left a comment
There was a problem hiding this comment.
Thanks @agriyakhetarpal! This looks pretty close to me. I only had a quick scan, but it's not 100% clear to me how we match the pip install version to the docs version in the non-dev gallery. Otherwise, I see no major hurdles.
skimage/data/__init__.pyi
Outdated
| 'moon', | ||
| 'nickel_solidification', | ||
| 'page', | ||
| 'palisades_of_vogt', |
There was a problem hiding this comment.
Is this a change necessary on main?
There was a problem hiding this comment.
I noticed that this was missing when I previously added a method here (which I've later reverted). This change is relevant but out of scope for this PR; will remove.
| pass | ||
|
|
||
| # This code path modifies the registry_urls dictionary to route all | ||
| # GitLab resources through a CORS proxy (cdn.statically.io), making |
There was a problem hiding this comment.
Is there a problem with always routing via CDN, instead of just for pyodide?
There was a problem hiding this comment.
My opinion is that we should avoid it. GitLab itself is using Cloudflare for its CDN services and can handle thrown on it, but switching to https://statically.io as a full-fledged and free CDN intended as a CORS proxy would put unnecessary strain on it. The JupyterLite docs would have much less traffic in comparison.
| " index_urls='https://pypi.anaconda.org/scientific-python-nightly-wheels/simple',\n" | ||
| ")", | ||
| ] | ||
| if "dev" in version |
There was a problem hiding this comment.
Why os the version missing for non-dev pip install?
Thanks for the review, @stefanv! This PR was addressing this point and the one you made in #7644 (comment) up to the time when I was bundling the wheel along with the docs, which I removed in later commits as it would increase the size of the https://github.com/scikit-image/docs repository. At this moment, this PR shouldn't close #6958 as it adds a nightly installation of scikit-image for the dev docs when it gets merged; it doesn't sync up the versions for older docs. I'd say that it is acceptable to add binary files to a repository like that and work with only a shallow clone if we need to modify the repository manually, but there's also a security angle towards adding them, which I cannot ignore. We'll need to figure out a solution for this. I have a few suggestions at hand:
I'm also curious if Loïc would have any suggestions, as this problem is one of the unsolved ones we have. :) |
|
My feeling right now for scikit-learn: the JupyterLite/Pyodide setup is experimental. We had zero reports about people being confused because the scikit-learn version on JupyterLite did not match what they expected 😅, probably because not that many people click on the JupyterLite link and/or they don't know where to complain. In a similar fashion, the Binder scikit-learn had been broken for at least 2 years and there had been zero report about it 😅. Personally, I sum this up as "it is completely fine to be less conservative than usual, let's try to get more people to use the JupyterLite setup, and let's improve it as we go". Of course I fully understand if other projects decide to be more conservative than scikit-learn. What I envision medium-term for scikit-learn (a bit hacky but 🤷) is to upload Pyodide wheels to anaconda.org scientific-python-nightly-wheel for scikit-learn released versions, so that I think building the Pyodide wheel during the build and shipping it within JupyterLite (see doc) is a fine option. Amongst other things, this should make it easier to keep the same version in the JupyterLite environment and the example gallery. For scikit-learn, I was a bit worried about the impact on the scikit-learn.github.io repo and on complicating the doc build slightly but I may change my mind about this in the future, we will see ... I haven't tried emscripten-forge recently but my understanding is that you do the equivalent of importing all the installed packages at kernel start-up time, which in my opinion doesn't lead to a super nice user experience 1. Having said this, I completely get it that opinions may differ about the trade-offs involved. This is the first time I hear about pyodide-jupyter-lock so I am not going to comment on it 😅 ... Footnotes
|
|
@lesteve, @lagru, and I are here in person at the Scientific Python summit. Our goal is to have this PR merged within the next few days. On my radar:
|
|
I'm marking this as a draft until #7931 is merged and a nightly Pyodide wheel is rereleased for usage. |
Description
Closes #6958
This pull request aims to enable interactive documentation for
scikit-image. Particularly, this relies on JupyterLite andjupyterlite-sphinx, particularly, our new0.18.0release – please see https://github.com/jupyterlite/jupyterlite-sphinx/releases/tag/v0.18.0. A list of the changes made in this PR is as follows:jupyterlite-sphinxas an optional dependency under the[docs]set of extras, andjupyterlite-pyodide-kernelto load Pyodide . Pyodide version 0.27 comes withscikit-imageversion 0.25.0 (see full list of packages). Thejupyterlite-pyodide-kernelis pinned to a specific version, as it controls the Pyodide version being used.jupyterlite-sphinxas an optional dependency.jupyter_lite_config.jsonfile for build-time configuration, that uses a custom wheel index that is passed topiplite, and the index is hosted from thedocs/source/skimage_docs_wasm_wheels/folder so that any and all wheels available within it are available to install. This folder is currently used in the CircleCI docs job, which now builds a WASM wheel (but doesn't test it – that still remains in GitHub Actions viaemscripten.ymlfor CI ergonomics) and uses it for the interactive docs. We then use Sphinx-Gallery's notebook_modification_function option to embed a%pip install scikit-imagecommand in the topmost notebook code cells to install from the custom wheel distribution, and add a JupyterLite warning, as the initial runtime takes a while to happen in the browser. Note that this command requires embedding the version, due to Installing newer versions of packages that are included in the Pyodide distribution already jupyterlite/jupyterlite#1557, and it is not possible for the Pyodide kernel to be able to pre-install packages from a local source yet (Configure the kernel to have packages automatically installed jupyterlite/pyodide-kernel#60).overrides.jsonfile adds runtime configuration for these notebooks – at this time, it adds a "Download" button for them in the JupyterLite UI.jupyterlite-sphinx'sTryExamplesdirective to enable API-based examples and ensured that the examples are self-contained, but kept it disabled for now (see Add JupyterLite-powered interactive galleries to thescikit-imagedocumentation #7644 (comment)). I'm happy to stem off those changes to a new PR.Tip
Please feel free to try out an example here, from the CircleCI deployment from this PR: https://output.circle-artifacts.com/output/job/2ccbb8a3-e4f8-452d-9a5b-c3846111ad5d/artifacts/0/doc/build/html/lite/lab/index.html?path=auto_examples%2Fnumpy_operations%2Fplot_camera_numpy.ipynb
Note
Another kernel, namely, the Xeus kernel is also available for use with JupyterLite (via
pip install jupyterlite-xeus) – the difference is that it uses theemscripten-forgedistribution instead of the Pyodide distribution noted above. I haven't used it becausescikit-imageseems to be packaged with version 0.19.3 there, which is a much older version than what is available at the time of writing.Checklist
./doc/examplesfor new featuresRelease note
For maintainers and optionally contributors, please refer to the instructions on how to document this PR for the release notes.
Here's my attempt at a release note:
Additional context
jupyterlite-sphinxnumpy/numpy#26745sphinx-gallery(optional, experimental): https://sphinx-gallery.github.io/stable/configuration.html#jupyterlite