Skip to main content

jupyterlab_unsafe_globals

Github Actions Status

Expose the classic Notebook globals (Jupyter, IPython) on the window, for JupyterLab and Jupyter Notebook.

The classic Notebook (< 7.0) exposed a Jupyter object (and its IPython alias) on the browser window. Many scripts and snippets relied on it, for example Jupyter.notebook.save_checkpoint() or Jupyter.notebook.kernel.execute(...). Jupyter Notebook 7+ and JupyterLab removed these globals on purpose (see jupyter/notebook#6394).

This extension restores a subset of those globals as an opt-in compatibility shim, implemented on top of the modern JupyterLab APIs. It is a transition aid, not a replacement for a proper port to the JupyterLab extension APIs.

screenshot showing some of the IPython and Jupyter globals used in the dev tools

⚠️ Warning: this is unsafe by design

Restoring these globals restores the security posture of the classic Notebook: any JavaScript running in the page, including code injected from a kernel with IPython.display.Javascript, can read, modify, execute, and save the current notebook, and reach the whole application through Jupyter.app. Install it only if you understand and accept this. Do not install it by default for other users.

Requirements

  • JupyterLab >= 4.0.0 or Jupyter Notebook >= 7.0.0

Install

To install the extension, execute:

pip install jupyterlab_unsafe_globals

Usage

After installing, window.Jupyter and window.IPython (a plain alias, like in classic) are available on notebook pages:

// insert a cell and run code on the kernel, classic style
const cell = Jupyter.notebook.insert_cell_below('code');
cell.set_text('print("hello")');

Jupyter.notebook.kernel.execute('1 + 1', {
  iopub: { output: msg => console.log(msg.content) },
  shell: { reply: msg => console.log(msg.content.status) }
});

Jupyter.notebook.save_checkpoint();

Jupyter.events.on('kernel_idle.Kernel', () => console.log('idle'));

Jupyter.notebook always points to the current notebook of the notebook tracker. In Jupyter Notebook there is one notebook per page, like in classic; in JupyterLab it is the most recently focused notebook, and null when no notebook is open.

What is shimmed

  • Jupyter.notebook: cell access and selection (get_cells, get_cell, get_selected_cell, get_selected_index, ncells, select, select_all, ...), insertion, deletion, movement, merge and split (insert_cell_above/below/at_index, delete_cell(s), move_cell_up/down, merge_cells, split_cell), the cell clipboard (copy_cell, cut_cell, paste_cell_above/below/replace, undelete_cell), type conversion (to_code, to_markdown, to_raw), outputs (clear_output, clear_all_output, toggle_output, collapse_output, expand_output), execution (execute_cell, execute_selected_cells, execute_all_cells, execute_cells, execute_cell_range), saving and checkpoints (save_notebook, save_checkpoint, create/list/restore/delete_checkpoint), rename, trust_notebook, kernel lifecycle (restart_kernel, restart_run_all, restart_clear_output, shutdown_kernel, start_session), and properties (metadata, dirty, trusted, mode, notebook_name, notebook_path, base_url, writable, _fully_loaded, session, contents, keyboard_manager).
  • Jupyter.notebook.kernel: execute(code, callbacks, options) with the exact classic callback shape and defaults (silent: true, store_history: false, stop_on_error: true), complete, inspect, kernel_info, comm_info, send_shell_message, interrupt, restart, reconnect, is_connected, send_input_reply, id, name, username, ws_url, info_reply, and comm_manager (register_target, new_comm, and classic Comm objects with send, on_msg, on_close).
  • Jupyter.events (also Jupyter.notebook.events): on, one, off, trigger with the jQuery conventions; emits over 30 classic events, including notebook_loaded/saved/renamed.Notebook, before_save.Notebook, the checkpoint events, create/delete/select.Cell, execute/finished_execute.CodeCell, rendered.MarkdownCell, output_appended.OutputArea, and the kernel lifecycle events (kernel_ready/busy/idle/restarting/dead.Kernel).
  • Jupyter.keyboard_manager: actions.register/call/get backed by the application command registry, and command_shortcuts / edit_shortcuts with add_shortcut(s) accepting the classic shortcut strings ('ctrl-shift-h', 'd,d').
  • Jupyter.toolbar.add_buttons_group, applied to every notebook toolbar, with FontAwesome 4 icons bundled.
  • Jupyter.dialog.modal, backed by the JupyterLab dialog.
  • Jupyter.contents (also Jupyter.notebook.contents): the classic contents API over the JupyterLab contents manager.
  • Jupyter.notebook.session: id, kernel, delete, restart, list.
  • Jupyter.menubar._nbconvert, Jupyter.actions (deprecated alias), Jupyter.version, Jupyter._target, and Jupyter.app (the JupyterFrontEnd application, not part of classic, provided as the migration escape hatch).

Cell objects support get_text, set_text, cell_type, metadata, execute, render, unrender, rendered, select, unselect, focus_cell, is_editable, is_deletable, input_prompt_number, set_input_prompt, line number toggles, notebook, events, element (a raw DOM node unless jQuery is present), output_area (outputs, append_output, clear_output, collapse and scroll toggles), and code_mirror (a CodeMirror 5 style adapter with getValue, setValue, cursor and selection methods, and the lineNumbers/readOnly options), plus widget, the underlying JupyterLab cell widget.

What is not shimmed

The classic constructors (Jupyter.CodeCell, ...), requirejs module access and prototype patching, and the other page globals ($, require, _, CodeMirror, MathJax) are out of scope. Jupyter.notebook.config is an inert stub whose loaded promise resolves immediately, so extensions that gate on it proceed with their defaults. CodeMirror 6 cannot serve the CM5 configuration APIs (gutters, folding, themes); those methods are absent and fail loudly. Full classic nbextensions will usually not run on this shim; port them to real JupyterLab extensions instead.

Note: metadata reads and writes work at the top level (metadata.foo = {...}); nested in-place mutations (metadata.foo.bar = 1) are not persisted, assign the whole sub-object instead.

Uninstall

To remove the extension, execute:

pip uninstall jupyterlab_unsafe_globals

Contributing

If you would like to contribute to this extension, please refer to the Contributing Guide.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jupyterlab_unsafe_globals-0.1.1.tar.gz (957.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jupyterlab_unsafe_globals-0.1.1-py3-none-any.whl (547.4 kB view details)

Uploaded Python 3

File details

Details for the file jupyterlab_unsafe_globals-0.1.1.tar.gz.

File metadata

File hashes

Hashes for jupyterlab_unsafe_globals-0.1.1.tar.gz
Algorithm Hash digest
SHA256 ee8a11df7bf341a97003f1ecc5987c685fef59a53aa44f9e22bde15933b79039
MD5 5a54d532d784bb65c2eeffc8388a1ccd
BLAKE2b-256 a0262d5668af3c3ffcab0ee53fb17c01f9722a91d3c2332d1ee1a955a0bc847e

See more details on using hashes here.

File details

Details for the file jupyterlab_unsafe_globals-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for jupyterlab_unsafe_globals-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5e2ff0e80088a16444cf78002f939471dfe471944fd499f33c4422c2eaea458a
MD5 a592e0431eb6027eedde711161eb7110
BLAKE2b-256 bf5f935ad8edb09d606d07cc1d81edbfbba8bfad7d4acc2a99c68b6508c9c0eb

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page