Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions jupyter_collaboration/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ class YDocExtension(ExtensionApp):
directory.""",
)

server_side_execution = Bool(
False,
config=True,
help="""Whether to execute notebooks in the server using the REST API, not using the kernel
protocol over WebSocket. The frontend only interacts with the notebook through its shared
model.""",
)

def initialize(self):
super().initialize()
self.serverapp.event_logger.register_event_schema(EVENTS_SCHEMA_PATH)
Expand Down
27 changes: 14 additions & 13 deletions packages/collaboration-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,20 @@
"@jupyter/collaboration": "^2.0.11",
"@jupyter/docprovider": "^2.0.11",
"@jupyter/ydoc": "^1.1.0-a0",
"@jupyterlab/application": "^4.0.5",
"@jupyterlab/apputils": "^4.0.5",
"@jupyterlab/codemirror": "^4.0.5",
"@jupyterlab/application": "^4.2.0-beta.0",
"@jupyterlab/apputils": "^4.2.0-beta.0",
"@jupyterlab/codemirror": "^4.2.0-beta.0",
"@jupyterlab/coreutils": "^6.0.5",
"@jupyterlab/docregistry": "^4.0.5",
"@jupyterlab/filebrowser": "^4.0.5",
"@jupyterlab/fileeditor": "^4.0.5",
"@jupyterlab/logconsole": "^4.0.5",
"@jupyterlab/notebook": "^4.0.5",
"@jupyterlab/docregistry": "^4.2.0-beta.0",
"@jupyterlab/filebrowser": "^4.2.0-beta.0",
"@jupyterlab/fileeditor": "^4.2.0-beta.0",
"@jupyterlab/logconsole": "^4.2.0-beta.0",
"@jupyterlab/notebook": "^4.2.0-beta.0",
"@jupyterlab/services": "^7.0.5",
"@jupyterlab/settingregistry": "^4.0.5",
"@jupyterlab/statedb": "^4.0.5",
"@jupyterlab/translation": "^4.0.5",
"@jupyterlab/ui-components": "^4.0.5",
"@jupyterlab/settingregistry": "^4.2.0-beta.0",
"@jupyterlab/statedb": "^4.2.0-beta.0",
"@jupyterlab/translation": "^4.2.0-beta.0",
"@jupyterlab/ui-components": "^4.2.0-beta.0",
"@lumino/commands": "^2.1.0",
"@lumino/widgets": "^2.1.0",
"y-protocols": "^1.0.5",
Expand Down Expand Up @@ -97,7 +97,8 @@
"schemaDir": "./schema",
"outputDir": "../../jupyter_collaboration/labextension",
"disabledExtensions": [
"@jupyterlab/filebrowser-extension:defaultFileBrowser"
"@jupyterlab/filebrowser-extension:defaultFileBrowser",
"@jupyterlab/notebook-extension:cell-executor"
],
"sharedPackages": {
"@codemirror/state": {
Expand Down
64 changes: 63 additions & 1 deletion packages/collaboration-extension/src/collaboration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import {
EditorExtensionRegistry,
IEditorExtensionRegistry
} from '@jupyterlab/codemirror';
import { type MarkdownCell } from '@jupyterlab/cells';
import { INotebookCellExecutor, runCell } from '@jupyterlab/notebook';
import { WebSocketAwarenessProvider } from '@jupyter/docprovider';
import { SidePanel, usersIcon } from '@jupyterlab/ui-components';
import { URLExt } from '@jupyterlab/coreutils';
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
import { ServerConnection } from '@jupyterlab/services';
import { IStateDB, StateDB } from '@jupyterlab/statedb';
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
Expand Down Expand Up @@ -189,3 +191,63 @@ export const userEditorCursors: JupyterFrontEndPlugin<void> = {
});
}
};

export const notebookCellExecutor: JupyterFrontEndPlugin<INotebookCellExecutor> =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to consider: do we want this plugin in a separate package in the future so that when we split frontend and backend (#269) we can still load this plugin but not the others? This question does not block merging this PR in any way.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But does it make sense to have server-side execution without collaboration? The former is based on the latter, so in my opinion they go together.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be sufficient to have the collaborative drive, right?

{
id: '@jupyter/collaboration-extension:notebook-cell-executor',
description:
'Add notebook cell executor that uses REST API instead of kernel protocol over WebSocket.',
autoStart: true,
provides: INotebookCellExecutor,
activate: (app: JupyterFrontEnd): INotebookCellExecutor => {
if (PageConfig.getOption('serverSideExecution') === 'true') {
return Object.freeze({ runCell: runCellServerSide });
}
return Object.freeze({ runCell });
}
};

async function runCellServerSide({
cell,
notebook,
notebookConfig,
onCellExecuted,
onCellExecutionScheduled,
sessionContext,
sessionDialogs,
translator
}: INotebookCellExecutor.IRunCellOptions): Promise<boolean> {
switch (cell.model.type) {
case 'markdown':
(cell as MarkdownCell).rendered = true;
cell.inputHidden = false;
onCellExecuted({ cell, success: true });
break;
case 'code': {
const kernelId = sessionContext?.session?.kernel?.id;
const settings = ServerConnection.makeSettings();
const apiURL = URLExt.join(
settings.baseUrl,
`api/kernels/${kernelId}/execute`
);
const cellId = cell.model.sharedModel.getId();
const documentId = `json:notebook:${notebook.sharedModel.getState(
'file_id'
)}`;
const body = `{"cell_id":"${cellId}","document_id":"${documentId}"}`;
const init = {
method: 'POST',
body
};
try {
await ServerConnection.makeRequest(apiURL, init, settings);
} catch (error: any) {
throw new ServerConnection.NetworkError(error);
}
break;
}
default:
break;
}
return Promise.resolve(true);
}
6 changes: 4 additions & 2 deletions packages/collaboration-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import {
menuBarPlugin,
rtcGlobalAwarenessPlugin,
rtcPanelPlugin,
userEditorCursors
userEditorCursors,
notebookCellExecutor
} from './collaboration';
import { sharedLink } from './sharedlink';

Expand All @@ -37,7 +38,8 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
rtcGlobalAwarenessPlugin,
rtcPanelPlugin,
sharedLink,
userEditorCursors
userEditorCursors,
notebookCellExecutor
];

export default plugins;
4 changes: 4 additions & 0 deletions packages/docprovider/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ const jestJupyterLab = require('@jupyterlab/testing/lib/jest-config');

const esModules = [
'@codemirror',
'@microsoft',
'exenv-es6',
'@jupyter/ydoc',
'@jupyter/react-components',
'@jupyter/web-components',
'@jupyterlab/',
'lib0',
'nanoid',
Expand Down
Loading