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

Voilite POC #1187

Merged
merged 10 commits into from
Feb 20, 2023
Merged

Voilite POC #1187

merged 10 commits into from
Feb 20, 2023

Conversation

martinRenou
Copy link
Member

@martinRenou martinRenou commented Aug 12, 2022

POC implementation for Voilite. Building on top of the lab-based PR #846

This PR implements a Voilite nbconvert exporter that will execute the code in the client using a client-side kernel.

jupyter nbconvert --to voilite_dashboard notebooks/basics.ipynb

Update 18/11

The nbconvert template is replaced by the voilite command. Users can convert a notebook into a static dashboard page with

voilite notebook.ipynb --theme=dark --template=gridstack --packages=ipywidgets --packages=ipyleaflet

Supported options:

  • --theme: Change the theme , can be dark, light or the full name of the JupyterLab themes.
  • --template: Change the template, for now Voilite supports lab, gridstack, reveal and classic theme
  • --packages: List of packages to be installed at run time in the lite kernel.

Voilite can be configured via the CLI or the voilite.py/voilite.json file.

Remaining tasks

  • Update classic and reveal templates to support voilite.
  • Handle static files
  • Generate a tree page for the case of multiple notebooks.
  • Improve loading message.
  • Add tests and documentation (will be addressed in the follow-up PR )

voilite

@martinRenou
Copy link
Member Author

This is very much WIP for now, there is not much to see yet.

@github-actions
Copy link
Contributor

Binder 👈 Launch a Binder on branch martinRenou/voila/voilite

packages/voilite/index.js Outdated Show resolved Hide resolved
packages/voilite/package.json Outdated Show resolved Hide resolved
@jtpio jtpio added the enhancement New feature or request label Aug 17, 2022
@martinRenou martinRenou force-pushed the voilite branch 4 times, most recently from 21a9222 to cb28723 Compare August 25, 2022 13:07
@martinRenou
Copy link
Member Author

Sorry for the wild rebases/squashes. I was cleaning up the PR quite a bit. It's not yet ready for review.

@trungleduc
Copy link
Member

@martinRenou do you have anything in the pipeline? Can rebase and play around with this PR?

@martinRenou
Copy link
Member Author

Feel free to do it :)

I pushed all I have here. It's not complete, and not working.

@trungleduc
Copy link
Member

Since this PR is based on #846 and it started diverging from the upstream PR. I think it's better to wait for #846 to be merged before continuing.
I will port some changes back to the upstream PR.

Comment on lines 92 to 140
def copy_static_files(self, page_config: Dict) -> None:

lite_static_path = os.path.join(
os.path.dirname(os.path.realpath(__file__)), 'static'
)
dest_static_path = os.path.join(os.getcwd(), 'voila')
if os.path.isdir(dest_static_path):
shutil.rmtree(dest_static_path)
copy_tree(
os.path.join(lite_static_path, 'voila'),
os.path.join(dest_static_path, 'static'),
)
shutil.move(
os.path.join(dest_static_path, 'static', 'pypi'),
os.path.join(dest_static_path, 'build', 'pypi'),
)
shutil.copyfile(
os.path.join(lite_static_path, 'services.js'),
os.path.join(dest_static_path, 'services.js'),
)

# Copy extension files
labextensions_path = jupyter_path('labextensions')
federated_extensions = page_config.get('federated_extensions', [])
roots = tuple(
os.path.abspath(os.path.expanduser(p)) + os.sep
for p in labextensions_path
)
dest_extension_path = os.path.join(
os.getcwd(), 'voila', 'labextensions'
)
if os.path.isdir(dest_extension_path):
shutil.rmtree(dest_extension_path)
for extension in federated_extensions:
for root in roots:
name = extension['name']
full_path = os.path.join(root, name)
if os.path.isdir(full_path):
copy_tree(
full_path, os.path.join(dest_extension_path, name)
)

# Copy themes files
all_themes = find_all_lab_theme()
for theme in all_themes:
theme_dst = os.path.join(
dest_static_path, 'static', 'themes', theme[0]
)
copy_tree(theme[1], theme_dst)
Copy link
Member Author

Choose a reason for hiding this comment

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

We might be able to get rid of all this if we make it a JupyterLite addon?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not very familiar with JupyterLite, does that mean Voila will depend on JupyterLite?

Copy link
Member

Choose a reason for hiding this comment

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

The xeus python lite kernel is a good example of a JupyterLite addon: https://github.com/jupyterlite/xeus-python-kernel/blob/main/jupyterlite_xeus_python/env_build_addon.py

Copy link
Member Author

Choose a reason for hiding this comment

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

We could probably make voilite and voila two specific Python packages so that we don't make voila depend on jupyterlite

Copy link
Member

Choose a reason for hiding this comment

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

