jupyterpack 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/lib/document/commands.d.ts +8 -0
  2. package/lib/document/commands.js +76 -0
  3. package/lib/document/iframePanel.d.ts +4 -1
  4. package/lib/document/plugin.d.ts +2 -1
  5. package/lib/document/plugin.js +22 -4
  6. package/lib/document/toolbar.d.ts +9 -0
  7. package/lib/document/toolbar.js +20 -0
  8. package/lib/document/widgetFactory.d.ts +2 -1
  9. package/lib/document/widgetFactory.js +11 -5
  10. package/lib/index.d.ts +1 -1
  11. package/lib/pythonServer/dash/dashServer.d.ts +4 -6
  12. package/lib/pythonServer/dash/dashServer.js +18 -10
  13. package/lib/pythonServer/kernelExecutor.d.ts +5 -0
  14. package/lib/pythonServer/kernelExecutor.js +13 -6
  15. package/lib/pythonServer/streamlit/streamlitServer.d.ts +7 -26
  16. package/lib/pythonServer/streamlit/streamlitServer.js +32 -36
  17. package/lib/pythonServer/tornado/tornadoServer.d.ts +5 -3
  18. package/lib/pythonServer/tornado/tornadoServer.js +31 -14
  19. package/lib/pythonWidget/comm.d.ts +11 -0
  20. package/lib/pythonWidget/comm.js +52 -0
  21. package/lib/pythonWidget/pythonWidget.d.ts +5 -0
  22. package/lib/pythonWidget/pythonWidget.js +19 -0
  23. package/lib/pythonWidget/pythonWidgetModel.d.ts +16 -4
  24. package/lib/pythonWidget/pythonWidgetModel.js +77 -13
  25. package/lib/sandpackWidget/sandpackFilesModel.d.ts +6 -2
  26. package/lib/sandpackWidget/sandpackFilesModel.js +13 -2
  27. package/lib/sandpackWidget/sandpackPanel.d.ts +10 -1
  28. package/lib/sandpackWidget/sandpackPanel.js +38 -3
  29. package/lib/token.d.ts +2 -1
  30. package/lib/token.js +1 -0
  31. package/lib/tools.d.ts +5 -0
  32. package/lib/tools.js +17 -0
  33. package/lib/type.d.ts +27 -1
  34. package/package.json +6 -6
  35. package/src/document/commands.ts +91 -0
  36. package/src/document/iframePanel.ts +4 -1
  37. package/src/document/plugin.ts +28 -7
  38. package/src/document/toolbar.ts +39 -0
  39. package/src/document/widgetFactory.ts +13 -5
  40. package/src/global.d.ts +5 -0
  41. package/src/pythonServer/dash/dashServer.ts +23 -14
  42. package/src/pythonServer/kernelExecutor.ts +21 -7
  43. package/src/pythonServer/streamlit/streamlitServer.ts +41 -61
  44. package/src/pythonServer/tornado/tornadoServer.ts +35 -18
  45. package/src/pythonWidget/comm.ts +65 -0
  46. package/src/pythonWidget/pythonWidget.ts +19 -1
  47. package/src/pythonWidget/pythonWidgetModel.ts +105 -18
  48. package/src/sandpackWidget/sandpackFilesModel.ts +17 -3
  49. package/src/sandpackWidget/sandpackPanel.ts +45 -4
  50. package/src/token.ts +5 -1
  51. package/src/tools.ts +22 -0
  52. package/src/type.ts +29 -1
  53. package/style/base.css +7 -0
  54. package/style/icons/autoreload.svg +16 -0
  55. package/style/icons/box.svg +12 -0
  56. package/style/icons/externallink.svg +10 -0
  57. package/lib/pythonServer/common/generatedPythonFiles.d.ts +0 -2
  58. package/lib/pythonServer/common/generatedPythonFiles.js +0 -72
  59. package/lib/pythonServer/dash/generatedPythonFiles.d.ts +0 -2
  60. package/lib/pythonServer/dash/generatedPythonFiles.js +0 -31
  61. package/lib/pythonServer/streamlit/generatedPythonFiles.d.ts +0 -2
  62. package/lib/pythonServer/streamlit/generatedPythonFiles.js +0 -147
  63. package/lib/pythonServer/tornado/generatedPythonFiles.d.ts +0 -3
  64. package/lib/pythonServer/tornado/generatedPythonFiles.js +0 -456
  65. package/src/pythonServer/common/generatedPythonFiles.ts +0 -73
  66. package/src/pythonServer/dash/generatedPythonFiles.ts +0 -32
  67. package/src/pythonServer/streamlit/generatedPythonFiles.ts +0 -148
  68. package/src/pythonServer/tornado/generatedPythonFiles.ts +0 -457
