Skip to content

Commit efe5dde

Browse files
add README file
1 parent c796766 commit efe5dde

File tree

5 files changed

+57
-66
lines changed

5 files changed

+57
-66
lines changed

README.md

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,79 @@
1-
# distributed_jupyter_demo
1+
# Distributed Jupyter Kernel Demo
22

33
[![Github Actions Status](https://github.com/QuantStack/distributed-jupyter-demo/workflows/Build/badge.svg)](https://github.com/QuantStack/distributed-jupyter-demo/actions/workflows/build.yml)
44

5-
A JupyterLab extension.
5+
This project demonstrates a **proof of concept** for using a custom JupyterLab plugin to connect to a **remote Jupyter server's kernel manager** using a shared token. It shows how one JupyterLab frontend (Server B) can start and interact with kernels running on another backend Jupyter server (Server A).
66

7-
## Requirements
7+
---
88

9-
- JupyterLab >= 4.0.0
9+
## 🧩 What This Demo Does
1010

11-
## Install
11+
- **Server A** is a Jupyter Server that exposes a kernel manager (with CORS enabled).
12+
- **Server B** is a JupyterLab instance running a custom **ServiceManagerPlugin**.
13+
- The plugin in Server B creates its own `KernelManager` that connects to Server A using a shared token and URL.
14+
- Kernels started from Server B appear and run on Server A.
1215

13-
To install the extension, execute:
16+
This can be a helpful starting point for building distributed or decoupled architectures in the Jupyter ecosystem (e.g., connecting to remote compute backends, multi-user systems, etc.).
1417

15-
```bash
16-
pip install distributed_jupyter_demo
17-
```
18+
---
1819

19-
## Uninstall
20+
## 🔧 Local Setup (Without Docker)
2021

21-
To remove the extension, execute:
22+
### 1. Create a Conda/mamba Environment and Install Dependencies
2223

2324
```bash
24-
pip uninstall distributed_jupyter_demo
25-
```
25+
conda create -n distributed-jupyter-demo python=3.11 -y
26+
conda activate distributed-jupyter-demo
2627

27-
## Contributing
28+
pip install -e . && pip install jupyterlab
29+
jlpm install
30+
jupyter labextension develop . --overwrite
31+
jupyter lab build
2832

29-
### Development install
33+
```
34+
35+
---
3036

31-
Note: You will need NodeJS to build the extension package.
37+
### 2. Start the Servers (In Separate Terminals)
3238

33-
The `jlpm` command is JupyterLab's pinned version of
34-
[yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use
35-
`yarn` or `npm` in lieu of `jlpm` below.
39+
**Terminal 1: Server A**
3640

3741
```bash
38-
# Clone the repo to your local environment
39-
# Change directory to the distributed_jupyter_demo directory
40-
# Install package in development mode
41-
pip install -e "."
42-
# Link your development version of the extension with JupyterLab
43-
jupyter labextension develop . --overwrite
44-
# Rebuild extension Typescript source after making changes
45-
jlpm build
42+
jupyter server --port 8888 --ServerApp.token=abc123 --ServerApp.allow_origin='http://localhost:8889'
4643
```
4744

48-
You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.
45+
**Terminal 2: Server B**
4946

5047
```bash
51-
# Watch the source directory in one terminal, automatically rebuilding when needed
52-
jlpm watch
53-
# Run JupyterLab in another terminal
54-
jupyter lab
48+
jupyter lab --port 8889 --ServerApp.token=abc123
5549
```
5650

57-
With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).
51+
Then open your browser at **http://localhost:8889/lab**. The kernel plugin will automatically start a kernel on Server A.
5852

59-
By default, the `jlpm build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:
53+
You can confirm the kernel was created by checking **http://localhost:8888/api/kernels**.
6054

61-
```bash
62-
jupyter lab build --minimize=False
63-
```
55+
## 🐳 Run with Docker
6456

65-
### Development uninstall
57+
This project comes with a ready-to-use Docker and Docker Compose setup.
58+
You will need to have **Docker** installed in your system.
59+
60+
### 1. Build and Start the Servers
6661

6762
```bash
68-
pip uninstall distributed_jupyter_demo
63+
docker compose up --build
6964
```
7065

71-
In development mode, you will also need to remove the symlink created by `jupyter labextension develop`
72-
command. To find its location, you can run `jupyter labextension list` to figure out where the `labextensions`
73-
folder is located. Then you can remove the symlink named `distributed-jupyter-demo` within that folder.
66+
This launches:
67+
68+
- **http://localhost:8888** → Server A (backend kernel server)
69+
- **http://localhost:8889** → Server B (JupyterLab frontend with plugin)
70+
71+
After going to **http://localhost:8889/lab**, Server B will start a kernel on Server A when loaded and you can see it in **http://localhost:8888/api/kernels**.
72+
73+
## 💡 Notes
74+
75+
This demo uses a shared token (abc123) to authenticate both servers. In production, proper security measures must be taken.
7476

75-
### Packaging the extension
77+
CORS is enabled on Server A to allow requests from Server B.
7678

77-
See [RELEASE](RELEASE.md)
79+
This setup assumes both servers are running on the same host, but the architecture can be adapted for different machines or containers.

docker-compose.yml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@ services:
44
container_name: jlab-serverA
55
ports:
66
- '8888:8888'
7-
volumes:
8-
- ./jupyter_serverA_config.py:/etc/jupyter/jupyter_server_config.py
9-
command: ["jupyter", "server", "--no-browser", "--config=/etc/jupyter/jupyter_server_config.py"]
7+
command: >
8+
jupyter server --no-browser
9+
--ip=0.0.0.0
10+
--port=8888
11+
--ServerApp.token=abc123
12+
--ServerApp.allow_origin=*
1013
1114
serverb:
1215
build: .
1316
container_name: jlab-serverB
1417
ports:
1518
- '8889:8889'
16-
volumes:
17-
- ./jupyter_serverB_config.py:/etc/jupyter/jupyter_server_config.py
18-
command: ["jupyter", "lab", "--no-browser", "--config=/etc/jupyter/jupyter_server_config.py"]
19+
command: >
20+
jupyter lab --no-browser
21+
--ip=0.0.0.0
22+
--port=8889
23+
--ServerApp.token=abc123

jupyter_serverA_config.py

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

jupyter_serverB_config.py

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

src/index.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ import {
66
ServiceManagerPlugin
77
} from '@jupyterlab/services';
88

9-
/*class CustomKernelManager extends KernelManager {
10-
async startNew(
11-
options: Partial<Pick<Kernel.IModel, 'name'>> | undefined
12-
): Promise<Kernel.IKernelConnection> {
13-
console.log('CustomKernelManager.startNew called with', options);
14-
return super.startNew(options);
15-
}
16-
}*/
17-
189
const kernelPlugin: ServiceManagerPlugin<Kernel.IManager> = {
1910
id: 'distributed-jupyter-demo:plugin',
2011
description: 'A JupyterLab extension providing a kernel manager',

0 commit comments

Comments
 (0)