diff --git a/docs/source/examples/Notebook/Distributing Jupyter Extensions as Python Packages.ipynb b/docs/source/examples/Notebook/Distributing Jupyter Extensions as Python Packages.ipynb index 43e2d1b54..2f95bc5be 100644 --- a/docs/source/examples/Notebook/Distributing Jupyter Extensions as Python Packages.ipynb +++ b/docs/source/examples/Notebook/Distributing Jupyter Extensions as Python Packages.ipynb @@ -31,7 +31,7 @@ "metadata": {}, "source": [ "### Why create a Python package for Jupyter extensions?\n", - "Since it is rare to have a server extension that does not have any frontend components (an nbextension), for convenience and consistency, all these client and server extensions with their assets can be packaged and versioned together as a Python package with a few simple commands. This makes installing the package of extensions easier and less error-prone for the user. " + "Since it is rare to have a server extension that does not have any frontend components (an nbextension), for convenience and consistency, all these client and server extensions with their assets can be packaged and versioned together as a Python package with a few simple commands, or as of Notebook 5.3, handled automatically by your package manager of choice. This makes installing the package of extensions easier and less error-prone for the user." ] }, { @@ -52,6 +52,16 @@ "```" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Automatic installation and Enabling\n", + "> New in Notebook 5.3\n", + "\n", + "The absolute simplest case requires no user interaction at all! Configured correctly, after installing with their package manager of choice, both server and frontend extensions can be enabled by default in the environment where they were installed, i.e. `--sys-prefix`. See the `setup.py` in the example below." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -259,6 +269,130 @@ "```" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Automatically enabling a server extension and nbextension\n", + "> New in Notebook 5.3\n", + "\n", + "Server extensions and nbextensions can be installed and enabled without any user intervention or post-install scripts beyond ` install `" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition to the `my_fancy_module` file tree, assume:\n", + "- `jupyter-config/`\n", + " - `jupyter_notebook_config.d/`\n", + " - `my_fancy_module.json`\n", + " - `nbconfig/`\n", + " - `notebook.d/`\n", + " - `my_fancy_module.json`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### `jupyter-config/jupyter_notebook_config.d/my_fancy_module.json`\n", + "```json\n", + "{\n", + " \"NotebookApp\": {\n", + " \"nbserver_extensions\": {\n", + " \"my_fancy_module\": true\n", + " }\n", + " }\n", + "}\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### `jupyter-config/nbconfig/notebook.d/my_fancy_module.json`\n", + "```json\n", + "{\n", + " \"load_extensions\": {\n", + " \"my_fancy_module/index\": true\n", + " }\n", + "}\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Put all of them in place via:\n", + "\n", + "#### `setup.py`\n", + "```python\n", + "import setuptools\n", + "\n", + "setuptools.setup(\n", + " name=\"MyFancyModule\",\n", + " ...\n", + " include_package_data=True,\n", + " data_files=[\n", + " # like `jupyter nbextension install --sys-prefix`\n", + " (\"share/jupyter/nbextensions/my_fancy_module\", [\n", + " \"my_fancy_module/static/index.js\",\n", + " ]),\n", + " # like `jupyter nbextension enable --sys-prefix`\n", + " (\"etc/jupyter/nbconfig/notebook.d\", [\n", + " \"jupyter-config/nbconfig/notebook.d/my_fancy_module.json\"\n", + " ]),\n", + " # like `jupyter serverextension enable --sys-prefix`\n", + " (\"etc/jupyter/jupyter_notebook_config.d\", [\n", + " \"jupyter-config/jupyter_notebook_config.d/my_fancy_module.json\"\n", + " ])\n", + " ],\n", + " ...\n", + " zip_safe=False\n", + ")\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and last, but not least:\n", + "\n", + "#### `MANIFEST.in`\n", + "```config\n", + "recursive-include jupyter-config *.json\n", + "recursive-include my_fancy_module/static *.js\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As most package managers will only modify their environment, the eventual configuration will be as if the user had typed:\n", + "```\n", + "jupyter nbextension install --py my_fancy_module --sys-prefix\n", + "jupyter nbextension enable --py my_fancy_module --sys-prefix\n", + "jupyter serverextension enable --py my_fancy_module --sys-prefix\n", + "```\n", + "\n", + "If a user manually `disable`s an extension, that configuration will override the bundled package configuration." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### When automagical install fails\n", + "Note this can still fail in certain situations with `pip`, requiring manual use of `install` and `enable` commands.\n", + "\n", + "Non-python-specific package managers (e.g. `conda`, `apt`) may choose not to implement the above behavior at the `setup.py` level, having more ways to put data files in various places at build time." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -368,7 +502,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.1" + "version": "3.6.5" } }, "nbformat": 4,