Skip to content

Commit e9aaf55

Browse files
authored
Merge pull request #4 from jtpio/discover-execute-commands
Discover and execute JupyterLab commands
2 parents 9d36817 + 044058a commit e9aaf55

File tree

7 files changed

+323
-275
lines changed

7 files changed

+323
-275
lines changed

README.md

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@ for the frontend extension.
1010

1111
## Features
1212

13-
- **Document Management**: Open documents in JupyterLab with various layout modes
14-
- **Markdown Preview**: Open markdown files in rendered preview mode
15-
- **Notebook Operations**: Clear outputs and show diffs for notebooks
16-
- **Jupyter AI Integration**: Tools available for use with Jupyter AI
13+
- **Command Discovery**: List all available JupyterLab commands with their metadata
14+
- **Command Execution**: Execute any JupyterLab command programmatically from Python
1715

1816
## Requirements
1917

20-
- JupyterLab >= 4.0.0
21-
- jupyter-ai (for AI toolkit functionality)
18+
- JupyterLab >= 4.5.0a3
2219

2320
## Install
2421

@@ -30,47 +27,29 @@ pip install jupyterlab_commands_toolkit
3027

3128
## Usage
3229

33-
### With Jupyter AI
34-
35-
The extension provides a toolkit for Jupyter AI with the following tools:
36-
37-
1. **open_document_tool**: Open documents in JupyterLab with various layout modes
38-
2. **open_markdown_preview_tool**: Open markdown files in rendered preview mode
39-
3. **clear_notebook_outputs_tool**: Clear all outputs in the active notebook
40-
4. **show_notebook_diff_tool**: Show git diff for the current notebook using nbdime
30+
Use the toolkit to execute any JupyterLab command from Python:
4131

4232
```python
43-
# Access the AI toolkit
44-
from jupyterlab_commands_toolkit import ai_toolkit
33+
import asyncio
34+
from jupyterlab_commands_toolkit.tools import execute_command, list_all_commands
4535

46-
# The toolkit is automatically available to Jupyter AI when installed
47-
```
36+
# Execute a command (requires running in an async context)
37+
async def main():
38+
# List all available commands
39+
commands = await list_all_commands()
4840

49-
### Direct Usage
41+
# Toggle the file browser
42+
result = await execute_command("filebrowser:toggle-main")
5043

51-
You can also use the commands directly:
52-
53-
```python
54-
from jupyterlab_commands_toolkit.tools import (
55-
open_document,
56-
open_markdown_file_in_preview_mode,
57-
clear_all_outputs_in_notebook,
58-
show_diff_of_current_notebook
59-
)
44+
# Run notebook cells
45+
result = await execute_command("notebook:run-all-cells")
6046

61-
# Open a document
62-
open_document("notebook.ipynb", mode="split-right")
63-
64-
# Open markdown in preview
65-
open_markdown_file_in_preview_mode("README.md")
66-
67-
# Clear notebook outputs
68-
clear_all_outputs_in_notebook(True)
69-
70-
# Show notebook diff
71-
show_diff_of_current_notebook(True)
47+
# Run in JupyterLab environment
48+
asyncio.run(main())
7249
```
7350

51+
For a full list of available commands in JupyterLab, refer to the [JupyterLab Command Registry documentation](https://jupyterlab.readthedocs.io/en/latest/user/commands.html#commands-list).
52+
7453
## Uninstall
7554

7655
To remove the extension, execute:

jupyterlab_commands_toolkit/__init__.py

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,73 @@
55
# in editable mode with pip. It is highly recommended to install
66
# the package from a stable release or in editable mode: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs
77
import warnings
8-
warnings.warn("Importing 'jupyterlab_commands_toolkit' outside a proper installation.")
8+
9+
warnings.warn(
10+
"Importing 'jupyterlab_commands_toolkit' outside a proper installation."
11+
)
912
__version__ = "dev"
1013

1114
import pathlib
1215

1316
from jupyter_server.serverapp import ServerApp
14-
from .toolkit import toolkit
1517

16-
# Export the AI toolkit for jupyter-ai integration
17-
try:
18-
from .toolkit import toolkit as ai_toolkit
19-
except ImportError:
20-
# If jupyter-ai is not available, the AI toolkit won't be available
21-
toolkit = None
2218

2319
def _jupyter_labextension_paths():
24-
return [{
25-
"src": "labextension",
26-
"dest": "jupyterlab-commands-toolkit"
27-
}]
20+
return [{"src": "labextension", "dest": "jupyterlab-commands-toolkit"}]
2821

2922

3023
def _jupyter_server_extension_points():
31-
return [{
32-
"module": "jupyterlab_commands_toolkit"
33-
}]
24+
return [{"module": "jupyterlab_commands_toolkit"}]
25+
3426

3527
def _load_jupyter_server_extension(serverapp: ServerApp):
36-
schema_path = pathlib.Path(__file__).parent / "events" / "jupyterlab-command.yml"
37-
serverapp.event_logger.register_event_schema(schema_path)
38-
serverapp.log.info("jupyterlab_commands_toolkit extension loaded.")
28+
command_schema_path = (
29+
pathlib.Path(__file__).parent / "events" / "jupyterlab-command.yml"
30+
)
31+
serverapp.event_logger.register_event_schema(command_schema_path)
32+
33+
result_schema_path = (
34+
pathlib.Path(__file__).parent / "events" / "jupyterlab-command-result.yml"
35+
)
36+
serverapp.event_logger.register_event_schema(result_schema_path)
37+
38+
async def command_result_listener(logger, schema_id: str, data: dict) -> None:
39+
"""
40+
Handle command result events from the frontend.
41+
42+
This listener receives the results of JupyterLab commands that were
43+
executed in the frontend and processes them accordingly.
44+
"""
45+
from .tools import handle_command_result
46+
47+
try:
48+
request_id = data.get("requestId", "unknown")
49+
success = data.get("success", False)
50+
result = data.get("result")
51+
error = data.get("error")
52+
53+
serverapp.log.info(
54+
f"Received command result for request {request_id}: success={success}"
55+
)
56+
57+
if success:
58+
if result is not None:
59+
serverapp.log.debug(f"Command result: {result}")
60+
else:
61+
serverapp.log.warning(f"Command failed: {error}")
62+
63+
handle_command_result(data)
64+
65+
except Exception as e:
66+
serverapp.log.error(f"Error processing command result: {e}")
67+
68+
result_schema_id = (
69+
"https://events.jupyter.org/jupyterlab_command_toolkit/lab_command_result/v1"
70+
)
71+
serverapp.event_logger.add_listener(
72+
schema_id=result_schema_id, listener=command_result_listener
73+
)
74+
75+
serverapp.log.info(
76+
"jupyterlab_commands_toolkit extension loaded with bidirectional event communication."
77+
)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"$id": https://events.jupyter.org/jupyterlab_command_toolkit/lab_command_result/v1
2+
version: 1
3+
title: A JupyterLab Command Execution Result
4+
personal-data: true
5+
description: |
6+
Result of a JupyterLab Command execution
7+
type: object
8+
required:
9+
- requestId
10+
- success
11+
properties:
12+
requestId:
13+
type: string
14+
description: The unique identifier for the command request
15+
success:
16+
type: boolean
17+
description: Whether the command executed successfully
18+
result:
19+
description: The result data from the command execution
20+
error:
21+
type: string
22+
description: Error message if the command failed

jupyterlab_commands_toolkit/toolkit.py

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)