diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 5fa9f9cd5..eb75254e6 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -5,8 +5,8 @@ If you're reading this section, you're probably interested in contributing to Jupyter. Welcome and thanks for your interest in contributing! Please take a look at the Contributor documentation, familiarize yourself with -using the Jupyter Notebook, and introduce yourself on the mailing list and share -what area of the project you are interested in working on. +using the Jupyter Notebook, and introduce yourself on the mailing list and +share what area of the project you are interested in working on. General Guidelines ------------------ @@ -141,8 +141,8 @@ or to run just ``notebook/tests/notebook/deletecell.js``:: Building the Documentation -------------------------- -To build the documentation you'll need `Sphinx `_, `pandoc `_ -and a few other packages. +To build the documentation you'll need `Sphinx `_, +`pandoc `_ and a few other packages. To install (and activate) a `conda environment`_ named ``notebook_docs`` containing all the necessary packages (except pandoc), use:: diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 008e28ba4..76e8bd358 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -4,7 +4,8 @@ Jupyter notebook changelog ========================== A summary of changes in the Jupyter notebook. -For more detailed information, see `GitHub `__. +For more detailed information, see +`GitHub `__. .. 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 `__ ) +- 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 `__ ) .. 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 `__ and `pull requests `__ handled. +See the 4.1 milestone on GitHub for a complete list of +`issues `__ +and `pull requests `__ handled. 4.0.x ----- diff --git a/docs/source/config_overview.rst b/docs/source/config_overview.rst index d176d42e2..5a346b7d5 100644 --- a/docs/source/config_overview.rst +++ b/docs/source/config_overview.rst @@ -25,8 +25,8 @@ and editing settings is similar for all the Jupyter applications. - `Jupyter’s Common Configuration Approach `_ - `Common Directories and File Locations `_ - `Language kernels `_ - - `traitlets `_ provide a low-level - architecture for configuration. + - `traitlets `_ + provide a low-level architecture for configuration. .. _configure_nbserver: @@ -35,28 +35,30 @@ Notebook server The Notebook server runs the language kernel and communicates with the front-end Notebook client (i.e. the familiar notebook interface). - - Configuring the Notebook server + - Configuring the Notebook server - To create a ``jupyter_notebook_config.py`` file in the ``.jupyter`` - directory, with all the defaults commented out, use the following - command:: + To create a ``jupyter_notebook_config.py`` file in the ``.jupyter`` + directory, with all the defaults commented out, use the following + command:: - $ jupyter notebook --generate-config + $ jupyter notebook --generate-config - :ref:`Command line arguments for configuration ` settings are - documented in the configuration file and the user documentation. + :ref:`Command line arguments for configuration ` settings are + documented in the configuration file and the user documentation. - - :ref:`Running a Notebook server ` - - Related: `Configuring a language kernel `_ - to run in the Notebook server enables your server to run other languages, like R or Julia. + - :ref:`Running a Notebook server ` + - Related: `Configuring a language kernel `_ + to run in the Notebook server enables your server to run other languages, like R or Julia. .. _configure_nbclient: Notebook front-end client ------------------------- - :ref:`How front-end configuration works ` - * :ref:`Example: Changing the notebook's default indentation setting ` - * :ref:`Example: Restoring the notebook's default indentation setting ` + * :ref:`Example: Changing the notebook's default indentation setting + ` + * :ref:`Example: Restoring the notebook's default indentation setting + ` - :ref:`Persisting configuration settings ` .. _configure_nbextensions: diff --git a/docs/source/extending/bundler_extensions.rst b/docs/source/extending/bundler_extensions.rst index f4dc9f948..9712d9806 100644 --- a/docs/source/extending/bundler_extensions.rst +++ b/docs/source/extending/bundler_extensions.rst @@ -1,13 +1,19 @@ Custom bundler extensions ========================= -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 `_ +* 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 `_ 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 'module_name': 'mypackage.hello_bundler', # module containing bundle() '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 Notebook model from the configured ContentManager """ handler.finish('I bundled {}!'.format(model['path'])) - -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 # now respond handler.finish('I spent 10 seconds bundling {}!'.format(model['path'])) -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 +following: .. code:: bash jupyter bundlerextension enable --py mypackage.hello_bundler --sys-prefix - -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: 1. User opens a notebook document 2. Notebook front-end JavaScript loads notebook configuration -3. Bundler front-end JS creates menu items for all bundler extensions in the config +3. Bundler front-end JS creates menu items for all bundler extensions in the + config 4. User clicks a bundler menu item -5. JS click handler opens a new browser window/tab to `/bundle/?bundler=` (i.e., a HTTP GET request) +5. JS click handler opens a new browser window/tab to + `/bundle/?bundler=` (i.e., a + HTTP GET request) 6. Bundle handler validates the notebook path and bundler `name` -7. Bundle handler delegates the request to the `bundle` function in the bundler's `module_name` -8. `bundle` function finishes the HTTP request \ No newline at end of file +7. Bundle handler delegates the request to the `bundle` function in the + bundler's `module_name` +8. `bundle` function finishes the HTTP request diff --git a/docs/source/extending/contents.rst b/docs/source/extending/contents.rst index 9271d8ecd..4c116706d 100644 --- a/docs/source/extending/contents.rst +++ b/docs/source/extending/contents.rst @@ -67,7 +67,7 @@ Models may contain the following entries: .. _modelcontent: Certain model fields vary in structure depending on the ``type`` field of the -model. There are three model types: **notebook**, **file**, and **directory** . +model. There are three model types: **notebook**, **file**, and **directory**. - ``notebook`` models - The ``format`` field is always ``"json"``. diff --git a/docs/source/extending/frontend_extensions.rst b/docs/source/extending/frontend_extensions.rst index 66fe560f8..e1a852de6 100644 --- a/docs/source/extending/frontend_extensions.rst +++ b/docs/source/extending/frontend_extensions.rst @@ -207,11 +207,11 @@ You can install your nbextension with the command:: jupyter nbextension install path/to/my_extension/ [--user|--sys-prefix] -The default installation is system-wide. You can use ``--user`` to do a per-user installation, -or ``--sys-prefix`` to install to Python's prefix (e.g. in a virtual or conda environment). -Where my_extension is the directory containing the Javascript files. -This will copy it to a Jupyter data directory (the exact location is platform -dependent - see :ref:`jupyter_path`). +The default installation is system-wide. You can use ``--user`` to do a +per-user installation, or ``--sys-prefix`` to install to Python's prefix (e.g. +in a virtual or conda environment). Where my_extension is the directory +containing the Javascript files. This will copy it to a Jupyter data directory +(the exact location is platform dependent - see :ref:`jupyter_path`). For development, you can use the ``--symlink`` flag to symlink your extension rather than copying it, so there's no need to reinstall after changes. @@ -267,11 +267,12 @@ Here is an example of ``kernel.js``:: .. code:: javascript - // kernel.js - define(function(){ return {onload: function(){ console.info('Kernel specific javascript loaded'); - // do more things here, like define a codemirror mode, + + // do more things here, like define a codemirror mode + }} + }); diff --git a/docs/source/extending/handlers.rst b/docs/source/extending/handlers.rst index 119f1e304..f8a7dc613 100644 --- a/docs/source/extending/handlers.rst +++ b/docs/source/extending/handlers.rst @@ -23,7 +23,7 @@ when the extension is loaded. def load_jupyter_server_extension(nb_server_app): """ Called when the extension is loaded. - + Args: nb_server_app (NotebookWebApplication): handle to the Notebook webserver instance. """ @@ -98,7 +98,7 @@ Notebook server. See the following example: route_pattern = url_path_join(web_app.settings['base_url'], '/hello') web_app.add_handlers(host_pattern, [(route_pattern, HelloWorldHandler)]) -Putting this together with the extension code, the example looks like the +Putting this together with the extension code, the example looks like the following: .. code:: python @@ -113,7 +113,7 @@ following: def load_jupyter_server_extension(nb_server_app): """ Called when the extension is loaded. - + Args: nb_server_app (NotebookWebApplication): handle to the Notebook webserver instance. """ @@ -122,6 +122,6 @@ following: route_pattern = url_path_join(web_app.settings['base_url'], '/hello') web_app.add_handlers(host_pattern, [(route_pattern, HelloWorldHandler)]) -References: -1. `Peter Parente's -Mindtrove `__ +References: + +1. `Peter Parente's Mindtrove `__ diff --git a/docs/source/extending/keymaps.rst b/docs/source/extending/keymaps.rst index cceac75c9..1d2cc7334 100644 --- a/docs/source/extending/keymaps.rst +++ b/docs/source/extending/keymaps.rst @@ -3,9 +3,9 @@ Customize keymaps .. note:: - Declarative Custom Keymaps is a provisional feature with unstable API which is not - guaranteed to be kept in future versions of the notebook, and can be - removed or changed without warnings. + Declarative Custom Keymaps is a provisional feature with unstable API + which is not guaranteed to be kept in future versions of the notebook, + and can be removed or changed without warnings. The notebook shortcuts that are defined by jupyter both in edit mode an command mode are configurable in the frontend configuration file @@ -14,15 +14,16 @@ suffer of several limitations, mainly that your Browser and OS might prevent certain shortcut to work correctly. If this is the case, there are unfortunately not much than can be done. The second issue can arise with keyboard that have a layout different than US English. Again even if we are -aware of the issue, there is not much we can do about that. +aware of the issue, there is not much we can do about that. Shortcut are also limited by the underlying library that handle code and text edition: CodeMirror. If some Keyboard shortcuts are conflicting, the method describe below might not work to create new keyboard shortcuts, especially in -the ``edit`` mode of the notebook. +the ``edit`` mode of the notebook. -The 4 sections of interest in ``~/.jupyter/nbconfig/notebook.json`` are the following: +The 4 sections of interest in ``~/.jupyter/nbconfig/notebook.json`` are the +following: - ``keys.command.unbind`` - ``keys.edit.unbind`` @@ -31,7 +32,7 @@ The 4 sections of interest in ``~/.jupyter/nbconfig/notebook.json`` are the foll The first two section describe which default keyboard shortcut not to register at notebook startup time. These are mostly useful if you need to ``unbind`` a -default keyboard shortcut before binding it to a new ``command``. +default keyboard shortcut before binding it to a new ``command``. These two first sections apply respectively to the ``command`` and ``edit`` mode of the notebook. They take a list of shortcut to ``unbind``. @@ -57,10 +58,11 @@ cursor (``Ctrl-Shift-Minus``)use the following: The last two section describe which new keyboard shortcut to register -at notebook startup time, and which actions they trigger. +at notebook startup time, and which actions they trigger. -These two last sections apply respectively to the ``command`` and ``edit`` mode of the notebook. -They take a dictionary with shortcuts as ``keys`` and ``commands`` name as value. +These two last sections apply respectively to the ``command`` and ``edit`` +mode of the notebook. They take a dictionary with shortcuts as ``keys`` and +``commands`` name as value. For example, to bind the shortcut ``G,G,G`` (Press G three time in a row) in command mode, to the command that restart the kernel and run all cells, use the @@ -85,4 +87,4 @@ following: The name of the available ``commands`` can be find by hovering the right end of -a row in the command palette. +a row in the command palette. diff --git a/docs/source/extending/savehooks.rst b/docs/source/extending/savehooks.rst index c07cdaf09..470597ba8 100644 --- a/docs/source/extending/savehooks.rst +++ b/docs/source/extending/savehooks.rst @@ -4,9 +4,9 @@ File save hooks You can configure functions that are run whenever a file is saved. There are two hooks available: -* ``ContentsManager.pre_save_hook`` runs on the API path and model with content. - This can be used for things like stripping output that people don't like - adding to VCS noise. +* ``ContentsManager.pre_save_hook`` runs on the API path and model with + content. This can be used for things like stripping output that people don't + like adding to VCS noise. * ``FileContentsManager.post_save_hook`` runs on the filesystem path and model without content. This could be used to commit changes after every save, for instance. @@ -43,10 +43,12 @@ A pre-save hook for stripping output:: A post-save hook to make a script equivalent whenever the notebook is saved (replacing the ``--script`` option in older versions of the notebook):: +.. sourcecode:: python + import io import os from notebook.utils import to_api_path - + _script_exporter = None def script_post_save(model, os_path, contents_manager, **kwargs): @@ -60,8 +62,10 @@ A post-save hook to make a script equivalent whenever the notebook is saved return global _script_exporter + if _script_exporter is None: _script_exporter = ScriptExporter(parent=contents_manager) + log = contents_manager.log base, ext = os.path.splitext(os_path) @@ -69,9 +73,12 @@ A post-save hook to make a script equivalent whenever the notebook is saved script, resources = _script_exporter.from_filename(os_path) script_fname = base + resources.get('output_extension', '.txt') log.info("Saving script /%s", to_api_path(script_fname, contents_manager.root_dir)) + with io.open(script_fname, 'w', encoding='utf-8') as f: f.write(script) + c.FileContentsManager.post_save_hook = script_post_save + This could be a simple call to ``jupyter nbconvert --to script``, but spawning the subprocess every time is quite slow. diff --git a/docs/source/notebook.rst b/docs/source/notebook.rst index 698bedbac..e1a5b133e 100644 --- a/docs/source/notebook.rst +++ b/docs/source/notebook.rst @@ -22,7 +22,8 @@ text, mathematics, images, and rich media representations of objects. .. seealso:: - See the :ref:`installation guide ` on how to install the notebook and its dependencies. + See the :ref:`installation guide ` on how to install the + notebook and its dependencies. Main features of the web application @@ -376,12 +377,13 @@ Specific plotting library integration is a feature of the kernel. Installing kernels ------------------ -For information on how to install a Python kernel, refer to the `IPython install -page `__. +For information on how to install a Python kernel, refer to the +`IPython install page `__. Kernels for other languages can be found in the `IPython wiki `_. -They usually come with instruction what to run to make the kernel available in the notebook. +They usually come with instruction what to run to make the kernel available +in the notebook. .. _signing_notebooks: @@ -396,8 +398,9 @@ If the signature stored in the notebook metadata does not match, javascript and HTML output will not be displayed on load, and must be regenerated by re-executing the cells. -Any notebook that you have executed yourself *in its entirety* will be considered trusted, -and its HTML and javascript output will be displayed on load. +Any notebook that you have executed yourself *in its entirety* will be +considered trusted, and its HTML and javascript output will be displayed on +load. If you need to see HTML or Javascript output without re-executing, you can explicitly trust notebooks, such as those shared with you, @@ -417,13 +420,15 @@ You can generate a new notebook signing key with:: Browser Compatibility --------------------- -The Jupyter Notebook is officially supported the latest stable version the following browsers: +The Jupyter Notebook is officially supported the latest stable version the +following browsers: * Chrome * Safari * Firefox -The is mainly due to the notebook's usage of WebSockets and the flexible box model. +The is mainly due to the notebook's usage of WebSockets and the flexible box +model. The following browsers are unsupported: diff --git a/docs/source/public_server.rst b/docs/source/public_server.rst index b1482854b..cb2701cbe 100644 --- a/docs/source/public_server.rst +++ b/docs/source/public_server.rst @@ -16,13 +16,23 @@ serving HTTP requests. This document describes how you can :ref:`secure a notebook server ` and how to -:ref:`run it on a public interface `. +:ref:`run it on a public interface `. -.. 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 `_. + 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 `_. @@ -30,7 +40,7 @@ This document describes how you can .. _Tornado: http://www.tornadoweb.org -.. _JupyterHub: https://jupyterhub.readthedocs.io/en/latest/ +.. _JupyterHub: https://jupyterhub.readthedocs.io/en/latest/ .. _notebook_server_security: @@ -78,16 +88,18 @@ You can prepare a hashed password using the function Adding hashed password to your notebook configuration file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can then add the hashed password to your :file:`jupyter_notebook_config.py`. -The default location for this file :file:`jupyter_notebook_config.py` is in -your Jupyter folder in your home directory, ``~/.jupyter``, e.g.:: +You can then add the hashed password to your +:file:`jupyter_notebook_config.py`. The default location for this file +:file:`jupyter_notebook_config.py` is in your Jupyter folder in your home +directory, ``~/.jupyter``, e.g.:: c.NotebookApp.password = u'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed' Using SSL for encrypted communication ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When using a password, it is a good idea to also use SSL with a web certificate, -so that your hashed password is not sent unencrypted by your browser. +When using a password, it is a good idea to also use SSL with a web +certificate, so that your hashed password is not sent unencrypted by your +browser. .. important:: Web security is rapidly changing and evolving. We provide this document @@ -113,9 +125,10 @@ with the command:: When starting the notebook server, your browser may warn that your self-signed certificate is insecure or unrecognized. If you wish to have a fully compliant self-signed certificate that will not raise warnings, it is possible -(but rather involved) to create one, as explained in detail in this `tutorial`_. -Alternatively, you may use `Let's Encrypt`_ to acquire a free SSL certificate -and follow the steps in :ref:`using-lets-encrypt` to set up a public server. +(but rather involved) to create one, as explained in detail in this +`tutorial`_. Alternatively, you may use `Let's Encrypt`_ to acquire a free SSL +certificate and follow the steps in :ref:`using-lets-encrypt` to set up a +public server. .. _OWASP: https://www.owasp.org .. _tutorial: http://arstechnica.com/security/news/2009/12/how-to-get-set-with-a-secure-sertificate-for-free.ars @@ -145,7 +158,8 @@ all fields commented out. The minimum set of configuration options that you should uncomment and edit in :file:`jupyter_notebook_config.py` is the following:: - # Set options for certfile, ip, password, and toggle off browser auto-opening + # Set options for certfile, ip, password, and toggle off + # browser auto-opening c.NotebookApp.certfile = u'/absolute/path/to/your/certificate/mycert.pem' c.NotebookApp.keyfile = u'/absolute/path/to/your/certificate/mykey.key' # Set ip to '*' to bind on all interfaces (ips) for the public server @@ -172,7 +186,7 @@ certificate with a few configuration changes. Here are the steps: 2. Use :ref:`hashed-pw` to create one. 3. If you don't already have config file for the notebook, create one using the following command: - + .. code-block:: bash $ jupyter notebook --generate-config @@ -183,7 +197,8 @@ all fields commented out. The minimum set of configuration options that you should to uncomment and edit in :file:`jupyter_notebook_config.py` is the following:: - # Set options for certfile, ip, password, and toggle off browser auto-opening + # Set options for certfile, ip, password, and toggle off + # browser auto-opening c.NotebookApp.certfile = u'/absolute/path/to/your/certificate/fullchain.pem' c.NotebookApp.keyfile = u'/absolute/path/to/your/certificate/privkey.pem' # Set ip to '*' to bind on all interfaces (ips) for the public server @@ -249,10 +264,12 @@ instructions about modifying ``jupyter_notebook_config.py``): Embedding the notebook in another website ----------------------------------------- -Sometimes you may want to embed the notebook somewhere on your website, e.g. in an IFrame. -To do this, you may need to override the Content-Security-Policy to allow embedding. -Assuming your website is at `https://mywebsite.example.com`, -you can embed the notebook on your website with the following configuration setting in :file:`jupyter_notebook_config.py`: +Sometimes you may want to embed the notebook somewhere on your website, +e.g. in an IFrame. To do this, you may need to override the +Content-Security-Policy to allow embedding. Assuming your website is at +`https://mywebsite.example.com`, you can embed the notebook on your website +with the following configuration setting in +:file:`jupyter_notebook_config.py`: .. sourcecode:: python @@ -266,7 +283,8 @@ When embedding the notebook in a website using an iframe, consider putting the notebook in single-tab mode. Since the notebook opens some links in new tabs by default, single-tab mode keeps the notebook from opening additional tabs. -Adding the following to :file:`~/.jupyter/custom/custom.js` will enable single-tab mode: +Adding the following to :file:`~/.jupyter/custom/custom.js` will enable +single-tab mode: .. sourcecode:: javascript