Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register all kernels in one plugin #107

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Changes from all 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
81 changes: 49 additions & 32 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,56 @@ import { IKernel, IKernelSpecs } from '@jupyterlite/kernel';

import { WebWorkerKernel } from './web_worker_kernel';

function getJson(url: string) {
const json_url = URLExt.join(PageConfig.getBaseUrl(), url);
const xhr = new XMLHttpRequest();
xhr.open('GET', json_url, false);
xhr.send(null);
return JSON.parse(xhr.responseText);
}
/**
* Fetches JSON data from the specified URL asynchronously.
*
* This function constructs the full URL using the base URL from the PageConfig and
* the provided relative URL. It then performs a GET request using the Fetch API
* and returns the parsed JSON data.
*
* @param {string} url - The relative URL to fetch the JSON data from.
* @returns {Promise<any>} - A promise that resolves to the parsed JSON data.
* @throws {Error} - Throws an error if the HTTP request fails.
*
*/
async function getJson(url: string) {
const jsonUrl = URLExt.join(PageConfig.getBaseUrl(), url);
const response = await fetch(jsonUrl, { method: 'GET' });

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

let kernel_list: string[] = [];
try {
kernel_list = getJson('xeus/kernels.json');
} catch (err) {
console.log(`Could not fetch xeus/kernels.json: ${err}`);
throw err;
const data = await response.json();
return data;
}

const plugins = kernel_list.map((kernel): JupyterLiteServerPlugin<void> => {
return {
id: `@jupyterlite/xeus-${kernel}:register`,
autoStart: true,
requires: [IKernelSpecs],
optional: [IServiceWorkerManager, IBroadcastChannelWrapper],
activate: (
app: JupyterLiteServer,
kernelspecs: IKernelSpecs,
serviceWorker?: IServiceWorkerManager,
broadcastChannel?: IBroadcastChannelWrapper
) => {
const kernelPlugin: JupyterLiteServerPlugin<void> = {
id: '@jupyterlite/xeus-kernel:register',
Copy link
Member

Choose a reason for hiding this comment

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

Looks like having a single plugin would prevent disabling some kernels via disabledExtensions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can keep the current behavior by checking for the PageConfig.disabledExtensions value in the activation function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason we need synchronous XHR is to generate JupyterLab plugins dynamically from the fetch data. Which I do not feel is necessary since these plugins do not provide any token. If it's just about to disable some kernels later, we can have other mechanisms

Copy link
Member

Choose a reason for hiding this comment

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

Right, it would be great to remove this synchronous XHR.

Copy link
Member

Choose a reason for hiding this comment

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

Do we really need the ability to disable kernels?

If users don't want a kernel in the UI, their solution is to not install it in the provided environment.yml file.

autoStart: true,
requires: [IKernelSpecs],
optional: [IServiceWorkerManager, IBroadcastChannelWrapper],
activate: async (
app: JupyterLiteServer,
kernelspecs: IKernelSpecs,
serviceWorker?: IServiceWorkerManager,
broadcastChannel?: IBroadcastChannelWrapper
) => {
// Fetch kernel list
let kernelList: string[] = [];
try {
kernelList = await getJson('xeus/kernels.json');
} catch (err) {
console.log(`Could not fetch xeus/kernels.json: ${err}`);
throw err;
}
const contentsManager = app.serviceManager.contents;

for (const kernel of kernelList) {
// Fetch kernel spec
const kernelspec = getJson('xeus/kernels/' + kernel + '/kernel.json');
const kernelspec = await getJson(
'xeus/kernels/' + kernel + '/kernel.json'
);
kernelspec.name = kernel;
kernelspec.dir = kernel;
for (const [key, value] of Object.entries(kernelspec.resources)) {
Expand All @@ -51,9 +71,6 @@ const plugins = kernel_list.map((kernel): JupyterLiteServerPlugin<void> => {
value as string
);
}

const contentsManager = app.serviceManager.contents;

kernelspecs.register({
spec: kernelspec,
create: async (options: IKernel.IOptions): Promise<IKernel> => {
Expand Down Expand Up @@ -81,7 +98,7 @@ const plugins = kernel_list.map((kernel): JupyterLiteServerPlugin<void> => {
}
});
}
};
});
}
};

export default plugins;
export default kernelPlugin;
Loading