Skip to content

Commit

Permalink
Add option to install dependencies from CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Nov 18, 2022
1 parent 0a856b6 commit 22bea83
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 25 deletions.
29 changes: 21 additions & 8 deletions packages/voilite/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,16 @@ export class VoiliteApp extends JupyterFrontEnd<IShell> {
const notebookSrc = JSON.parse(
PageConfig.getOption('notebookSrc')
) as ICellData[];

const packagesSrc = PageConfig.getOption('packagesSrc');
kernel.statusChanged.connect(async (_, status) => {
if (!executed && status === 'idle') {
executed = true;
await App.executeCells(notebookSrc, rendermime, connection.kernel!);
await App.executeCells({
packages: packagesSrc,
source: notebookSrc,
rendermime,
kernel: connection.kernel!
});
}
});
}
Expand Down Expand Up @@ -218,12 +223,20 @@ export namespace App {
default: JupyterFrontEndPlugin<any> | JupyterFrontEndPlugin<any>[];
}

export async function executeCells(
source: ICellData[],
rendermime: RenderMimeRegistry,
kernel: IKernelConnection
): Promise<void> {
// const cellKeys = Object.keys(cells).map(key => parseInt(key));
export async function executeCells(options: {
packages?: string;
source: ICellData[];
rendermime: RenderMimeRegistry;
kernel: IKernelConnection;
}): Promise<void> {
const { packages, source, rendermime, kernel } = options;
if (packages && packages.length > 0) {
window.update_loading_text(0, 0, 'Installing dependencies');
const future = kernel.requestExecute({
code: packages
});
await future.done;
}
const cellCount = source.length;
for (let idx = 0; idx < cellCount; idx++) {
const cell = source[idx];
Expand Down
34 changes: 25 additions & 9 deletions voila/voilite/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import logging
import os
import shutil
from copy import deepcopy
from pathlib import Path
from typing import Dict
from typing import List as TypeList
Expand Down Expand Up @@ -67,6 +66,7 @@ class Voilite(Application):
'theme': 'VoilaConfiguration.theme',
'base_url': 'Voilite.base_url',
'contents': 'Voilite.contents',
'packages': 'Voilite.packages',
}

output_prefix = Unicode(
Expand All @@ -79,6 +79,16 @@ class Voilite(Application):
'files', config=True, help=_('Name of the user contents directory')
)

packages = List(
[],
config=True,
help=_('List of packages to be installed in the voilite enviroment'),
)

config_file_paths = List(
Unicode(), config=True, help=_('Paths to search for voilite.(py|json)')
)

@default('log_level')
def _default_log_level(self):
return logging.INFO
Expand All @@ -90,6 +100,10 @@ def _default_root_dir(self):
else:
return os.getcwd()

@default('config_file_paths')
def _config_file_paths_default(self):
return [os.getcwd()]

def setup_template_dirs(self):
if self.voilite_configuration.template:
template_name = self.voilite_configuration.template
Expand Down Expand Up @@ -147,6 +161,7 @@ def initialize(self, argv=None):
raise ValueError(
'provided more than 1 argument: %r' % self.extra_args
)
self.load_config_file('voilite', path=self.config_file_paths)
self.voilite_configuration = VoilaConfiguration(parent=self)
self.setup_template_dirs()

Expand Down Expand Up @@ -196,7 +211,8 @@ def ignore_func(dir, files: TypeList[str]) -> TypeList[str]:
return [
f
for f in files
if os.path.isfile(os.path.join(dir, f)) and f.endswith('voila.js')
if os.path.isfile(os.path.join(dir, f))
and f.endswith('voila.js')
]

for root in self.static_paths:
Expand Down Expand Up @@ -267,31 +283,29 @@ def convert_notebook(
nb_path: str,
page_config: Dict,
output_prefix: str,
packages: TypeList[str],
output_name: str = None,
) -> None:
nb_name = output_name

nb_path = Path(nb_path)
if not nb_name:
nb_name = f'{nb_path.stem}.html'

page_config_copy = deepcopy(page_config)

with open(nb_path) as f:
nb = nbformat.read(f, 4)
src = [
nb_src = [
{
'cell_source': cell['source'],
'cell_type': cell['cell_type'],
}
for cell in nb['cells']
]
page_config_copy['notebookSrc'] = src

voilite_exporter = VoiliteExporter(
voilite_config=self.voilite_configuration,
page_config=page_config_copy,
page_config=page_config,
base_url=self.base_url,
nb_src=nb_src,
packages=packages,
)
content, _ = voilite_exporter.from_filename(nb_path)
output_dir = os.path.join(output_prefix, nb_path.parent)
Expand All @@ -317,6 +331,7 @@ def convert_directory(self, page_config):
nb,
page_config,
os.path.join(self.output_prefix, 'voila', 'render'),
self.packages,
)

def start(self):
Expand Down Expand Up @@ -347,6 +362,7 @@ def start(self):
self.notebook_path,
page_config,
self.output_prefix,
self.packages,
'index.html',
)
else:
Expand Down
28 changes: 20 additions & 8 deletions voila/voilite/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
#############################################################################


from traitlets import default
from copy import deepcopy

from nbconvert.filters.highlight import Highlight2HTML
from jupyter_server.services.contents.largefilemanager import LargeFileManager

from nbconvert.exporters import TemplateExporter
from nbconvert.filters.highlight import Highlight2HTML
from nbconvert.preprocessors import ClearOutputPreprocessor
from traitlets import default

from ..exporter import VoilaExporter
from ..paths import collect_template_paths
Expand All @@ -25,14 +25,14 @@ def __init__(self, *args, **kwargs):
kwargs.setdefault('base_url', '/')
kwargs.setdefault('contents_manager', LargeFileManager())

self.voilite_configuration = kwargs.get('voilite_config')
super().__init__(*args, **kwargs)

self.voilite_configuration = kwargs.get('voilite_config')
self.page_config = kwargs.get('page_config', {})
self.theme = self.voilite_configuration.theme
self.template_name = self.voilite_configuration.template
# template_paths?

super().__init__(*args, **kwargs)
self.packages = kwargs.get('packages', [])
self.nb_src = kwargs.get('nb_src', [])

# TODO
# Investigate why this doesnt work
Expand Down Expand Up @@ -66,6 +66,7 @@ def from_notebook_node(self, nb, resources=None, **kwargs):
nb_copy, resources = super(TemplateExporter, self).from_notebook_node(
nb, resources, **kwargs
)

resources['base_url'] = self.base_url
resources.setdefault('raw_mimetypes', self.raw_mimetypes)
resources['global_content_filter'] = {
Expand Down Expand Up @@ -97,7 +98,7 @@ def notebook_execute(nb, kernel_id):
resources=resources,
**extra_context,
static_url=self.static_url,
page_config=self.page_config
page_config=self.update_page_config(self.page_config),
):
html.append(html_snippet)

Expand All @@ -120,3 +121,14 @@ def _init_resources(self, resources):
resources['include_lab_theme'] = lambda x: ''

return resources

def update_page_config(self, page_config):
page_config_copy = deepcopy(page_config)

page_config_copy['notebookSrc'] = self.nb_src
if len(self.packages) > 0:
packages_src = 'import piplite\n'
packages_src += f'await piplite.install({self.packages})\n'
page_config_copy['packagesSrc'] = packages_src

return page_config_copy

0 comments on commit 22bea83

Please sign in to comment.