Frankly, I'm not a fan of splitting voila/voilite, even at the command level.
I would love to be able to switch seamlessly between the two versions in the same voila command. It would be even better if we can mix the two types together on the same page. For example, when we serve a directory of notebooks we can config (by voila.json, voila.py,...) which ones will be served by the normal voila, and which one by the lite version.

@trungleduc trungleduc added this to the 0.5.0 milestone Oct 28, 2022
@martinRenou martinRenou mentioned this pull request Oct 28, 2022
voila/voilite/exporter.py Outdated Show resolved Hide resolved
share/jupyter/voila/templates/lab/index.html.j2 Outdated Show resolved Hide resolved
@jtpio
Copy link
Member

jtpio commented Nov 23, 2022

Many thanks @trungleduc for picking this up, will have a look soon 👍

@jtpio jtpio self-requested a review November 23, 2022 12:40
@martinRenou
Copy link
Member Author

There seems to be an error when passing a directory to voilite:

$ voilite notebooks/
Traceback (most recent call last):
  File "/home/martinrenou/micromamba/envs/voila/bin/voilite", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/martinrenou/micromamba/envs/voila/lib/python3.11/site-packages/traitlets/config/application.py", line 985, in launch_instance
    app.start()
  File "/home/martinrenou/github/voila/voila/voilite/app.py", line 369, in start
    self.convert_directory(page_config)
  File "/home/martinrenou/github/voila/voila/voilite/app.py", line 330, in convert_directory
    self.convert_notebook(
  File "/home/martinrenou/github/voila/voila/voilite/app.py", line 294, in convert_notebook
    with open(nb_path) as f:
         ^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'basics.ipynb'

@trungleduc
Copy link
Member

@martinRenou @jtpio to reuse jupyterlite addons, I think it would be better to spit voilite into a standalone package. What do you think?

@martinRenou
Copy link
Member Author

I'm personally fine with that 👍🏽

@jiboncom
Copy link

Hello all,
This looks amazing! I was trying to install from the PR but I am having a problem building the package. I always get a
ValueError: Aborting. Could not find cmd (jlpm) in path. If command is not expected to be in user's path, use an absolute path.

Any ideas on how to fix it?

@trungleduc
Copy link
Member

Hello all, This looks amazing! I was trying to install from the PR but I am having a problem building the package. I always get a ValueError: Aborting. Could not find cmd (jlpm) in path. If command is not expected to be in user's path, use an absolute path.

Any ideas on how to fix it?

you can alias your yarn command to jlpm or just install jupyterlab, it comes with the jlpm command.

@jiboncom
Copy link

Hello all, This looks amazing! I was trying to install from the PR but I am having a problem building the package. I always get a ValueError: Aborting. Could not find cmd (jlpm) in path. If command is not expected to be in user's path, use an absolute path.
Any ideas on how to fix it?

you can alias your yarn command to jlpm or just install jupyterlab, it comes with the jlpm command.

Thanks, it worked! This is absolutely great and could allow us to easily deploy dashboards to hundreds of students simultaneously! Many thanks for all your work.

I would like to suggest one potential improvement/feature although I have no idea about how hard it would be to implement. It would be great to first quickly show a cached output of the notebook/dashboard and have something signal the kernel still is loading. This way, people quickly get something to see and start exploring the dashboard instead of first having to wait and only then start discovering the content. I see it as the equivalent of the preheated kernels (although not the same, of course!).

Yours thankfully,
Javier.

@trungleduc
Copy link
Member

Hello all, This looks amazing! I was trying to install from the PR but I am having a problem building the package. I always get a ValueError: Aborting. Could not find cmd (jlpm) in path. If command is not expected to be in user's path, use an absolute path.
Any ideas on how to fix it?

you can alias your yarn command to jlpm or just install jupyterlab, it comes with the jlpm command.

Thanks, it worked! This is absolutely great and could allow us to easily deploy dashboards to hundreds of students simultaneously! Many thanks for all your work.

I would like to suggest one potential improvement/feature although I have no idea about how hard it would be to implement. It would be great to first quickly show a cached output of the notebook/dashboard and have something signal the kernel still is loading. This way, people quickly get something to see and start exploring the dashboard instead of first having to wait and only then start discovering the content. I see it as the equivalent of the preheated kernels (although not the same, of course!).

Yours thankfully, Javier.

Thanks for your feedback, indeed the preview output is a great idea! I will take a look at it.

@trungleduc trungleduc self-assigned this Jan 30, 2023
@martinRenou
Copy link
Member Author

Let's merge and iterate in follow-up PRs!

@martinRenou martinRenou merged commit 0b013b4 into voila-dashboards:main Feb 20, 2023
@martinRenou martinRenou deleted the voilite branch February 20, 2023 09:50
@martinRenou
Copy link
Member Author

As discussed with @trungleduc, we will revert this merge and create a new repository for Voilite.

martinRenou added a commit that referenced this pull request Feb 20, 2023
martinRenou added a commit that referenced this pull request Feb 20, 2023
@martinRenou martinRenou mentioned this pull request Feb 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants