jupyterlab_unsafe_globals
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.
⚠️ 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, andcomm_manager(register_target,new_comm, and classicCommobjects withsend,on_msg,on_close).Jupyter.events(alsoJupyter.notebook.events):on,one,off,triggerwith the jQuery conventions; emits over 30 classic events, includingnotebook_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/getbacked by the application command registry, andcommand_shortcuts/edit_shortcutswithadd_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(alsoJupyter.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, andJupyter.app(theJupyterFrontEndapplication, 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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.