@@ -0,0 +1,8 @@
1
+ import { CommandRegistry } from '@lumino/commands';
2
+ import { IJupyterpackDocTracker } from '../type';
3
+ export declare const CommandIDs: {
4
+ RELOAD: string;
5
+ TOGGLE_AUTORELOAD: string;
6
+ OPEN_SPECTA: string;
7
+ };
8
+ export declare function addCommands(commands: CommandRegistry, tracker: IJupyterpackDocTracker): void;
@@ -0,0 +1,76 @@
1
+ import { refreshIcon } from '@jupyterlab/ui-components';
2
+ import { autoReloadIcon, linkIcon } from '../tools';
3
+ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
4
+ export const CommandIDs = {
5
+ RELOAD: 'jupyterpack:reload',
6
+ TOGGLE_AUTORELOAD: 'jupyterpack:toggleAutoreload',
7
+ OPEN_SPECTA: 'jupyterpack:openInSpecta'
8
+ };
9
+ const labBaseUrl = PageConfig.getOption('baseUrl');
10
+ function getCurrentIframPanel(tracker) {
11
+ var _a;
12
+ const current = (_a = tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.content;
13
+ if (!current) {
14
+ return;
15
+ }
16
+ const widget = current.widgets[0];
17
+ if (!widget) {
18
+ return;
19
+ }
20
+ return widget;
21
+ }
22
+ export function addCommands(commands, tracker) {
23
+ commands.addCommand(CommandIDs.RELOAD, {
24
+ caption: 'Reload',
25
+ isEnabled: () => {
26
+ return tracker.currentWidget !== null;
27
+ },
28
+ icon: refreshIcon,
29
+ execute: async () => {
30
+ const widget = getCurrentIframPanel(tracker);
31
+ if (widget) {
32
+ await widget.reload();
33
+ }
34
+ }
35
+ });
36
+ const commandState = { toggled: false };
37
+ commands.addCommand(CommandIDs.TOGGLE_AUTORELOAD, {
38
+ isEnabled: () => {
39
+ return tracker.currentWidget !== null;
40
+ },
41
+ isToggled: () => {
42
+ const widget = getCurrentIframPanel(tracker);
43
+ return Boolean(widget === null || widget === void 0 ? void 0 : widget.autoreload);
44
+ },
45
+ icon: autoReloadIcon,
46
+ caption: e => {
47
+ return commandState.toggled
48
+ ? 'Auto-reload enabled'
49
+ : 'Auto-reload disabled';
50
+ },
51
+ execute: async () => {
52
+ const widget = getCurrentIframPanel(tracker);
53
+ if (widget) {
54
+ widget.autoreload = !(widget === null || widget === void 0 ? void 0 : widget.autoreload);
55
+ commands.notifyCommandChanged(CommandIDs.TOGGLE_AUTORELOAD);
56
+ }
57
+ }
58
+ });
59
+ commands.addCommand(CommandIDs.OPEN_SPECTA, {
60
+ caption: 'Open in Specta',
61
+ isEnabled: () => {
62
+ return tracker.currentWidget !== null;
63
+ },
64
+ icon: linkIcon,
65
+ execute: async () => {
66
+ var _a;
67
+ const context = (_a = tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.context;
68
+ if (!context) {
69
+ return;
70
+ }
71
+ const spectaUrl = new URL(URLExt.join(labBaseUrl, 'specta'), window.location.origin);
72
+ spectaUrl.searchParams.set('path', context.path);
73
+ window.open(spectaUrl.toString(), '_blank');
74
+ }
75
+ });
76
+ }
@@ -1,7 +1,10 @@
1
1
  import { Widget } from '@lumino/widgets';
2
- export declare class IFramePanel extends Widget {
2
+ export declare abstract class IFramePanel extends Widget {
3
3
  constructor();
4
4
  toggleSpinner(show: boolean): void;
5
+ abstract reload(): Promise<void>;
6
+ abstract autoreload: boolean;
7
+ abstract isReady: Promise<void>;
5
8
  protected _iframe: HTMLIFrameElement;
6
9
  protected _spinner: HTMLDivElement;
7
10
  }
@@ -1,2 +1,3 @@
1
1
  import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
- export declare const spkPlugin: JupyterFrontEndPlugin<void>;
2
+ import { IJupyterpackDocTracker } from '../type';
3
+ export declare const spkPlugin: JupyterFrontEndPlugin<IJupyterpackDocTracker>;
@@ -1,12 +1,20 @@
1
1
  import { JupyterPackWidgetFactory } from './widgetFactory';
2
- import { IConnectionManagerToken } from '../token';
2
+ import { IConnectionManagerToken, IJupyterpackDocTrackerToken } from '../token';
3
+ import { WidgetTracker } from '@jupyterlab/apputils';
4
+ import { logoIcon } from '../tools';
5
+ import { addCommands } from './commands';
3
6
  const FACTORY = 'jupyterpack';
4
7
  const CONTENT_TYPE = 'jupyterpack';
5
8
  export const spkPlugin = {
6
9
  id: 'jupyterpack:spkplugin',
7
10
  requires: [IConnectionManagerToken],
8
11
  autoStart: true,
12
+ provides: IJupyterpackDocTrackerToken,
9
13
  activate: (app, connectionManager) => {
14
+ const tracker = new WidgetTracker({
15
+ namespace: FACTORY
16
+ });
17
+ addCommands(app.commands, tracker);
10
18
  const widgetFactory = new JupyterPackWidgetFactory({
11
19
  name: FACTORY,
12
20
  modelName: 'text',
@@ -14,7 +22,8 @@ export const spkPlugin = {
14
22
  defaultFor: [CONTENT_TYPE],
15
23
  commands: app.commands,
16
24
  manager: app.serviceManager,
17
- connectionManager
25
+ connectionManager,
26
+ tracker
18
27
  });
19
28
  // Registering the widget factory
20
29
  app.docRegistry.addWidgetFactory(widgetFactory);
@@ -22,10 +31,19 @@ export const spkPlugin = {
22
31
  app.docRegistry.addFileType({
23
32
  name: CONTENT_TYPE,
24
33
  displayName: 'SPK',
25
- mimeTypes: ['text/json'],
34
+ mimeTypes: ['application/json'],
26
35
  extensions: ['.spk', '.SPK'],
27
36
  fileFormat: 'json',
28
- contentType: CONTENT_TYPE
37
+ contentType: CONTENT_TYPE,
38
+ icon: logoIcon
39
+ });
40
+ widgetFactory.widgetCreated.connect((_, widget) => {
41
+ widget.title.icon = logoIcon;
42
+ widget.context.pathChanged.connect(() => {
43
+ tracker.save(widget);
44
+ });
45
+ tracker.add(widget);
29
46
  });
47
+ return tracker;
30
48
  }
31
49
  };
@@ -0,0 +1,9 @@
1
+ import { ReactiveToolbar } from '@jupyterlab/ui-components';
2
+ import { CommandRegistry } from '@lumino/commands';
3
+ import { IJupyterpackDocTracker } from '../type';
4
+ export declare class ToolbarWidget extends ReactiveToolbar {
5
+ constructor(options: {
6
+ tracker: IJupyterpackDocTracker;
7
+ commands: CommandRegistry;
8
+ });
9
+ }
@@ -0,0 +1,20 @@
1
+ import { CommandToolbarButton, ReactiveToolbar } from '@jupyterlab/ui-components';
2
+ import { CommandIDs } from './commands';
3
+ export class ToolbarWidget extends ReactiveToolbar {
4
+ constructor(options) {
5
+ super();
6
+ this.addClass('jupyterpack-toolbar');
7
+ this.addItem('Reload', new CommandToolbarButton({
8
+ commands: options.commands,
9
+ id: CommandIDs.RELOAD
10
+ }));
11
+ this.addItem('Toggle Auto Reload', new CommandToolbarButton({
12
+ id: CommandIDs.TOGGLE_AUTORELOAD,
13
+ commands: options.commands
14
+ }));
15
+ this.addItem('Open Specta', new CommandToolbarButton({
16
+ id: CommandIDs.OPEN_SPECTA,
17
+ commands: options.commands
18
+ }));
19
+ }
20
+ }
@@ -1,12 +1,13 @@
1
1
  import { ABCWidgetFactory, DocumentRegistry } from '@jupyterlab/docregistry';
2
2
  import { ServiceManager } from '@jupyterlab/services';
3
3
  import { CommandRegistry } from '@lumino/commands';
4
- import { IConnectionManager } from '../type';
4
+ import { IConnectionManager, IJupyterpackDocTracker } from '../type';
5
5
  import { JupyterPackDocWidget } from './jupyterpackDocWidget';
6
6
  interface IOptions extends DocumentRegistry.IWidgetFactoryOptions {
7
7
  commands: CommandRegistry;
8
8
  manager: ServiceManager.IManager;
9
9
  connectionManager: IConnectionManager;
10
+ tracker: IJupyterpackDocTracker;
10
11
  }
11
12
  export declare class JupyterPackWidgetFactory extends ABCWidgetFactory<JupyterPackDocWidget> {
12
13
  private options;
@@ -1,11 +1,12 @@
1
1
  import { ABCWidgetFactory } from '@jupyterlab/docregistry';
2
+ import { UUID } from '@lumino/coreutils';
2
3
  import { Panel } from '@lumino/widgets';
3
- import { JupyterPackFramework } from '../type';
4
+ import { PythonWidget } from '../pythonWidget/pythonWidget';
5
+ import { PythonWidgetModel } from '../pythonWidget/pythonWidgetModel';
4
6
  import { SandpackPanel } from '../sandpackWidget/sandpackPanel';
7
+ import { JupyterPackFramework } from '../type';
5
8
  import { JupyterPackDocWidget } from './jupyterpackDocWidget';
6
- import { PythonWidgetModel } from '../pythonWidget/pythonWidgetModel';
7
- import { UUID } from '@lumino/coreutils';
8
- import { PythonWidget } from '../pythonWidget/pythonWidget';
9
+ import { ToolbarWidget } from './toolbar';
9
10
  export class JupyterPackWidgetFactory extends ABCWidgetFactory {
10
11
  constructor(options) {
11
12
  super(options);
@@ -55,9 +56,14 @@ export class JupyterPackWidgetFactory extends ABCWidgetFactory {
55
56
  }
56
57
  }
57
58
  });
59
+ const toolbar = new ToolbarWidget({
60
+ tracker: this.options.tracker,
61
+ commands: this.options.commands
62
+ });
58
63
  return new JupyterPackDocWidget({
59
64
  context,
60
- content
65
+ content,
66
+ toolbar
61
67
  });
62
68
  }
63
69
  }
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- declare const _default: (import("@jupyterlab/application").JupyterFrontEndPlugin<void> | import("@jupyterlab/application").JupyterFrontEndPlugin<import("./type").IConnectionManager>)[];
1
+ declare const _default: (import("@jupyterlab/application").JupyterFrontEndPlugin<import("./type").IJupyterpackDocTracker> | import("@jupyterlab/application").JupyterFrontEndPlugin<import("./type").IConnectionManager>)[];
2
2
  export default _default;
@@ -14,11 +14,9 @@ export declare class DashServer extends KernelExecutor {
14
14
  content?: string;
15
15
  }): string;
16
16
  disposePythonServer(): Promise<void>;
17
- openWebsocket(options: {
18
- instanceId: string;
19
- kernelId: string;
20
- wsUrl: string;
21
- protocol?: string;
17
+ reloadPythonServer(options: {
18
+ entryPath?: string;
19
+ initCode?: string;
22
20
  }): Promise<void>;
23
- private DASH_GET_RESPONSE_FUNCTION;
21
+ private _DASH_SERVER_VAR;
24
22
  }
@@ -1,12 +1,10 @@
1
1
  import { stringOrNone } from '../../tools';
2
2
  import { JupyterPackFramework } from '../../type';
3
- import { patch } from '../common/generatedPythonFiles';
4
3
  import { KernelExecutor } from '../kernelExecutor';
5
- import { bootstrap, dashLoader } from './generatedPythonFiles';
6
4
  export class DashServer extends KernelExecutor {
7
5
  constructor() {
8
6
  super(...arguments);
9
- this.DASH_GET_RESPONSE_FUNCTION = '__jupyterpack_dash_get_response';
7
+ this._DASH_SERVER_VAR = '__jupyterpack_dash_server';
10
8
  }
11
9
  async init(options) {
12
10
  await super.init(options);
@@ -16,24 +14,34 @@ export class DashServer extends KernelExecutor {
16
14
  kernelClientId,
17
15
  framework: JupyterPackFramework.DASH
18
16
  });
19
- await this.executeCode({ code: patch });
20
17
  await this.executeCode({
21
- code: bootstrap.replaceAll('{{base_url}}', baseURL)
18
+ code: `
19
+ import os
20
+ os.environ["DASH_URL_BASE_PATHNAME"] = "${baseURL}"
21
+ `
22
22
  });
23
23
  if (initCode) {
24
24
  await this.executeCode({ code: initCode });
25
25
  }
26
- await this.executeCode({ code: dashLoader });
26
+ const loaderCode = `
27
+ from jupyterpack.dash import DashServer
28
+ ${this._DASH_SERVER_VAR} = DashServer(app, "${baseURL}")
29
+ `;
30
+ await this.executeCode({ code: loaderCode });
27
31
  }
28
32
  getResponseFunctionFactory(options) {
29
33
  const { method, urlPath, headers, params, content } = options;
30
- const code = `${this.DASH_GET_RESPONSE_FUNCTION}("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
34
+ const code = `${this._DASH_SERVER_VAR}.get_response("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
31
35
  return code;
32
36
  }
33
37
  async disposePythonServer() {
34
- //no-op
38
+ await this.executeCode({ code: `${this._DASH_SERVER_VAR}.dispose()` });
35
39
  }
36
- async openWebsocket(options) {
37
- //no-op
40
+ async reloadPythonServer(options) {
41
+ const { initCode } = options;
42
+ if (initCode) {
43
+ await this.executeCode({ code: initCode });
44
+ }
45
+ await this.executeCode({ code: `${this._DASH_SERVER_VAR}.reload(app)` }, true);
38
46
  }
39
47
  }
@@ -4,6 +4,10 @@ export declare abstract class KernelExecutor implements IKernelExecutor {
4
4
  constructor(options: KernelExecutor.IOptions);
5
5
  get isDisposed(): boolean;
6
6
  abstract disposePythonServer(): Promise<void>;
7
+ abstract reloadPythonServer(options: {
8
+ entryPath?: string;
9
+ initCode?: string;
10
+ }): Promise<void>;
7
11
  abstract getResponseFunctionFactory(options: {
8
12
  urlPath: string;
9
13
  method: string;
@@ -55,6 +59,7 @@ export declare abstract class KernelExecutor implements IKernelExecutor {
55
59
  kernelClientId: string;
56
60
  framework: JupyterPackFramework;
57
61
  }): string;
62
+ protected _baseUrl: string | undefined;
58
63
  private _isDisposed;
59
64
  private _sessionConnection;
60
65
  private _wsPatch;
@@ -2,7 +2,6 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
2
2
  import stripAnsi from 'strip-ansi';
3
3
  import { arrayBufferToBase64, base64ToArrayBuffer, base64ToString, isBinaryContentType } from '../tools';
4
4
  import websocketPatch from '../websocket/websocket.js?raw';
5
- import { patch } from './common/generatedPythonFiles';
6
5
  export class KernelExecutor {
7
6
  constructor(options) {
8
7
  this._isDisposed = false;
@@ -13,7 +12,11 @@ export class KernelExecutor {
13
12
  return this._isDisposed;
14
13
  }
15
14
  async init(options) {
16
- await this.executeCode({ code: patch });
15
+ const patchCode = `
16
+ from jupyterpack.common import patch_all
17
+ patch_all()
18
+ `;
19
+ await this.executeCode({ code: patchCode });
17
20
  }
18
21
  openWebsocketFunctionFactory(options) {
19
22
  return undefined;
@@ -92,11 +95,14 @@ export class KernelExecutor {
92
95
  }
93
96
  case 'stream': {
94
97
  const content = msg.content;
98
+ if (content.text.length === 0) {
99
+ break;
100
+ }
95
101
  if (content.name === 'stderr') {
96
- console.error('Kernel stream', content.text);
102
+ console.error('Kernel stream:', content.text);
97
103
  }
98
104
  else {
99
- console.log('Kernel stream', content.text);
105
+ console.log('Kernel stream:', content.text);
100
106
  }
101
107
  break;
102
108
  }
@@ -126,8 +132,9 @@ export class KernelExecutor {
126
132
  }
127
133
  buildBaseURL(options) {
128
134
  const { instanceId, kernelClientId, framework } = options;
129
- const labBaseUrl = PageConfig.getOption('baseUrl');
130
- const baseURL = URLExt.join(labBaseUrl, 'extensions/jupyterpack/static', instanceId, framework, kernelClientId, '/');
135
+ const fullLabextensionsUrl = PageConfig.getOption('fullLabextensionsUrl');
136
+ const baseURL = URLExt.join(fullLabextensionsUrl, 'jupyterpack/static', instanceId, framework, kernelClientId, '/');
137
+ this._baseUrl = baseURL;
131
138
  return baseURL;
132
139
  }
133
140
  }
@@ -1,33 +1,14 @@
1
- import { IDict } from '../../type';
2
- import { KernelExecutor } from '../kernelExecutor';
3
- export declare class StreamlitServer extends KernelExecutor {
1
+ import { TornadoServer } from '../tornado/tornadoServer';
2
+ export declare class StreamlitServer extends TornadoServer {
4
3
  init(options: {
5
4
  entryPath?: string;
6
5
  initCode?: string;
7
6
  instanceId: string;
8
7
  kernelClientId: string;
9
8
  }): Promise<void>;
10
- getResponseFunctionFactory(options: {
11
- urlPath: string;
12
- method: string;
13
- headers: IDict;
14
- params?: string;
15
- content?: string;
16
- }): string;
17
- openWebsocketFunctionFactory(options: {
18
- instanceId: string;
19
- kernelId: string;
20
- wsUrl: string;
21
- protocol?: string;
22
- }): string;
23
- sendWebsocketMessageFunctionFactory(options: {
24
- instanceId: string;
25
- kernelId: string;
26
- wsUrl: string;
27
- message: string;
28
- }): string;
29
- disposePythonServer(): Promise<void>;
30
- private _GET_RESPONSE_FUNCTION;
31
- private _OPEN_WEBSOCKET_FUNCTION;
32
- private _SEND_WEBSOCKET_FUNCTION;
9
+ reloadPythonServer(options: {
10
+ entryPath?: string;
11
+ initCode?: string;
12
+ }): Promise<void>;
13
+ protected _SERVER_VAR: string;
33
14
  }
@@ -1,18 +1,11 @@
1
- import { stringOrNone } from '../../tools';
2
1
  import { JupyterPackFramework } from '../../type';
3
- import { patch, tools } from '../common/generatedPythonFiles';
4
- import { KernelExecutor } from '../kernelExecutor';
5
- import { bootstrap as tornadoBootstrap, tornadoBridge } from '../tornado/generatedPythonFiles';
6
- import { bootstrap, streamlitLoader } from './generatedPythonFiles';
7
- export class StreamlitServer extends KernelExecutor {
2
+ import { TornadoServer } from '../tornado/tornadoServer';
3
+ export class StreamlitServer extends TornadoServer {
8
4
  constructor() {
9
5
  super(...arguments);
10
- this._GET_RESPONSE_FUNCTION = '__jupyterpack_streamlit_get_response';
11
- this._OPEN_WEBSOCKET_FUNCTION = '__jupyterpack_streamlit_open_ws';
12
- this._SEND_WEBSOCKET_FUNCTION = '__jupyterpack_streamlit_receive_ws_message';
6
+ this._SERVER_VAR = '__jupyterpack_streamlit_server';
13
7
  }
14
8
  async init(options) {
15
- await super.init(options);
16
9
  const { instanceId, kernelClientId, entryPath } = options;
17
10
  if (!entryPath) {
18
11
  throw new Error('Missing streamlit entry path, please check your SPK file');
@@ -22,34 +15,37 @@ export class StreamlitServer extends KernelExecutor {
22
15
  kernelClientId,
23
16
  framework: JupyterPackFramework.STREAMLIT
24
17
  });
25
- await this.executeCode({ code: patch });
26
- await this.executeCode({ code: tools.replaceAll('{{base_url}}', baseURL) });
27
- await this.executeCode({ code: tornadoBootstrap });
28
- await this.executeCode({ code: tornadoBridge });
29
- await this.executeCode({ code: bootstrap });
30
- const stCode = streamlitLoader
31
- .replaceAll('{{base_url}}', baseURL)
32
- .replaceAll('{{script_path}}', entryPath);
18
+ const patchCode = `
19
+ from jupyterpack.common import set_base_url_env, patch_tornado, patch_all
20
+ patch_all()
21
+ patch_tornado()
22
+ set_base_url_env("${baseURL}")
23
+ `;
24
+ await this.executeCode({ code: patchCode });
25
+ const bootstrapCode = `
26
+ from jupyterpack.streamlit import patch_streamlit
27
+ patch_streamlit()
28
+ `;
29
+ await this.executeCode({ code: bootstrapCode });
30
+ const stCode = `
31
+ from jupyterpack.streamlit import StreamlitServer, create_streamlit_app
32
+ __jupyterpack_st_server, __jupyterpack_tor_app = await create_streamlit_app("${entryPath}", "${baseURL}")
33
+ ${this._SERVER_VAR} = StreamlitServer(__jupyterpack_tor_app, "${baseURL}", __jupyterpack_st_server)
34
+ `;
33
35
  await this.executeCode({ code: stCode });
34
36
  }
35
- getResponseFunctionFactory(options) {
36
- const { method, urlPath, headers, params, content } = options;
37
- const code = `await ${this._GET_RESPONSE_FUNCTION}("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
38
- return code;
39
- }
40
- openWebsocketFunctionFactory(options) {
41
- const { instanceId, kernelId, wsUrl, protocol } = options;
42
- const code = `await ${this._OPEN_WEBSOCKET_FUNCTION}("${instanceId}", "${kernelId}", "${wsUrl}", ${stringOrNone(protocol)})`;
43
- return code;
44
- }
45
- sendWebsocketMessageFunctionFactory(options) {
46
- const { instanceId, kernelId, wsUrl, message } = options;
47
- const code = `await ${this._SEND_WEBSOCKET_FUNCTION}("${instanceId}", "${kernelId}", "${wsUrl}", '''${message}''')`;
48
- return code;
49
- }
50
- async disposePythonServer() {
37
+ async reloadPythonServer(options) {
38
+ const { entryPath } = options;
39
+ if (!entryPath || !this._baseUrl) {
40
+ return;
41
+ }
42
+ const reloadCode = `
43
+ ${this._SERVER_VAR}.dispose()
44
+ __jupyterpack_st_server, __jupyterpack_tor_app = await create_streamlit_app("${entryPath}", "${this._baseUrl}")
45
+ ${this._SERVER_VAR}.reload(__jupyterpack_tor_app, __jupyterpack_st_server)
46
+ `;
51
47
  await this.executeCode({
52
- code: '__jupyterpack_streamlit_dispose()'
53
- });
48
+ code: reloadCode
49
+ }, true);
54
50
  }
55
51
  }
@@ -26,7 +26,9 @@ export declare class TornadoServer extends KernelExecutor {
26
26
  message: string;
27
27
  }): string;
28
28
  disposePythonServer(): Promise<void>;
29
- private _GET_RESPONSE_FUNCTION;
30
- private _OPEN_WEBSOCKET_FUNCTION;
31
- private _SEND_WEBSOCKET_FUNCTION;
29
+ reloadPythonServer(options: {
30
+ entryPath?: string;
31
+ initCode?: string;
32
+ }): Promise<void>;
33
+ protected _SERVER_VAR: string;
32
34
  }
@@ -1,14 +1,10 @@
1
1
  import { stringOrNone } from '../../tools';
2
2
  import { JupyterPackFramework } from '../../type';
3
- import { tools } from '../common/generatedPythonFiles';
4
3
  import { KernelExecutor } from '../kernelExecutor';
5
- import { bootstrap, tornadoBridge, tornadoLoader } from './generatedPythonFiles';
6
4
  export class TornadoServer extends KernelExecutor {
7
5
  constructor() {
8
6
  super(...arguments);
9
- this._GET_RESPONSE_FUNCTION = '__jupyterpack_tornado_get_response';
10
- this._OPEN_WEBSOCKET_FUNCTION = '__jupyterpack_tornado_open_ws';
11
- this._SEND_WEBSOCKET_FUNCTION = '__jupyterpack_tornado_receive_ws_message';
7
+ this._SERVER_VAR = '__jupyterpack_tornado_server';
12
8
  }
13
9
  async init(options) {
14
10
  await super.init(options);
@@ -18,34 +14,55 @@ export class TornadoServer extends KernelExecutor {
18
14
  kernelClientId,
19
15
  framework: JupyterPackFramework.TORNADO
20
16
  });
21
- await this.executeCode({ code: tools.replaceAll('{{base_url}}', baseURL) });
22
- await this.executeCode({ code: bootstrap });
23
- await this.executeCode({ code: tornadoBridge });
17
+ const bootstrapCode = `
18
+ from jupyterpack.common import set_base_url_env, patch_tornado
19
+ set_base_url_env("${baseURL}")
20
+ patch_tornado()
21
+
22
+ `;
23
+ await this.executeCode({ code: bootstrapCode });
24
24
  if (initCode) {
25
25
  const initCodeWithUrl = initCode.replaceAll('{{base_url}}', baseURL);
26
26
  await this.executeCode({ code: initCodeWithUrl });
27
- const torCode = tornadoLoader.replaceAll('{{base_url}}', baseURL);
28
- await this.executeCode({ code: torCode });
27
+ const loaderCode = `
28
+ from jupyterpack.tornado import TornadoServer
29
+ ${this._SERVER_VAR} = TornadoServer(app, "${baseURL}")
30
+ `;
31
+ await this.executeCode({ code: loaderCode });
29
32
  }
30
33
  }
31
34
  getResponseFunctionFactory(options) {
32
35
  const { method, urlPath, headers, params, content } = options;
33
- const code = `await ${this._GET_RESPONSE_FUNCTION}("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
36
+ const code = `await ${this._SERVER_VAR}.get_response("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
34
37
  return code;
35
38
  }
36
39
  openWebsocketFunctionFactory(options) {
37
40
  const { instanceId, kernelId, wsUrl, protocol } = options;
38
- const code = `await ${this._OPEN_WEBSOCKET_FUNCTION}("${instanceId}", "${kernelId}", "${wsUrl}", ${stringOrNone(protocol)})`;
41
+ const code = `await ${this._SERVER_VAR}.open_ws("${instanceId}", "${kernelId}", "${wsUrl}", ${stringOrNone(protocol)})`;
39
42
  return code;
40
43
  }
41
44
  sendWebsocketMessageFunctionFactory(options) {
42
45
  const { instanceId, kernelId, wsUrl, message } = options;
43
- const code = `await ${this._SEND_WEBSOCKET_FUNCTION}("${instanceId}", "${kernelId}", "${wsUrl}", '''${message}''')`;
46
+ const code = `await ${this._SERVER_VAR}.receive_ws_message("${instanceId}", "${kernelId}", "${wsUrl}", '''${message}''')`;
44
47
  return code;
45
48
  }
46
49
  async disposePythonServer() {
47
50
  await this.executeCode({
48
- code: '__jupyterpack_tornado_dispose()'
51
+ code: `${this._SERVER_VAR}.dispose()`
49
52
  });
50
53
  }
54
+ async reloadPythonServer(options) {
55
+ var _a;
56
+ const { initCode } = options;
57
+ if (initCode) {
58
+ await this.executeCode({
59
+ code: initCode.replaceAll('{{base_url}}', (_a = this._baseUrl) !== null && _a !== void 0 ? _a : '')
60
+ });
61
+ const reloadCode = `
62
+ ${this._SERVER_VAR}.dispose()
63
+ ${this._SERVER_VAR}.reload(app)
64
+ `;
65
+ await this.executeCode({ code: reloadCode }, true);
66
+ }
67
+ }
51
68
  }
@@ -0,0 +1,11 @@
1
+ import { Kernel } from '@jupyterlab/services';
2
+ export declare class CommBroadcastManager {
3
+ constructor();
4
+ registerKernel(kernel: Kernel.IKernelConnection): void;
5
+ unregisterKernel(kernelId?: string): void;
6
+ private _handle_comm_open;
7
+ dispose(): void;
8
+ private _kernels;
9
+ private _comms;
10
+ private _broadcastChannels;
11
+ }