notebook.rst 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. Notebook
  2. --------
  3. Background
  4. ~~~~~~~~~~
  5. `JupyterLab Walkthrough June 16, 2016 YouTube
  6. video <https://www.youtube.com/watch?v=4Qm6oD_Rlw8&feature=youtu.be&t=55m19s>`__
  7. The most complicated plugin included in the **JupyterLab application**
  8. is the **Notebook plugin**.
  9. The
  10. `NotebookWidgetFactory <http://jupyterlab.github.io/jupyterlab/classes/_notebook_src_widgetfactory_.notebookwidgetfactory.html>`__
  11. constructs a new
  12. `NotebookPanel <http://jupyterlab.github.io/jupyterlab/classes/_notebook_src_panel_.notebookpanel.html>`__
  13. from a model and populates the toolbar with default widgets.
  14. Structure of the Notebook plugin
  15. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16. The Notebook plugin provides a model and widgets for dealing with
  17. notebook files.
  18. Model
  19. ^^^^^
  20. The
  21. **`NotebookModel <http://jupyterlab.github.io/jupyterlab/classes/_notebook_src_model_.notebookmodel.html>`__**
  22. contains an observable list of cells.
  23. A **`cell
  24. model <http://jupyterlab.github.io/jupyterlab/modules/_cells_src_model_.html>`__**
  25. can be:
  26. - a code cell
  27. - a markdown cell
  28. - raw cell
  29. A code cell contains a list of **output models**. The list of cells and
  30. the list of outputs can be observed for changes.
  31. Cell operations
  32. '''''''''''''''
  33. The NotebookModel cell list supports single-step operations such as
  34. moving, adding, or deleting cells. Compound cell list operations, such
  35. as undo/redo, are also supported by the NotebookModel. Right now,
  36. undo/redo is only supported on cells and is not supported on notebook
  37. attributes, such as notebook metadata. Currently, undo/redo for
  38. individual cell input content is supported by the CodeMirror editor's
  39. undo feature. (Note: CodeMirror editor's undo does not cover cell
  40. metadata changes.)
  41. Cursors and metadata
  42. ''''''''''''''''''''
  43. The notebook model and the cell model (i.e. notebook cells) support
  44. getting and setting metadata through cursors. You may request a cursor
  45. to write to a specific metadata key from a notebook model or a cell
  46. model.
  47. Notebook widget
  48. ^^^^^^^^^^^^^^^
  49. After the NotebookModel is created, the NotebookWidgetFactory constructs
  50. a new NotebookPanel from the model. The NotebookPanel widget is added to
  51. the DockPanel. The **NotebookPanel** contains:
  52. - a
  53. `Toolbar <http://jupyterlab.github.io/jupyterlab/modules/_apputils_src_toolbar_.html>`__
  54. - a `Notebook
  55. widget <http://jupyterlab.github.io/jupyterlab/classes/_notebook_src_widget_.notebook.html>`__.
  56. The NotebookPanel also adds completion logic.
  57. The **NotebookToolbar** maintains a list of widgets to add to the
  58. toolbar. The **Notebook widget** contains the rendering of the notebook
  59. and handles most of the interaction logic with the notebook itself (such
  60. as keeping track of interactions such as selected and active cells and
  61. also the current edit/command mode).
  62. The NotebookModel cell list provides ways to do fine-grained changes to
  63. the cell list.
  64. Higher level actions using NotebookActions
  65. ''''''''''''''''''''''''''''''''''''''''''
  66. Higher-level actions are contained in the
  67. `NotebookActions <http://jupyterlab.github.io/jupyterlab/modules/_notebook_src_actions_.notebookactions.html>`__
  68. namespace, which has functions, when given a notebook widget, to run a
  69. cell and select the next cell, merge or split cells at the cursor,
  70. delete selected cells, etc.
  71. Widget hierarchy
  72. ''''''''''''''''
  73. A Notebook widget contains a list of `cell
  74. widgets <http://jupyterlab.github.io/jupyterlab/modules/_cells_src_widget_.html>`__,
  75. corresponding to the cell models in its cell list.
  76. - Each cell widget contains an
  77. `InputArea <http://jupyterlab.github.io/jupyterlab/classes/_cells_src_inputarea_.inputarea.html>`__,
  78. - which contains n
  79. `CodeEditorWrapper <http://jupyterlab.github.io/jupyterlab/classes/_codeeditor_src_widget_.codeeditorwrapper.html>`__,
  80. - which contains a JavaScript CodeMirror instance.
  81. A
  82. `CodeCell <http://jupyterlab.github.io/jupyterlab/classes/_cells_src_widget_.codecell.html>`__
  83. also contains an
  84. `OutputArea <http://jupyterlab.github.io/jupyterlab/classes/_outputarea_src_widget_.outputarea.html>`__.
  85. An OutputArea is responsible for rendering the outputs in the
  86. `OutputAreaModel <http://jupyterlab.github.io/jupyterlab/classes/_outputarea_src_model_.outputareamodel.html>`__
  87. list. An OutputArea uses a notebook-specific
  88. `RenderMimeRegistry <http://jupyterlab.github.io/jupyterlab/classes/_rendermime_src_registry_.rendermimeregistry.html>`__
  89. object to render ``display_data`` output messages.
  90. Rendering output messages
  91. '''''''''''''''''''''''''
  92. A **Rendermime plugin** provides a pluggable system for rendering output
  93. messages. Default renderers are provided for markdown, html, images,
  94. text, etc. Extensions can register renderers to be used across the
  95. entire application by registering a handler and mimetype in the
  96. rendermime registry. When a notebook is created, it copies the global
  97. Rendermime singleton so that notebook-specific renderers can be added.
  98. The ipywidgets widget manager is an example of an extension that adds a
  99. notebook-specific renderer, since rendering a widget depends on
  100. notebook-specific widget state.
  101. How to extend the Notebook plugin
  102. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  103. We'll walk through two notebook extensions:
  104. - adding a button to the toolbar
  105. - adding an ipywidgets extension
  106. Adding a button to the toolbar
  107. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  108. Start from the cookie cutter extension template.
  109. ::
  110. pip install cookiecutter
  111. cookiecutter https://github.com/jupyterlab/extension-cookiecutter-ts
  112. cd my-cookie-cutter-name
  113. Install the dependencies. Note that extensions are built against the
  114. released npm packages, not the development versions.
  115. ::
  116. npm install --save @jupyterlab/notebook @jupyterlab/application @jupyterlab/apputils @jupyterlab/docregistry @phosphor/disposable
  117. Copy the following to ``src/index.ts``:
  118. .. code:: typescript
  119. import {
  120. IDisposable, DisposableDelegate
  121. } from '@phosphor/disposable';
  122. import {
  123. JupyterLab, JupyterLabPlugin
  124. } from '@jupyterlab/application';
  125. import {
  126. ToolbarButton
  127. } from '@jupyterlab/apputils';
  128. import {
  129. DocumentRegistry
  130. } from '@jupyterlab/docregistry';
  131. import {
  132. NotebookActions, NotebookPanel, INotebookModel
  133. } from '@jupyterlab/notebook';
  134. /**
  135. * The plugin registration information.
  136. */
  137. const plugin: JupyterLabPlugin<void> = {
  138. activate,
  139. id: 'my-extension-name:buttonPlugin',
  140. autoStart: true
  141. };
  142. /**
  143. * A notebook widget extension that adds a button to the toolbar.
  144. */
  145. export
  146. class ButtonExtension implements DocumentRegistry.IWidgetExtension<NotebookPanel, INotebookModel> {
  147. /**
  148. * Create a new extension object.
  149. */
  150. createNew(panel: NotebookPanel, context: DocumentRegistry.IContext<INotebookModel>): IDisposable {
  151. let callback = () => {
  152. NotebookActions.runAll(panel.notebook, context.session);
  153. };
  154. let button = new ToolbarButton({
  155. className: 'myButton',
  156. onClick: callback,
  157. tooltip: 'Run All'
  158. });
  159. let i = document.createElement('i');
  160. i.classList.add('fa', 'fa-fast-forward');
  161. button.node.appendChild(i);
  162. panel.toolbar.insertItem(0, 'runAll', button);
  163. return new DisposableDelegate(() => {
  164. button.dispose();
  165. });
  166. }
  167. }
  168. /**
  169. * Activate the extension.
  170. */
  171. function activate(app: JupyterLab) {
  172. app.docRegistry.addWidgetExtension('Notebook', new ButtonExtension());
  173. };
  174. /**
  175. * Export the plugin as default.
  176. */
  177. export default plugin;
  178. Run the following commands:
  179. ::
  180. npm install
  181. npm run build
  182. jupyter labextension install .
  183. jupyter lab
  184. Open a notebook and observe the new "Run All" button.
  185. The *ipywidgets* third party extension
  186. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  187. This discussion will be a bit confusing since we've been using the term
  188. **widget** to refer to **phosphor widgets**. In the discussion below,
  189. *ipython widgets* will be referred to as *ipywidgets*. There is no
  190. intrinsic relation between **phosphor widgets** and *ipython widgets*.
  191. The *ipywidgets* extension registers a factory for a notebook **widget**
  192. extension using the `Document
  193. Registry <http://jupyterlab.github.io/jupyterlab/classes/_docregistry_src_registry_.documentregistry.html>`__.
  194. The ``createNew()`` function is called with a NotebookPanel and
  195. [DocumentContext]
  196. (http://jupyterlab.github.io/jupyterlab/interfaces/_docregistry_src_registry_.documentregistry.icontext.html).
  197. The plugin then creates a ipywidget manager (which uses the context to
  198. interact the kernel and kernel's comm manager). The plugin then
  199. registers an ipywidget renderer with the notebook instance's rendermime
  200. (which is specific to that particular notebook).
  201. When an ipywidget model is created in the kernel, a comm message is sent
  202. to the browser and handled by the ipywidget manager to create a
  203. browser-side ipywidget model. When the model is displayed in the kernel,
  204. a ``display_data`` output is sent to the browser with the ipywidget
  205. model id. The renderer registered in that notebook's rendermime is asked
  206. to render the output. The renderer asks the ipywidget manager instance
  207. to render the corresponding model, which returns a JavaScript promise.
  208. The renderer creates a container **phosphor widget** which it hands back
  209. synchronously to the OutputArea, and then fills the container with the
  210. rendered *ipywidget* when the promise resolves.
  211. Note: The ipywidgets third party extension has not yet been released.