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.

Metadata

Release files for jupyterlab-unsafe-globals 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jupyterlab-unsafe-globals 0.1.1
File Size Uploaded Provenance Actions
jupyterlab_unsafe_globals-0.1.1.tar.gz 957.8 kB Without provenance Details for jupyterlab_unsafe_globals-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for jupyterlab-unsafe-globals 0.1.1
File Interpreter ABI Platform Actions
jupyterlab_unsafe_globals-0.1.1-py3-none-any.whl Python 3 none any Details for jupyterlab_unsafe_globals-0.1.1-py3-none-any.whl

Total release size: 1.5 MB

Release files / jupyterlab_unsafe_globals-0.1.1.tar.gz

Download URL jupyterlab_unsafe_globals-0.1.1.tar.gz
Size 957.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ee8a11df7bf341a97003f1ecc5987c685fef59a53aa44f9e22bde15933b79039
BLAKE2b-256 checksum
How to use checksums
a0262d5668af3c3ffcab0ee53fb17c01f9722a91d3c2332d1ee1a955a0bc847e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / jupyterlab_unsafe_globals-0.1.1-py3-none-any.whl

Download URL jupyterlab_unsafe_globals-0.1.1-py3-none-any.whl
Size 547.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5e2ff0e80088a16444cf78002f939471dfe471944fd499f33c4422c2eaea458a
BLAKE2b-256 checksum
How to use checksums
bf5f935ad8edb09d606d07cc1d81edbfbba8bfad7d4acc2a99c68b6508c9c0eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.12.14

Security for jupyterlab-unsafe-globals 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page