Skip to content

Commit d9e385c

Browse files
authored
Merge pull request #329 from Zsailer/migration-docs
Documentation for migrating server extensions
2 parents 523f198 + 463a08c commit d9e385c

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

docs/source/developers/extensions.rst

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,3 +401,146 @@ Putting it all together, authors can distribute their extension following this s
401401
.. links
402402
403403
.. _`Jupyter's paths`: https://jupyter.readthedocs.io/en/latest/projects/jupyter-directories.html
404+
405+
406+
Migrating an extension to use Jupyter Server
407+
============================================
408+
409+
If you're a developer of a `classic Notebook Server`_ extension, your extension should be able to work with *both* the classic notebook server and ``jupyter_server``.
410+
411+
There are a few key steps to make this happen:
412+
413+
1. Point Jupyter Server to the ``load_jupyter_server_extension`` function with a new reference name.
414+
The ``load_jupyter_server_extension`` function was the key to loading a server extension in the classic Notebook Server. Jupyter Server expects the name of this function to be prefixed with an underscore—i.e. ``_load_jupyter_server_extension``. You can easily achieve this by adding a reference to the old function name with the new name in the same module.
415+
416+
.. code-block:: python
417+
418+
def load_jupyter_server_extension(nb_server_app):
419+
...
420+
421+
# Reference the old function name with the new function name.
422+
423+
_load_jupyter_server_extension = load_jupyter_server_extension
424+
425+
2. Add new data files to your extension package that enable it with Jupyter Server.
426+
This new file can go next to your classic notebook server data files. Create a new sub-directory, ``jupyter_server_config.d``, and add a new ``.json`` file there:
427+
428+
.. raw:: html
429+
430+
<pre>
431+
myextension
432+
├── myextension/
433+
│ ├── __init__.py
434+
│ └── app.py
435+
├── jupyter-config/
436+
│ └── jupyter_notebook_config.d/
437+
│ └── myextension.json
438+
│ <b>└── jupyter_server_config.d/</b>
439+
│ <b>└── myextension.json</b>
440+
└── setup.py
441+
</pre>
442+
443+
The new ``.json`` file should look something like this (you'll notice the changes in the configured class and trait names):
444+
445+
.. code-block:: json
446+
447+
{
448+
"ServerApp": {
449+
"jpserver_extensions": {
450+
"myextension": true
451+
}
452+
}
453+
}
454+
455+
Update your extension package's ``setup.py`` so that the data-files are moved into the jupyter configuration directories when users download the package.
456+
457+
.. code-block:: python
458+
459+
from setuptools import setup
460+
461+
setup(
462+
name="myextension",
463+
...
464+
include_package_data=True,
465+
data_files=[
466+
(
467+
"etc/jupyter/jupyter_server_config.d",
468+
["jupyter-config/jupyter_server_config.d/myextension.json"]
469+
),
470+
(
471+
"etc/jupyter/jupyter_notebook_config.d",
472+
["jupyter-config/jupyter_notebook_config.d/myextension.json"]
473+
),
474+
]
475+
476+
)
477+
478+
3. (Optional) Point extension at the new favicon location.
479+
The favicons in the Jupyter Notebook have been moved to a new location in Jupyter Server. If your extension is using one of these icons, you'll want to add a set of redirect handlers this. (In ``ExtensionApp``, this is handled automatically).
480+
481+
This usually means adding a chunk to your ``load_jupyter_server_extension`` function similar to this:
482+
483+
.. code-block:: python
484+
485+
def load_jupyter_server_extension(nb_server_app):
486+
487+
web_app = nb_server_app.web_app
488+
host_pattern = '.*$'
489+
base_url = web_app.settings['base_url']
490+
491+
# Add custom extensions handler.
492+
custom_handlers = [
493+
...
494+
]
495+
496+
# Favicon redirects.
497+
favicon_redirects = [
498+
(
499+
url_path_join(base_url, "/static/favicons/favicon.ico"),
500+
RedirectHandler,
501+
{"url": url_path_join(serverapp.base_url, "static/base/images/favicon.ico")
502+
),
503+
(
504+
url_path_join(base_url, "/static/favicons/favicon-busy-1.ico"),
505+
RedirectHandler,
506+
{"url": url_path_join(serverapp.base_url, "static/base/images/favicon-busy-1.ico")}
507+
),
508+
(
509+
url_path_join(base_url, "/static/favicons/favicon-busy-2.ico"),
510+
RedirectHandler,
511+
{"url": url_path_join(serverapp.base_url, "static/base/images/favicon-busy-2.ico")}
512+
),
513+
(
514+
url_path_join(base_url, "/static/favicons/favicon-busy-3.ico"),
515+
RedirectHandler,
516+
{"url": url_path_join(serverapp.base_url, "static/base/images/favicon-busy-3.ico")}
517+
),
518+
(
519+
url_path_join(base_url, "/static/favicons/favicon-file.ico"),
520+
RedirectHandler,
521+
{"url": url_path_join(serverapp.base_url, "static/base/images/favicon-file.ico")}
522+
),
523+
(
524+
url_path_join(base_url, "/static/favicons/favicon-notebook.ico"),
525+
RedirectHandler,
526+
{"url": url_path_join(serverapp.base_url, "static/base/images/favicon-notebook.ico")}
527+
),
528+
(
529+
url_path_join(base_url, "/static/favicons/favicon-terminal.ico"),
530+
RedirectHandler,
531+
{"url": url_path_join(serverapp.base_url, "static/base/images/favicon-terminal.ico")}
532+
),
533+
(
534+
url_path_join(base_url, "/static/logo/logo.png"),
535+
RedirectHandler,
536+
{"url": url_path_join(serverapp.base_url, "static/base/images/logo.png")}
537+
),
538+
]
539+
540+
web_app.add_handlers(
541+
host_pattern,
542+
custom_handlers + favicon_redirects
543+
)
544+
545+
546+
.. _`classic Notebook Server`: https://jupyter-notebook.readthedocs.io/en/stable/extending/handlers.html

0 commit comments

Comments
 (0)