Skip to content

Commit

Permalink
Update to JupyterLab 2.0 (jupyterlab#70)
Browse files Browse the repository at this point in the history
* Update to JupyterLab 2.0

* Run embedme

* Add python kernelPreference

* Fix kernel selection dialog

* Fix launcher card with custom icon

* Update to rc2

* Fix icons

* Fix embedme

* Use same TypeScript version everywhere

* Update to 2.0 final
  • Loading branch information
jtpio authored Feb 29, 2020
1 parent 2f87d40 commit c555052
Show file tree
Hide file tree
Showing 51 changed files with 343 additions and 365 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
python-version: '3.7'
architecture: 'x64'
- name: Install the Python dependencies
run: python -m pip install jupyterlab
run: python -m pip install jupyterlab --pre
- name: Install the NPM dependencies
run: |
cd ${EXAMPLE_FOLDER}
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
python-version: '3.7'
architecture: 'x64'
- name: Install the Python dependencies
run: python -m pip install jupyterlab
run: python -m pip install jupyterlab --pre
- name: Install the NPM dependencies
run: |
cd advanced/server-extension
Expand Down Expand Up @@ -136,7 +136,7 @@ jobs:
python-version: '3.7'
architecture: 'x64'
- name: Install the Python dependencies
run: python -m pip install jupyterlab
run: python -m pip install jupyterlab --pre
- name: Bootstrap the jlpm deps
run: jlpm
- name: Build all the extensions
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ git clone https://github.com/jtpio/jupyterlab-extension-examples.git &&
jupyter lab --watch
```

The examples currently target **JupyterLab 2.x**.

If you would like to use the examples with JupyterLab 1.x, check out the [1.x branch](https://github.com/jtpio/jupyterlab-extension-examples/tree/1.x). Note that the `1.x` branch is not updated anymore.

## Develop by Examples

You may find it easier to learn how to create extensions _by examples_, instead of going through the documentation.
Expand Down
101 changes: 60 additions & 41 deletions advanced/kernel-messaging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,36 @@ execution result.

## Initializing and managing a kernel session (`panel.ts`)

Jupyterlab provides a class `ClientSession`
([see the documentation](https://jupyterlab.github.io/jupyterlab/apputils/classes/clientsession.html))
Jupyterlab provides a class `SessionContext`
([see the documentation](https://jupyterlab.github.io/jupyterlab/apputils/classes/sessioncontext.html))
that manages a single kernel session. Here is the code to initialize such session:

```ts
// src/panel.ts#L29-L32
// src/panel.ts#L33-L37

this._session = new ClientSession({
manager: manager.sessions,
this._sessionContext = new SessionContext({
sessionManager: manager.sessions,
specsManager: manager.kernelspecs,
name: 'Example'
});
```

<!-- prettier-ignore-start -->
<!-- embedme src/panel.ts#L38-L42 -->
<!-- embedme src/panel.ts#L43-L54 -->

```ts
this._session.initialize().catch(reason => {
console.error(
`Failed to initialize the session in ExamplePanel.\n${reason}`
);
});
void this._sessionContext
.initialize()
.then(async value => {
if (value) {
await sessionContextDialogs.selectKernel(this._sessionContext);
}
})
.catch(reason => {
console.error(
`Failed to initialize the session in ExamplePanel.\n${reason}`
);
});
```
<!-- prettier-ignore-end -->

Expand All @@ -66,12 +74,12 @@ const manager = app.serviceManager;
With these lines, you can extend the panel widget from the [signal example](../../basics/signals) to initialize a
kernel. In addition, you will create a `KernelModel` class in it and
overwrite the `dispose` and `onCloseRequest` methods of the `StackedPanel`
([see the documentation](https://phosphorjs.github.io/phosphor/api/widgets/classes/stackedpanel.html))
([see the documentation](https://jupyterlab.github.io/lumino/api/widgets/classes/stackedpanel.html))
to free the kernel session resources if the panel is closed. The whole adapted
panel class looks like this:

```ts
// src/panel.ts#L21-L62
// src/panel.ts#L25-L74

export class ExamplePanel extends StackedPanel {
constructor(manager: ServiceManager.IManager) {
Expand All @@ -81,28 +89,36 @@ export class ExamplePanel extends StackedPanel {
this.title.label = 'Example View';
this.title.closable = true;

this._session = new ClientSession({
manager: manager.sessions,
this._sessionContext = new SessionContext({
sessionManager: manager.sessions,
specsManager: manager.kernelspecs,
name: 'Example'
});

this._model = new KernelModel(this._session);
this._model = new KernelModel(this._sessionContext);
this._example = new KernelView(this._model);

this.addWidget(this._example);
this._session.initialize().catch(reason => {
console.error(
`Failed to initialize the session in ExamplePanel.\n${reason}`
);
});
void this._sessionContext
.initialize()
.then(async value => {
if (value) {
await sessionContextDialogs.selectKernel(this._sessionContext);
}
})
.catch(reason => {
console.error(
`Failed to initialize the session in ExamplePanel.\n${reason}`
);
});
}

get session(): IClientSession {
return this._session;
get session(): ISessionContext {
return this._sessionContext;
}

dispose(): void {
this._session.dispose();
this._sessionContext.dispose();
super.dispose();
}

Expand All @@ -112,20 +128,21 @@ export class ExamplePanel extends StackedPanel {
}

private _model: KernelModel;
private _session: ClientSession;
private _sessionContext: SessionContext;
private _example: KernelView;
}
```

## Executing code and retrieving messages from a kernel (`model.ts`)

Once a kernel is initialized and ready, code can be executed on it through
the `ClientSession` object with the following snippet:
Once a kernel is initialized and ready, code can be executed with the following snippet:

```ts
// src/model.ts#L46-L46
// src/model.ts#L46-L48

this.future = this._session.kernel.requestExecute({ code });
this.future = this._sessionContext.session?.kernel?.requestExecute({
code
});
```

`future` is an object that can receive some messages from the kernel as a
Expand All @@ -136,16 +153,16 @@ types `execute_result`, `display_data` and `update_display_data`.

Once such a message is received by the `future` object, it can trigger an
action. In this case, that message is stored in `this._output`. Then
a `stateChanged` signal is emitted.
a `stateChanged` signal is emitted.
The `KernelModel` has a `stateChanged` signal that will be used by the
view. It is implemented as follows:

```ts
// src/model.ts#L9-L72
// src/model.ts#L9-L74

export class KernelModel {
constructor(session: IClientSession) {
this._session = session;
constructor(session: ISessionContext) {
this._sessionContext = session;
}

get future(): Kernel.IFuture<
Expand All @@ -168,7 +185,7 @@ export class KernelModel {
value.onIOPub = this._onIOPub;
}

get output(): nbformat.IOutput | null {
get output(): IOutput | null {
return this._output;
}

Expand All @@ -177,10 +194,12 @@ export class KernelModel {
}

execute(code: string) {
if (!this._session || !this._session.kernel) {
if (!this._sessionContext || !this._sessionContext.session?.kernel) {
return;
}
this.future = this._session.kernel.requestExecute({ code });
this.future = this._sessionContext.session?.kernel?.requestExecute({
code
});
}

private _onIOPub = (msg: KernelMessage.IIOPubMessage) => {
Expand All @@ -189,7 +208,7 @@ export class KernelModel {
case 'execute_result':
case 'display_data':
case 'update_display_data':
this._output = msg.content as nbformat.IOutput;
this._output = msg.content as IOutput;
console.log(this._output);
this._stateChanged.emit();
break;
Expand All @@ -203,8 +222,8 @@ export class KernelModel {
KernelMessage.IExecuteRequestMsg,
KernelMessage.IExecuteReplyMsg
> | null = null;
private _output: nbformat.IOutput | null = null;
private _session: IClientSession;
private _output: IOutput | null = null;
private _sessionContext: ISessionContext;
private _stateChanged = new Signal<KernelModel, void>(this);
}
```
Expand All @@ -223,7 +242,7 @@ in a text field.

<!-- prettier-ignore-start -->
```ts
// src/widget.tsx#L26-L30
// src/widget.tsx#L25-L29

<UseSignal signal={this._model.stateChanged}>
{() => (
Expand All @@ -237,7 +256,7 @@ Finally to trigger a statement execution, the click event of a button is
implemented to call the `this._model.execute` method.

```ts
// src/widget.tsx#L17-L25
// src/widget.tsx#L16-L24

<button
key="header-thread"
Expand Down
18 changes: 10 additions & 8 deletions advanced/kernel-messaging/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,23 @@
"watch": "tsc -w"
},
"dependencies": {
"@jupyterlab/application": "^1.2.0",
"@jupyterlab/launcher": "^1.2.0",
"@jupyterlab/mainmenu": "^1.2.0",
"@phosphor/algorithm": "^1.2.0",
"@phosphor/coreutils": "^1.3.1",
"@phosphor/datagrid": "^0.3.1",
"@phosphor/disposable": "^1.3.1"
"@jupyterlab/application": "^2.0.0",
"@jupyterlab/launcher": "^2.0.0",
"@jupyterlab/mainmenu": "^2.0.0",
"@jupyterlab/nbformat": "^2.0.0",
"@lumino/algorithm": "^1.2.3",
"@lumino/coreutils": "^1.3.1",
"@lumino/datagrid": "^0.5.2",
"@lumino/disposable": "^1.3.1",
"@lumino/widgets": "^1.11.0"
},
"devDependencies": {
"rimraf": "^3.0.0",
"tslint": "^5.20.1",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^4.1.0",
"typescript": "^3.7.2"
"typescript": "~3.7.5"
},
"sideEffects": [
"style/*.css"
Expand Down
6 changes: 1 addition & 5 deletions advanced/kernel-messaging/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ILauncher } from '@jupyterlab/launcher';

import { IMainMenu } from '@jupyterlab/mainmenu';

import { Menu } from '@phosphor/widgets';
import { Menu } from '@lumino/widgets';

import { ExamplePanel } from './panel';

Expand Down Expand Up @@ -50,12 +50,8 @@ function activate(
}

async function createPanel(): Promise<ExamplePanel> {
await manager.ready;
const panel = new ExamplePanel(manager);

await panel.session.ready;
shell.add(panel, 'main');

return panel;
}

Expand Down
24 changes: 13 additions & 11 deletions advanced/kernel-messaging/src/model.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { IClientSession } from '@jupyterlab/apputils';
import { ISessionContext } from '@jupyterlab/apputils';

import { nbformat } from '@jupyterlab/coreutils';
import { IOutput } from '@jupyterlab/nbformat';

import { Kernel, KernelMessage } from '@jupyterlab/services';

import { ISignal, Signal } from '@phosphor/signaling';
import { ISignal, Signal } from '@lumino/signaling';

export class KernelModel {
constructor(session: IClientSession) {
this._session = session;
constructor(session: ISessionContext) {
this._sessionContext = session;
}

get future(): Kernel.IFuture<
Expand All @@ -31,7 +31,7 @@ export class KernelModel {
value.onIOPub = this._onIOPub;
}

get output(): nbformat.IOutput | null {
get output(): IOutput | null {
return this._output;
}

Expand All @@ -40,10 +40,12 @@ export class KernelModel {
}

execute(code: string) {
if (!this._session || !this._session.kernel) {
if (!this._sessionContext || !this._sessionContext.session?.kernel) {
return;
}
this.future = this._session.kernel.requestExecute({ code });
this.future = this._sessionContext.session?.kernel?.requestExecute({
code
});
}

private _onIOPub = (msg: KernelMessage.IIOPubMessage) => {
Expand All @@ -52,7 +54,7 @@ export class KernelModel {
case 'execute_result':
case 'display_data':
case 'update_display_data':
this._output = msg.content as nbformat.IOutput;
this._output = msg.content as IOutput;
console.log(this._output);
this._stateChanged.emit();
break;
Expand All @@ -66,7 +68,7 @@ export class KernelModel {
KernelMessage.IExecuteRequestMsg,
KernelMessage.IExecuteReplyMsg
> | null = null;
private _output: nbformat.IOutput | null = null;
private _session: IClientSession;
private _output: IOutput | null = null;
private _sessionContext: ISessionContext;
private _stateChanged = new Signal<KernelModel, void>(this);
}
Loading

0 comments on commit c555052

Please sign in to comment.