diff --git a/tests/conftest.py b/tests/conftest.py index d6c58e63d..4e9c484ae 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -29,7 +29,8 @@ def voila_args_extra(): @pytest.fixture def voila_args(voila_notebook, voila_args_extra): - return [voila_notebook, '--VoilaApp.log_level=DEBUG'] + voila_args_extra + debug_args = ['--VoilaTest.log_level=DEBUG'] if os.environ.get('VOILA_TEST_DEBUG', False) else [] + return [voila_notebook] + voila_args_extra + debug_args @pytest.fixture diff --git a/tests/template_cli_test.py b/tests/template_cli_test.py new file mode 100644 index 000000000..eb0860a66 --- /dev/null +++ b/tests/template_cli_test.py @@ -0,0 +1,20 @@ +# tests programmatic config of template sytem +import pytest +import os + +BASE_DIR = os.path.dirname(__file__) + + +@pytest.fixture +def voila_args_extra(): + path_gridstack = os.path.abspath(os.path.join(BASE_DIR, '../share/jupyter/voila/template/gridstack/nbconvert_templates')) + path_default = os.path.abspath(os.path.join(BASE_DIR, '../share/jupyter/voila/template/default/nbconvert_templates')) + return ['--template=None', '--Voila.nbconvert_template_paths=[%r, %r]' % (path_gridstack, path_default)] + + +@pytest.mark.gen_test +def test_template_gridstack(http_client, base_url): + response = yield http_client.fetch(base_url) + assert response.code == 200 + assert 'gridstack.css' in response.body.decode('utf-8') + assert 'Hi Voila' in response.body.decode('utf-8') diff --git a/voila/app.py b/voila/app.py index 55ff488ae..4c23b5ef4 100644 --- a/voila/app.py +++ b/voila/app.py @@ -20,7 +20,7 @@ import tornado.web from traitlets.config.application import Application -from traitlets import Unicode, Integer, Bool, default +from traitlets import Unicode, Integer, Bool, List, default from jupyter_server.services.kernels.kernelmanager import MappingKernelManager from jupyter_server.services.kernels.handlers import KernelHandler, ZMQChannelsHandler @@ -101,6 +101,39 @@ class Voila(Application): ) ) + notebook_path = Unicode( + None, + config=True, + allow_none=True, + help=( + 'path to notebook to serve with voila') + ) + + nbconvert_template_paths = List( + [], + config=True, + help=( + 'path to nbconvert templates' + ) + ) + + template_paths = List( + [], + allow_none=True, + config=True, + help=( + 'path to nbconvert templates' + ) + ) + + static_paths = List( + [STATIC_ROOT], + config=True, + help=( + 'paths to static assets' + ) + ) + @default('connection_dir_root') def _default_connection_dir(self): connection_dir = tempfile.gettempdir() @@ -138,20 +171,19 @@ def initialize(self, argv=None): def parse_command_line(self, argv=None): super(Voila, self).parse_command_line(argv) - self.notebook_path = self.extra_args[0] if len(self.extra_args) == 1 else None - self.nbconvert_template_paths = [] - self.template_paths = [] - self.static_paths = [self.static_root] + + def setup_template_dirs(self): + self.notebook_path = self.notebook_path if self.notebook_path else self.extra_args[0] if len(self.extra_args) == 1 else None if self.template: collect_template_paths( self.nbconvert_template_paths, self.static_paths, self.template_paths, self.template) - self.log.debug('using template: %s', self.template) - self.log.debug('nbconvert template paths: %s', self.nbconvert_template_paths) - self.log.debug('template paths: %s', self.template_paths) - self.log.debug('static paths: %s', self.static_paths) + self.log.debug('using template: %s', self.template) + self.log.debug('nbconvert template paths: %s', self.nbconvert_template_paths) + self.log.debug('template paths: %s', self.template_paths) + self.log.debug('static paths: %s', self.static_paths) if self.notebook_path and not os.path.exists(self.notebook_path): raise ValueError('Notebook not found: %s' % self.notebook_path) @@ -160,6 +192,7 @@ def _handle_signal_stop(self, sig, frame): self.ioloop.add_callback_from_signal(self.ioloop.stop) def start(self): + self.setup_template_dirs() self.connection_dir = tempfile.mkdtemp( prefix='voila_', dir=self.connection_dir_root