2015-09-30 03:42:56 +08:00
|
|
|
Custom request handlers
|
|
|
|
=======================
|
2015-09-30 03:34:17 +08:00
|
|
|
|
2015-09-30 03:42:56 +08:00
|
|
|
The notebook webserver can be interacted with using a well `defined
|
|
|
|
RESTful
|
2016-03-30 05:59:49 +08:00
|
|
|
API <http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml>`__.
|
2015-09-30 03:42:56 +08:00
|
|
|
You can define custom RESTful API handlers in addition to the ones
|
|
|
|
provided by the notebook. As described below, to define a custom handler
|
|
|
|
you need to first write a notebook server extension. Then, in the
|
|
|
|
extension, you can register the custom handler.
|
2015-09-30 03:34:17 +08:00
|
|
|
|
2015-09-30 03:42:56 +08:00
|
|
|
Writing a notebook server extension
|
|
|
|
-----------------------------------
|
2015-09-30 03:34:17 +08:00
|
|
|
|
2015-09-30 03:42:56 +08:00
|
|
|
The notebook webserver is written in Python, hence your server extension
|
|
|
|
should be written in Python too. Server extensions, like IPython
|
|
|
|
extensions, are Python modules that define a specially named load
|
|
|
|
function, ``load_jupyter_server_extension``. This function is called
|
|
|
|
when the extension is loaded.
|
2015-09-30 03:34:17 +08:00
|
|
|
|
2015-09-30 03:42:56 +08:00
|
|
|
.. code:: python
|
2015-09-30 03:34:17 +08:00
|
|
|
|
|
|
|
def load_jupyter_server_extension(nb_server_app):
|
|
|
|
"""
|
|
|
|
Called when the extension is loaded.
|
2016-10-03 02:59:18 +08:00
|
|
|
|
2015-09-30 03:34:17 +08:00
|
|
|
Args:
|
|
|
|
nb_server_app (NotebookWebApplication): handle to the Notebook webserver instance.
|
|
|
|
"""
|
2015-09-30 03:42:56 +08:00
|
|
|
pass
|
|
|
|
|
|
|
|
To get the notebook server to load your custom extension, you'll need to
|
|
|
|
add it to the list of extensions to be loaded. You can do this using the
|
2017-02-25 02:25:33 +08:00
|
|
|
config system. ``NotebookApp.nbserver_extensions`` is a config variable
|
2017-02-25 02:26:13 +08:00
|
|
|
which is a dictionary of strings, each a Python module to be imported, mapping
|
2017-02-25 02:25:33 +08:00
|
|
|
to ``True`` to enable or ``False`` to disable each extension.
|
2015-09-30 03:42:56 +08:00
|
|
|
Because this variable is notebook config, you can set it two different
|
|
|
|
ways, using config files or via the command line.
|
|
|
|
|
|
|
|
For example, to get your extension to load via the command line add a
|
2017-02-25 02:25:33 +08:00
|
|
|
double dash before the variable name, and put the Python dictionary in
|
2015-09-30 03:42:56 +08:00
|
|
|
double quotes. If your package is "mypackage" and module is
|
|
|
|
"mymodule", this would look like
|
2017-02-25 02:25:33 +08:00
|
|
|
``jupyter notebook --NotebookApp.nbserver_extensions="{'mypackage.mymodule':True}"``
|
2015-10-01 12:12:14 +08:00
|
|
|
.
|
2015-09-30 03:42:56 +08:00
|
|
|
Basically the string should be Python importable.
|
|
|
|
|
|
|
|
Alternatively, you can have your extension loaded regardless of the
|
|
|
|
command line args by setting the variable in the Jupyter config file.
|
|
|
|
The default location of the Jupyter config file is
|
2017-02-25 02:25:33 +08:00
|
|
|
``~/.jupyter/jupyter_notebook_config.py`` (see :doc:`/config_overview`). Inside
|
2015-09-30 03:42:56 +08:00
|
|
|
the config file, you can use Python to set the variable. For example,
|
2017-02-25 02:25:33 +08:00
|
|
|
the following config does the same as the previous command line example.
|
2015-09-30 03:42:56 +08:00
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
c = get_config()
|
2017-02-25 02:25:33 +08:00
|
|
|
c.NotebookApp.nbserver_extensions = {
|
|
|
|
'mypackage.mymodule': True,
|
|
|
|
}
|
2015-09-30 03:42:56 +08:00
|
|
|
|
|
|
|
Before continuing, it's a good idea to verify that your extension is
|
|
|
|
being loaded. Use a print statement to print something unique. Launch
|
|
|
|
the notebook server and you should see your statement printed to the
|
|
|
|
console.
|
|
|
|
|
|
|
|
Registering custom handlers
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
Once you've defined a server extension, you can register custom handlers
|
|
|
|
because you have a handle to the Notebook server app instance
|
|
|
|
(``nb_server_app`` above). However, you first need to define your custom
|
|
|
|
handler. To declare a custom handler, inherit from
|
|
|
|
``notebook.base.handlers.IPythonHandler``. The example below[1] is a
|
|
|
|
Hello World handler:
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
from notebook.base.handlers import IPythonHandler
|
|
|
|
|
|
|
|
class HelloWorldHandler(IPythonHandler):
|
|
|
|
def get(self):
|
|
|
|
self.finish('Hello, world!')
|
|
|
|
|
|
|
|
The Jupyter Notebook server use
|
|
|
|
`Tornado <http://www.tornadoweb.org/en/stable/>`__ as its web framework.
|
|
|
|
For more information on how to implement request handlers, refer to the
|
|
|
|
`Tornado documentation on the
|
|
|
|
matter <http://www.tornadoweb.org/en/stable/web.html#request-handlers>`__.
|
|
|
|
|
|
|
|
After defining the handler, you need to register the handler with the
|
|
|
|
Notebook server. See the following example:
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
web_app = nb_server_app.web_app
|
|
|
|
host_pattern = '.*$'
|
|
|
|
route_pattern = url_path_join(web_app.settings['base_url'], '/hello')
|
|
|
|
web_app.add_handlers(host_pattern, [(route_pattern, HelloWorldHandler)])
|
|
|
|
|
2016-10-03 02:59:18 +08:00
|
|
|
Putting this together with the extension code, the example looks like the
|
2015-10-01 12:12:14 +08:00
|
|
|
following:
|
2015-09-30 03:42:56 +08:00
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
from notebook.utils import url_path_join
|
|
|
|
from notebook.base.handlers import IPythonHandler
|
|
|
|
|
|
|
|
class HelloWorldHandler(IPythonHandler):
|
|
|
|
def get(self):
|
|
|
|
self.finish('Hello, world!')
|
|
|
|
|
2015-10-01 12:12:14 +08:00
|
|
|
def load_jupyter_server_extension(nb_server_app):
|
|
|
|
"""
|
|
|
|
Called when the extension is loaded.
|
2016-10-03 02:59:18 +08:00
|
|
|
|
2015-10-01 12:12:14 +08:00
|
|
|
Args:
|
|
|
|
nb_server_app (NotebookWebApplication): handle to the Notebook webserver instance.
|
|
|
|
"""
|
|
|
|
web_app = nb_server_app.web_app
|
|
|
|
host_pattern = '.*$'
|
|
|
|
route_pattern = url_path_join(web_app.settings['base_url'], '/hello')
|
|
|
|
web_app.add_handlers(host_pattern, [(route_pattern, HelloWorldHandler)])
|
|
|
|
|
2016-10-03 02:59:18 +08:00
|
|
|
References:
|
|
|
|
|
2019-03-27 20:43:15 +08:00
|
|
|
1. `Peter Parente's Mindtrove <https://mindtrove.info/4-ways-to-extend-jupyter-notebook/#nb-server-exts>`__
|