Simple example of creating a server extension using the new Jupyter server. This allows you to put your own frontend on a Jupyter server, giving you access to the whole Jupyter REST API. You also can add HTML templates and link your TypeScript to the server. When an extension application is launched, it
- starts and launches an instance of the Jupyter server.
- calls
self.load_jupyter_server_extension()
method. - loads configuration from config files+command line.
- appends the extension's handlers to the main web application.
- appends a
/static/<extension_name>/
endpoint where it serves static files (i.e. js, css, etc.).
-
Subclass the
ExtensionApp
. Set the following traits:extension_name
: name of the extension.static_paths
: path to static files directorytemplate_paths
: path to templates directory.
and define the following methods:
initialize_handlers()
: append handlers toself.handlers
in tuples of (r'/mypath/', MyHandlerName)initialize_settings()
: add extensions settings to the webapp usingself.settings
.initialize_templates()
: setup your HTML templating options.
Example using jinja for HTML templating
# application.py from jupyter_server.extension.application import ExtensionApp class MyExtension(ExtensionApp): # Name of the extension extension_name = "my_extension" # Local path to static files directory. static_paths = [ "/path/to/static/dir/" ] # Local path to templates directory. template_paths = [ "/path/to/template/dir/" ] def initialize_handlers(self): self.handlers.append( (r'/myextension', MyExtensionHandler) ) def initialize_templates(self): template_paths = [os.path.join(HERE,'templates')] env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_paths)) template_settings={'myextension_jinja2_env':env} self.settings.update(**template_settings) def initialize_settings(self): ...
-
Define handlers by subclassing the
ExtensionHandler
.Example using jinja
# handler.py from jupyter_server.extension.handler import ExtensionHandler class MyExtensionHandler(ExtensionHandler): def get_template(self,name): return self.settings['myextension_jinja2_env'].get_template(name) def get(self): html = self.render_template("index.html") self.write(html)
-
Point Jupyter server to the extension. We need to define two things:
_jupyter_server_extension_paths()
: a function defining what module to load the extension from.load_jupyter_server_extension()
: point there server to the extension's loading function mechansim.
Example
# __init__.py from .extension import MyExtension EXTENSION_NAME = "my_extension" def _jupyter_server_extension_paths(): return [{"module": EXTENSION_NAME}] load_jupyter_server_extension = MyExtension.load_jupyter_server_extension
-
Add the following configuration to your jupyter configuration directory to enable the extension.
{ "ServerApp": { "jpserver_extensions": { "notebook": true } } }
-
Add entry point in
setup.py
.setup( name='my_extension', version='0.1', data_files=[ ('etc/jupyter/jupyter_server_config.d', ['etc/jupyter/jupyter_server_config.d./my_extension.json']), ], ... 'entry_points': { 'console_scripts': [ 'jupyter-myext = my_extension.application:MyExtension.launch_instance' ] }, ... )
In your HTML template file, reference your bundled JavaScript in a <script>
using static_url
.
<script src="{{static_url('bundle.js')}}" type="text/javascript" charset="utf-8"></script>