Skip to content

Commit

Permalink
Fix getJupyterFrontEndModel & fix registerWidgetManager.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Fleming committed May 27, 2024
1 parent b1e305c commit 8ea26ff
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 34 deletions.
2 changes: 1 addition & 1 deletion examples/generic.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Some of the methods above have already been implemented in 'app.shell' on the Python object. And if you look at the code you'll see these methods use the *generic* method (technically, it is a subclass which inserts `'shell.'` infront of the path in the method `executeMethod` to match it's level in the JupyterFrontend Object. So basically the same function call is sent to the frontend.\n",
"Some of the methods above have already been implemented in 'app.shell' on the Python object. And if you look at the code you'll see these methods use the *generic* method (technically, it is a subclass which inserts `'shell.'` in front of the path in the method `executeMethod` to match it's level in the JupyterFrontend Object. So basically the same function call is sent to the frontend.\n",
"\n",
"In case you're interested, the custom part of message sent to the frontend looks like this:\n",
"\n",
Expand Down
2 changes: 1 addition & 1 deletion ipylab/main_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def load(
content: Panel | None = None,
area: Area = Area.main,
activate: bool = True,
mode: InsertMode = InsertMode.split_right,
mode: InsertMode = InsertMode.tab_after,
rank: int | None = None,
ref: str = "",
class_name="ipylab-main-area",
Expand Down
2 changes: 1 addition & 1 deletion ipylab/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
def init_ipylab_backend():
"""Initialize an ipylab backend.
Intended to run inside a kenrnel launched by Jupyter.
Intended to run inside a kernel launched by Jupyter.
"""
from ipylab.jupyterfrontend import JupyterFrontEnd

Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,8 @@
"@jupyterlab/launcher": "^4.1.0",
"@jupyterlab/observables": "^5.1.0",
"@jupyterlab/rendermime": "^4.1.0",
"@lumino/algorithm": "^2.0.1",
"@lumino/commands": "^2.2.0",
"@lumino/disposable": "^2.1.2",
"@lumino/messaging": "^2.0.1",
"@lumino/widgets": "^2.3.1"
},
"devDependencies": {
Expand Down
47 changes: 23 additions & 24 deletions src/widgets/frontend.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) ipylab contributors
// Distributed under the terms of the Modified BSD License.

import { unpack_models, uuid } from '@jupyter-widgets/base';
import { unpack_models } from '@jupyter-widgets/base';
import { LabShell } from '@jupyterlab/application';
import {
DOMUtils,
Expand Down Expand Up @@ -172,15 +172,15 @@ export class JupyterFrontEndModel extends IpylabModel {
let luminoWidget = view.luminoWidget;
if (area === 'main') {
luminoWidget = new IpylabMainAreaWidget({
content: view.luminoWidget,
content: view.luminoWidget as any,
kernelId: this.kernelId,
name: 'Ipylab'
});
}) as any;
}
if (!luminoWidget.id) {
luminoWidget.id = DOMUtils.createDomID();
}
this.shell.add(luminoWidget, area, options);
this.shell.add(luminoWidget as any, area, options);
onKernelLost(
(this.widget_manager as any).kernel,
luminoWidget.dispose,
Expand All @@ -196,42 +196,41 @@ export class JupyterFrontEndModel extends IpylabModel {
* @returns
*/
async getJupyterFrontEndModel(payload: any): Promise<JupyterFrontEndModel> {
const kernelId = payload.kernelId || uuid();
if (Private.jupyterFrontEndModels.has(kernelId)) {
return Private.jupyterFrontEndModels.get(kernelId);
if (payload.kernelId) {
if (Private.jupyterFrontEndModels.has(payload.kernelId)) {
return Private.jupyterFrontEndModels.get(payload.kernelId);
}
}
let kernel: Kernel.IKernelConnection;
const model = await this.app.serviceManager.kernels.findById(kernelId);
const model = await this.app.serviceManager.kernels.findById(
payload.kernelId
);
if (model) {
kernel = this.app.serviceManager.kernels.connectTo({ model: model });
} else {
payload.kernelId = kernelId;
const session = await newSession({
rendermime: IpylabModel.rendermime.clone(),
...payload
});
if (payload.kernelId) {
throw new Error(`Kernel does not exist: ${payload.kernelId}`);
}
const session = await newSession(payload);
kernel = session.kernel;
}
// Currently we need the kernel to create the JupyterFrontEnd widget.
// Currently we use the python kernel to create the JupyterFrontEnd widget.
const future = kernel.requestExecute({
code: 'import ipylab;_jfem=ipylab.JupyterFrontEnd()',
code: 'import ipylab;ipylab.JupyterFrontEnd()',
store_history: false,
stop_on_error: true,
silent: true,
allow_stdin: false,
user_expressions: { frontendId: '_jfem.model_id' }
allow_stdin: false
});
const result = (await future.done) as any;
if (
result.content.status !== 'ok' ||
!result.content.user_expressions.frontendId ||
!Private.jupyterFrontEndModels.has(kernelId)
) {
const jfem = Private.jupyterFrontEndModels.get(kernel.id);
if (!jfem) {
throw new Error(
`Failed to setup the JupyterFrontEnd in the new kernel with traceback=${result.content.traceback}`
`Failed to setup the JupyterFrontEnd in the kernel ${kernel.id}!
traceback=${result.content.traceback}`
);
}
return Private.jupyterFrontEndModels.get(kernelId);
return jfem;
}

static serializers: ISerializers = {
Expand Down
9 changes: 6 additions & 3 deletions src/widgets/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export async function newSession({
specsManager: IpylabModel.app.serviceManager.kernelspecs,
path: path,
name: name ?? path,
type: 'notebook',
type: 'ipylab',
kernelPreference: {
id: kernelId || `${UUID.uuid4()}`,
language: language
Expand All @@ -46,7 +46,10 @@ export async function newSession({
const session = sessionContext.session;
const context = {};
(context as any)['sessionContext'] = sessionContext;
(context as any)['saveState'] = new Signal(null);
(context as any)['saveState'] = new Signal({});
(context as any).saveState.connect(() => {
null;
});
registerWidgetManager(context as any, rendermime, [] as any);
if (code) {
const future = session.kernel.requestExecute(
Expand Down Expand Up @@ -140,7 +143,7 @@ export async function injectCode({
*/
export function getNestedObject(base: object, path: string): any {
let obj: object = base;
let path_: string = '';
let path_ = '';
const parts = path.split('.');
let attr = '';
for (let i = 0; i < parts.length; i++) {
Expand Down
2 changes: 0 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4877,10 +4877,8 @@ __metadata:
"@jupyterlab/launcher": ^4.1.0
"@jupyterlab/observables": ^5.1.0
"@jupyterlab/rendermime": ^4.1.0
"@lumino/algorithm": ^2.0.1
"@lumino/commands": ^2.2.0
"@lumino/disposable": ^2.1.2
"@lumino/messaging": ^2.0.1
"@lumino/widgets": ^2.3.1
"@types/expect.js": ^0.3.29
"@types/json-schema": ^7.0.11
Expand Down

0 comments on commit 8ea26ff

Please sign in to comment.