For more detailed information, see `GitHub <https://github.com/jupyter/notebook>`__.
For more detailed information, see
`GitHub <https://github.com/jupyter/notebook>`__.
..tip::
@ -42,7 +43,8 @@ All users are strongly encouraged to upgrade to 4.2.2.
could be added to the page in a way that could execute javascript.
- Fix missing POST in OPTIONS responses.
- Fix for downloading non-ascii filenames.
- Avoid clobbering ssl_options, so that users can specify more detailed SSL configuration.
- Avoid clobbering ssl_options, so that users can specify more detailed SSL
configuration.
- Fix inverted load order in nbconfig, so user config has highest priority.
- Improved error messages here and there.
@ -85,7 +87,8 @@ Highlighted changes:
- Restore ability for notebook directory to be root (4.1 regression)
- Large outputs are now throttled, reducing the ability of output floods to
kill the browser.
- Fix the notebook ignoring cell executions while a kernel is starting by queueing the messages.
- Fix the notebook ignoring cell executions while a kernel is starting by
queueing the messages.
- Fix handling of url prefixes (e.g. JupyterHub) in terminal and edit pages.
- Support nested SVGs in output.
@ -108,31 +111,43 @@ Bug fixes:
UI changes:
- Moved the cell toolbar selector into the *View* menu. Added a button that triggers a "hint" animation to the main toolbar so users can find the new location. (Click here to see a `screencast <https://cloud.githubusercontent.com/assets/335567/10711889/59665a5a-7a3e-11e5-970f-86b89592880c.gif>`__ )
- Moved the cell toolbar selector into the *View* menu. Added a button that
triggers a "hint" animation to the main toolbar so users can find the new
location. (Click here to see a `screencast <https://cloud.githubusercontent.com/assets/335567/10711889/59665a5a-7a3e-11e5-970f-86b89592880c.gif>`__ )
..image:: /_static/images/cell-toolbar-41.png
- Added *Restart & Run All* to the *Kernel* menu. Users can also bind it to a keyboard shortcut on action ``restart-kernel-and-run-all-cells``.
- Added multiple-cell selection. Users press ``Shift-Up/Down`` or ``Shift-K/J`` to extend selection in command mode. Various actions such as cut/copy/paste, execute, and cell type conversions apply to all selected cells.
- Added *Restart & Run All* to the *Kernel* menu. Users can also bind it to a
keyboard shortcut on action ``restart-kernel-and-run-all-cells``.
- Added multiple-cell selection. Users press ``Shift-Up/Down`` or ``Shift-K/J``
to extend selection in command mode. Various actions such as cut/copy/paste,
execute, and cell type conversions apply to all selected cells.
..image:: /_static/images/multi-select-41.png
- Added a command palette for executing Jupyter actions by name. Users press ``Cmd/Ctrl-Shift-P`` or click the new command palette icon on the toolbar.
- Added a command palette for executing Jupyter actions by name. Users press
``Cmd/Ctrl-Shift-P`` or click the new command palette icon on the toolbar.
..image:: /_static/images/command-palette-41.png
- Added a *Find and Replace* dialog to the *Edit* menu. Users can also press ``F`` in command mode to show the dialog.
- Added a *Find and Replace* dialog to the *Edit* menu. Users can also press
``F`` in command mode to show the dialog.
..image:: /_static/images/find-replace-41.png
Other improvements:
- Custom KernelManager methods can be Tornado coroutines, allowing async operations.
- Make clearing output optional when rewriting input with ``set_next_input(replace=True)``.
- Custom KernelManager methods can be Tornado coroutines, allowing async
operations.
- Make clearing output optional when rewriting input with
``set_next_input(replace=True)``.
- Added support for TLS client authentication via ``--NotebookApp.client-ca``.
- Added tags to ``jupyter/notebook`` releases on DockerHub. ``latest`` continues to track the master branch.
- Added tags to ``jupyter/notebook`` releases on DockerHub. ``latest``
continues to track the master branch.
See the 4.1 milestone on GitHub for a complete list of `issues <https://github.com/jupyter/notebook/issues?page=3&q=milestone%3A4.1+is%3Aclosed+is%3Aissue&utf8=%E2%9C%93>`__ and `pull requests <https://github.com/jupyter/notebook/pulls?q=milestone%3A4.1+is%3Aclosed+is%3Apr>`__ handled.
See the 4.1 milestone on GitHub for a complete list of
The notebook server supports the writing of *bundler extensions* that transform, package, and download/deploy notebook files. As a developer, you need only write a single Python function to implement a bundler. The notebook server automatically generates a *File -> Download as* or *File -> Deploy as* menu item in the notebook front-end to trigger your bundler.
The notebook server supports the writing of *bundler extensions* that
transform, package, and download/deploy notebook files. As a developer, you
need only write a single Python function to implement a bundler. The notebook
server automatically generates a *File -> Download as* or *File -> Deploy as*
menu item in the notebook front-end to trigger your bundler.
Here are some examples of what you can implement using bundler extensions:
* Convert a notebook file to a HTML document and publish it as a post on a blog site
* Create a snapshot of the current notebook environment and bundle that definition plus notebook into a zip download
* `Deploy a notebook as a standalone, interactive dashboard <https://github.com/jupyter-incubator/dashboards_bundlers>`_
* Convert a notebook file to a HTML document and publish it as a post on a
blog site
* Create a snapshot of the current notebook environment and bundle that
definition plus notebook into a zip download
* Deploy a notebook as a standalone, interactive `dashboard <https://github.com/jupyter-incubator/dashboards_bundlers>`_
To implement a bundler extension, you must do all of the following:
@ -20,7 +26,10 @@ The following sections describe these steps in detail.
Declaring bundler metadata
--------------------------
You must provide information about the bundler extension(s) your package provides by implementing a `_jupyter_bundlerextensions_paths` function. This function can reside anywhere in your package so long as it can be imported when enabling the bundler extension. (See :ref:`enabling-bundlers`.)
You must provide information about the bundler extension(s) your package
provides by implementing a `_jupyter_bundlerextensions_paths` function. This
function can reside anywhere in your package so long as it can be imported
when enabling the bundler extension. (See :ref:`enabling-bundlers`.)
..code:: python
@ -34,15 +43,21 @@ You must provide information about the bundler extension(s) your package provide
'group': 'deploy' # group under 'deploy' or 'download' menu
}]
Note that the return value is a list. By returning multiple dictionaries in the list, you allow users to enable/disable sets of bundlers all at once.
Note that the return value is a list. By returning multiple dictionaries in
the list, you allow users to enable/disable sets of bundlers all at once.
Writing the `bundle` function
-----------------------------
At runtime, a menu item with the given label appears either in the *File -> Deploy as* or *File -> Download as* menu depending on the `group` value in your metadata. When a user clicks the menu item, a new browser tab opens and notebook server invokes a `bundle` function in the `module_name` specified in the metadata.
At runtime, a menu item with the given label appears either in the
*File -> Deploy as* or *File -> Download as* menu depending on the `group`
value in your metadata. When a user clicks the menu item, a new browser tab
opens and notebook server invokes a `bundle` function in the `module_name`
specified in the metadata.
You must implement a `bundle` function that matches the signature of the following example:
You must implement a `bundle` function that matches the signature of the
following example:
..code:: python
@ -50,13 +65,13 @@ You must implement a `bundle` function that matches the signature of the followi
def bundle(handler, model):
"""Transform, convert, bundle, etc. the notebook referenced by the given
model.
Then issue a Tornado web response using the `handler` to redirect
the user's browser, download a file, show a HTML page, etc. This function
must finish the handler response before returning either explicitly or by
model.
Then issue a Tornado web response using the `handler` to redirect
the user's browser, download a file, show a HTML page, etc. This function
must finish the handler response before returning either explicitly or by
raising an exception.
Parameters
----------
handler : tornado.web.RequestHandler
@ -65,10 +80,17 @@ You must implement a `bundle` function that matches the signature of the followi
Your `bundle` function is free to do whatever it wants with the request and respond in any manner. For example, it may read additional query parameters from the request, issue a redirect to another site, run a local process (e.g., `nbconvert`), make a HTTP request to another service, etc.
The caller of the `bundle` function is `@tornado.gen.coroutine` decorated and wraps its call with `torando.gen.maybe_future`. This behavior means you may handle the web request synchronously, as in the example above, or asynchronously using `@tornado.gen.coroutine` and `yield`, as in the example below.
Your `bundle` function is free to do whatever it wants with the request and
respond in any manner. For example, it may read additional query parameters
from the request, issue a redirect to another site, run a local process (e.g.,
`nbconvert`), make a HTTP request to another service, etc.
The caller of the `bundle` function is `@tornado.gen.coroutine` decorated and
wraps its call with `torando.gen.maybe_future`. This behavior means you may
handle the web request synchronously, as in the example above, or
asynchronously using `@tornado.gen.coroutine` and `yield`, as in the example
below.
..code:: python
@ -82,26 +104,35 @@ The caller of the `bundle` function is `@tornado.gen.coroutine` decorated and wr
You should prefer the second, asynchronous approach when your bundle operation is long-running and would otherwise block the notebook server main loop if handled synchronously.
You should prefer the second, asynchronous approach when your bundle operation
is long-running and would otherwise block the notebook server main loop if
handled synchronously.
For more details about the data flow from menu item click to bundle function invocation, see :ref:`bundler-details`.
For more details about the data flow from menu item click to bundle function
invocation, see :ref:`bundler-details`.
.._enabling-bundlers:
Enabling/disabling bundler extensions
-------------------------------------
The notebook server includes a command line interface (CLI) for enabling and disabling bundler extensions.
The notebook server includes a command line interface (CLI) for enabling and
disabling bundler extensions.
You should document the basic commands for enabling and disabling your bundler. One possible command for enabling the `hello_bundler` example is the following:
You should document the basic commands for enabling and disabling your
bundler. One possible command for enabling the `hello_bundler` example is the
The above updates the notebook configuration file in the current conda/virtualenv environment (`--sys-prefix`) with the metadata returned by the `mypackage.hellow_bundler._jupyter_bundlerextension_paths` function.
The corresponding command to later disable the bundler extension is the following:
The above updates the notebook configuration file in the current
conda/virtualenv environment (`--sys-prefix`) with the metadata returned by
the `mypackage.hellow_bundler._jupyter_bundlerextension_paths` function.
The corresponding command to later disable the bundler extension is the
following:
..code:: bash
@ -112,13 +143,17 @@ For more help using the `bundlerextension` subcommand, run the following.
..code:: bash
jupyter bundlerextension --help
The output describes options for listing enabled bundlers, configuring bundlers for single users, configuring bundlers system-wide, etc.
The output describes options for listing enabled bundlers, configuring
bundlers for single users, configuring bundlers system-wide, etc.
Example: IPython Notebook bundle (.zip)
---------------------------------------
The `hello_bundler` example in this documentation is simplisitic in the name of brevity. For more meaningful examples, see `notebook/bundler/zip_bundler.py` and `notebook/bundler/tarball_bundler.py`. You can enable them to try them like so:
The `hello_bundler` example in this documentation is simplisitic in the name
of brevity. For more meaningful examples, see
`notebook/bundler/zip_bundler.py` and `notebook/bundler/tarball_bundler.py`.
You can enable them to try them like so:
..code:: bash
@ -130,13 +165,19 @@ The `hello_bundler` example in this documentation is simplisitic in the name of
Bundler invocation details
--------------------------
Support for bundler extensions comes from Python modules in `notebook/bundler` and JavaScript in `notebook/static/notebook/js/menubar.js`. The flow of data between the various components proceeds roughly as follows:
Support for bundler extensions comes from Python modules in `notebook/bundler`
and JavaScript in `notebook/static/notebook/js/menubar.js`. The flow of data
between the various components proceeds roughly as follows:
:ref:`secure a notebook server <notebook_server_security>` and how to
:ref:`run it on a public interface <notebook_public_server>`.
:ref:`run it on a public interface <notebook_public_server>`.
..important::
..important::
**This is not the multi-user server you are looking for**. This document describes how you can run a public server with a single user. This should only be done by someone who wants remote access to their personal machine. Even so, doing this requires a thorough understanding of the set-ups limitations and security implications. If you allow multiple users to access a notebook server as it is described in this document, their commands may collide, clobber and overwrite each other.
**This is not the multi-user server you are looking for**. This document
describes how you can run a public server with a single user. This should
only be done by someone who wants remote access to their personal machine.
Even so, doing this requires a thorough understanding of the set-ups
limitations and security implications. If you allow multiple users to
access a notebook server as it is described in this document, their
commands may collide, clobber and overwrite each other.
If you want a multi-user server, the official solution is JupyterHub_. To use JupyterHub, you need a Unix server (typically Linux) running somewhere that is accessible to your users on a network. This may run over the public internet, but doing so introduces additional `security concerns <https://jupyterhub.readthedocs.io/en/latest/getting-started.html#security>`_.
If you want a multi-user server, the official solution is JupyterHub_.
To use JupyterHub, you need a Unix server (typically Linux) running
somewhere that is accessible to your users on a network. This may run over
the public internet, but doing so introduces additional