jupyterpack 0.4.0 → 0.5.1

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 (40) hide show
  1. package/README.md +1 -1
  2. package/lib/document/widgetFactory.js +3 -1
  3. package/lib/pythonServer/baseServer.d.ts +82 -0
  4. package/lib/pythonServer/baseServer.js +141 -0
  5. package/lib/pythonServer/dash/dashServer.d.ts +2 -12
  6. package/lib/pythonServer/dash/dashServer.js +8 -21
  7. package/lib/pythonServer/index.d.ts +3 -3
  8. package/lib/pythonServer/index.js +5 -1
  9. package/lib/pythonServer/kernelExecutor.d.ts +2 -58
  10. package/lib/pythonServer/kernelExecutor.js +0 -72
  11. package/lib/pythonServer/shiny/shinyServer.d.ts +14 -0
  12. package/lib/pythonServer/shiny/shinyServer.js +49 -0
  13. package/lib/pythonServer/starlette/starletteServer.d.ts +13 -0
  14. package/lib/pythonServer/starlette/starletteServer.js +49 -0
  15. package/lib/pythonServer/streamlit/streamlitServer.d.ts +0 -1
  16. package/lib/pythonServer/streamlit/streamlitServer.js +7 -11
  17. package/lib/pythonServer/tornado/tornadoServer.d.ts +2 -24
  18. package/lib/pythonServer/tornado/tornadoServer.js +10 -35
  19. package/lib/swConnection/mainConnectionManager.d.ts +4 -4
  20. package/lib/swConnection/mainConnectionManager.js +23 -12
  21. package/lib/tools.d.ts +1 -0
  22. package/lib/tools.js +8 -0
  23. package/lib/type.d.ts +12 -3
  24. package/lib/type.js +2 -0
  25. package/lib/websocket/websocket.js +5 -1
  26. package/package.json +1 -1
  27. package/src/document/widgetFactory.ts +3 -1
  28. package/src/pythonServer/baseServer.ts +245 -0
  29. package/src/pythonServer/dash/dashServer.ts +10 -29
  30. package/src/pythonServer/index.ts +9 -5
  31. package/src/pythonServer/kernelExecutor.ts +3 -156
  32. package/src/pythonServer/shiny/shinyServer.ts +62 -0
  33. package/src/pythonServer/starlette/starletteServer.ts +59 -0
  34. package/src/pythonServer/streamlit/streamlitServer.ts +7 -9
  35. package/src/pythonServer/tornado/tornadoServer.ts +11 -55
  36. package/src/pythonWidget/pythonWidgetModel.ts +2 -2
  37. package/src/swConnection/mainConnectionManager.ts +28 -20
  38. package/src/tools.ts +9 -0
  39. package/src/type.ts +17 -6
  40. package/src/websocket/websocket.ts +9 -1
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## Features
9
9
 
10
- - **Python Web Apps**: Serve Python web applications directly in the browser using JupyterLite's in-browser Python kernel. `jupyterpack` currently supports Dash.
10
+ - **Python Web Apps**: Serve Python web applications directly in the browser using JupyterLite's in-browser Python kernel. `jupyterpack` currently supports Dash and Streamlit.
11
11
  - **JavaScript Web Apps**: Bundle and serve JavaScript web applications using in-browser bundlers.
12
12
 
13
13
  ![Image](https://github.com/user-attachments/assets/22849fe8-199f-4d9f-ad45-055bccf88bad)
@@ -35,7 +35,9 @@ export class JupyterPackWidgetFactory extends ABCWidgetFactory {
35
35
  }
36
36
  case JupyterPackFramework.DASH:
37
37
  case JupyterPackFramework.STREAMLIT:
38
- case JupyterPackFramework.TORNADO: {
38
+ case JupyterPackFramework.TORNADO:
39
+ case JupyterPackFramework.STARLETTE:
40
+ case JupyterPackFramework.SHINY: {
39
41
  const model = new PythonWidgetModel({
40
42
  jpackModel,
41
43
  context,
@@ -0,0 +1,82 @@
1
+ import { KernelExecutor } from './kernelExecutor';
2
+ import { IDict, IBasePythonServer, IKernelExecutor, JupyterPackFramework } from '../type';
3
+ export declare abstract class BasePythonServer implements IBasePythonServer {
4
+ constructor(options: KernelExecutor.IOptions);
5
+ abstract reloadPythonServer(options: {
6
+ entryPath?: string;
7
+ initCode?: string;
8
+ }): Promise<void>;
9
+ get isDisposed(): boolean;
10
+ get kernelExecutor(): IKernelExecutor;
11
+ dispose(): void;
12
+ init(options: {
13
+ entryPath?: string;
14
+ initCode?: string;
15
+ instanceId: string;
16
+ kernelClientId: string;
17
+ }): Promise<void>;
18
+ disposePythonServer(): Promise<void>;
19
+ getResponseFunctionFactory(options: {
20
+ urlPath: string;
21
+ method: string;
22
+ headers: IDict;
23
+ params?: string;
24
+ content?: string;
25
+ }): string;
26
+ openWebsocketFunctionFactory(options: {
27
+ instanceId: string;
28
+ kernelId: string;
29
+ wsUrl: string;
30
+ protocol?: string;
31
+ }): string;
32
+ closeWebsocketFunctionFactory(options: {
33
+ instanceId: string;
34
+ kernelId: string;
35
+ wsUrl: string;
36
+ }): string;
37
+ sendWebsocketMessageFunctionFactory(options: {
38
+ instanceId: string;
39
+ kernelId: string;
40
+ wsUrl: string;
41
+ message: string;
42
+ }): string;
43
+ openWebsocket(options: {
44
+ instanceId: string;
45
+ kernelId: string;
46
+ wsUrl: string;
47
+ protocol?: string;
48
+ }): Promise<void>;
49
+ closeWebsocket(options: {
50
+ instanceId: string;
51
+ kernelId: string;
52
+ wsUrl: string;
53
+ }): Promise<void>;
54
+ sendWebsocketMessage(options: {
55
+ instanceId: string;
56
+ kernelId: string;
57
+ wsUrl: string;
58
+ message: string;
59
+ }): Promise<void>;
60
+ getResponse(options: {
61
+ method: string;
62
+ urlPath: string;
63
+ headers: IDict;
64
+ requestBody?: ArrayBuffer;
65
+ params?: string;
66
+ }): Promise<IDict>;
67
+ protected buildBaseURL(options: {
68
+ instanceId: string;
69
+ kernelClientId: string;
70
+ framework: JupyterPackFramework;
71
+ }): string;
72
+ protected _baseUrl: string | undefined;
73
+ protected readonly _openedWebsockets: {
74
+ instanceId: string;
75
+ kernelId: string;
76
+ wsUrl: string;
77
+ }[];
78
+ protected readonly _server_var = "__jupyterpack_python_server";
79
+ private _kernelExecutor;
80
+ private _isDisposed;
81
+ private _wsPatch;
82
+ }
@@ -0,0 +1,141 @@
1
+ import { KernelExecutor } from './kernelExecutor';
2
+ import websocketPatch from '../websocket/websocket.js?raw';
3
+ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
4
+ import { arrayBufferToBase64, base64ToArrayBuffer, base64ToString, isBinaryContentType, stringOrNone } from '../tools';
5
+ export class BasePythonServer {
6
+ constructor(options) {
7
+ this._openedWebsockets = [];
8
+ this._server_var = '__jupyterpack_python_server';
9
+ this._isDisposed = false;
10
+ this._kernelExecutor = new KernelExecutor(options);
11
+ this._wsPatch = websocketPatch.replaceAll('"use strict";', '');
12
+ }
13
+ get isDisposed() {
14
+ return this._isDisposed;
15
+ }
16
+ get kernelExecutor() {
17
+ return this._kernelExecutor;
18
+ }
19
+ dispose() {
20
+ if (this._isDisposed) {
21
+ return;
22
+ }
23
+ this._isDisposed = true;
24
+ this.disposePythonServer()
25
+ .then(() => {
26
+ this._kernelExecutor.dispose();
27
+ })
28
+ .catch(console.error);
29
+ }
30
+ async init(options) {
31
+ const patchCode = `
32
+ from jupyterpack.common import patch_all
33
+ patch_all()
34
+ `;
35
+ await this._kernelExecutor.executeCode({ code: patchCode });
36
+ }
37
+ async disposePythonServer() {
38
+ await this.kernelExecutor.executeCode({
39
+ code: `${this._server_var}.dispose()`
40
+ });
41
+ for (const element of this._openedWebsockets) {
42
+ await this.closeWebsocket(element);
43
+ }
44
+ }
45
+ getResponseFunctionFactory(options) {
46
+ const { method, urlPath, headers, params, content } = options;
47
+ const code = `await ${this._server_var}.get_response("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
48
+ return code;
49
+ }
50
+ openWebsocketFunctionFactory(options) {
51
+ const { instanceId, kernelId, wsUrl, protocol } = options;
52
+ const code = `await ${this._server_var}.open_ws("${instanceId}", "${kernelId}", "${wsUrl}", ${stringOrNone(protocol)})`;
53
+ return code;
54
+ }
55
+ closeWebsocketFunctionFactory(options) {
56
+ const { instanceId, kernelId, wsUrl } = options;
57
+ const code = `await ${this._server_var}.close_ws("${instanceId}", "${kernelId}", "${wsUrl}")`;
58
+ return code;
59
+ }
60
+ sendWebsocketMessageFunctionFactory(options) {
61
+ const { instanceId, kernelId, wsUrl, message } = options;
62
+ const code = `await ${this._server_var}.receive_ws_message("${instanceId}", "${kernelId}", "${wsUrl}", '''${message}''')`;
63
+ return code;
64
+ }
65
+ async openWebsocket(options) {
66
+ const code = this.openWebsocketFunctionFactory(options);
67
+ if (code) {
68
+ try {
69
+ await this._kernelExecutor.executeCode({ code });
70
+ this._openedWebsockets.push(options);
71
+ }
72
+ catch (e) {
73
+ console.error('Failed to open websocket', e);
74
+ }
75
+ }
76
+ else {
77
+ throw new Error('Missing websocket open code');
78
+ }
79
+ }
80
+ async closeWebsocket(options) {
81
+ const code = this.closeWebsocketFunctionFactory(options);
82
+ if (code) {
83
+ await this._kernelExecutor.executeCode({ code });
84
+ }
85
+ else {
86
+ throw new Error('Missing websocket close code');
87
+ }
88
+ }
89
+ async sendWebsocketMessage(options) {
90
+ const code = this.sendWebsocketMessageFunctionFactory(options);
91
+ if (code) {
92
+ await this._kernelExecutor.executeCode({ code });
93
+ }
94
+ else {
95
+ throw new Error('Missing websocket send code');
96
+ }
97
+ }
98
+ async getResponse(options) {
99
+ var _a;
100
+ const { method, urlPath, requestBody, params, headers } = options;
101
+ const content = requestBody ? arrayBufferToBase64(requestBody) : undefined;
102
+ const code = this.getResponseFunctionFactory({
103
+ method,
104
+ urlPath,
105
+ headers,
106
+ params,
107
+ content
108
+ });
109
+ const raw = await this._kernelExecutor.executeCode({ code }, true);
110
+ if (!raw) {
111
+ throw new Error(`Missing response for ${urlPath}`);
112
+ }
113
+ const jsonStr = raw.replaceAll("'", '');
114
+ const obj = JSON.parse(jsonStr);
115
+ const responseHeaders = JSON.parse(atob(obj.headers));
116
+ const contentType = (_a = responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders['Content-Type']) !== null && _a !== void 0 ? _a : responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders['content-type'];
117
+ let responseContent;
118
+ if (isBinaryContentType(contentType)) {
119
+ responseContent = base64ToArrayBuffer(obj.content);
120
+ }
121
+ else {
122
+ responseContent = base64ToString(obj.content);
123
+ }
124
+ if (contentType && contentType.toLowerCase().includes('text/html')) {
125
+ responseContent = responseContent.replace('<head>', `<head>\n<script>\n${this._wsPatch}\n</script>\n`);
126
+ }
127
+ const decodedObj = {
128
+ status_code: obj.status_code,
129
+ headers: responseHeaders,
130
+ content: responseContent
131
+ };
132
+ return decodedObj;
133
+ }
134
+ buildBaseURL(options) {
135
+ const { instanceId, kernelClientId, framework } = options;
136
+ const fullLabextensionsUrl = PageConfig.getOption('fullLabextensionsUrl');
137
+ const baseURL = URLExt.join(fullLabextensionsUrl, 'jupyterpack/static', instanceId, framework, kernelClientId, '/');
138
+ this._baseUrl = baseURL;
139
+ return baseURL;
140
+ }
141
+ }
@@ -1,22 +1,12 @@
1
- import { IDict } from '../../type';
2
- import { KernelExecutor } from '../kernelExecutor';
3
- export declare class DashServer extends KernelExecutor {
1
+ import { BasePythonServer } from '../baseServer';
2
+ export declare class DashServer extends BasePythonServer {
4
3
  init(options: {
5
4
  initCode?: string;
6
5
  instanceId: string;
7
6
  kernelClientId: string;
8
7
  }): Promise<void>;
9
- getResponseFunctionFactory(options: {
10
- urlPath: string;
11
- method: string;
12
- headers: IDict;
13
- params?: string;
14
- content?: string;
15
- }): string;
16
- disposePythonServer(): Promise<void>;
17
8
  reloadPythonServer(options: {
18
9
  entryPath?: string;
19
10
  initCode?: string;
20
11
  }): Promise<void>;
21
- private _DASH_SERVER_VAR;
22
12
  }
@@ -1,11 +1,6 @@
1
- import { stringOrNone } from '../../tools';
2
1
  import { JupyterPackFramework } from '../../type';
3
- import { KernelExecutor } from '../kernelExecutor';
4
- export class DashServer extends KernelExecutor {
5
- constructor() {
6
- super(...arguments);
7
- this._DASH_SERVER_VAR = '__jupyterpack_dash_server';
8
- }
2
+ import { BasePythonServer } from '../baseServer';
3
+ export class DashServer extends BasePythonServer {
9
4
  async init(options) {
10
5
  await super.init(options);
11
6
  const { initCode, instanceId, kernelClientId } = options;
@@ -14,34 +9,26 @@ export class DashServer extends KernelExecutor {
14
9
  kernelClientId,
15
10
  framework: JupyterPackFramework.DASH
16
11
  });
17
- await this.executeCode({
12
+ await this.kernelExecutor.executeCode({
18
13
  code: `
19
14
  import os
20
15
  os.environ["DASH_URL_BASE_PATHNAME"] = "${baseURL}"
21
16
  `
22
17
  });
23
18
  if (initCode) {
24
- await this.executeCode({ code: initCode });
19
+ await this.kernelExecutor.executeCode({ code: initCode });
25
20
  }
26
21
  const loaderCode = `
27
22
  from jupyterpack.dash import DashServer
28
- ${this._DASH_SERVER_VAR} = DashServer(app, "${baseURL}")
23
+ ${this._server_var} = DashServer(app, "${baseURL}")
29
24
  `;
30
- await this.executeCode({ code: loaderCode });
31
- }
32
- getResponseFunctionFactory(options) {
33
- const { method, urlPath, headers, params, content } = options;
34
- const code = `${this._DASH_SERVER_VAR}.get_response("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
35
- return code;
36
- }
37
- async disposePythonServer() {
38
- await this.executeCode({ code: `${this._DASH_SERVER_VAR}.dispose()` });
25
+ await this.kernelExecutor.executeCode({ code: loaderCode });
39
26
  }
40
27
  async reloadPythonServer(options) {
41
28
  const { initCode } = options;
42
29
  if (initCode) {
43
- await this.executeCode({ code: initCode });
30
+ await this.kernelExecutor.executeCode({ code: initCode });
44
31
  }
45
- await this.executeCode({ code: `${this._DASH_SERVER_VAR}.reload(app)` }, true);
32
+ await this.kernelExecutor.executeCode({ code: `${this._server_var}.reload(app)` }, true);
46
33
  }
47
34
  }
@@ -1,5 +1,5 @@
1
- import { IKernelExecutor, JupyterPackFramework } from '../type';
1
+ import { IBasePythonServer, JupyterPackFramework } from '../type';
2
2
  import { KernelExecutor } from './kernelExecutor';
3
- type KernelExecutorConstructor = new (options: KernelExecutor.IOptions) => IKernelExecutor;
4
- export declare const PYTHON_SERVER: Map<JupyterPackFramework, KernelExecutorConstructor>;
3
+ type BasePythonServerConstructor = new (options: KernelExecutor.IOptions) => IBasePythonServer;
4
+ export declare const PYTHON_SERVER: Map<JupyterPackFramework, BasePythonServerConstructor>;
5
5
  export {};
@@ -1,9 +1,13 @@
1
1
  import { JupyterPackFramework } from '../type';
2
2
  import { DashServer } from './dash/dashServer';
3
+ import { ShinyServer } from './shiny/shinyServer';
4
+ import { StarletteServer } from './starlette/starletteServer';
3
5
  import { StreamlitServer } from './streamlit/streamlitServer';
4
6
  import { TornadoServer } from './tornado/tornadoServer';
5
7
  export const PYTHON_SERVER = new Map([
6
8
  [JupyterPackFramework.DASH, DashServer],
7
9
  [JupyterPackFramework.STREAMLIT, StreamlitServer],
8
- [JupyterPackFramework.TORNADO, TornadoServer]
10
+ [JupyterPackFramework.TORNADO, TornadoServer],
11
+ [JupyterPackFramework.SHINY, ShinyServer],
12
+ [JupyterPackFramework.STARLETTE, StarletteServer]
9
13
  ]);
@@ -1,68 +1,12 @@
1
1
  import { KernelMessage, Session } from '@jupyterlab/services';
2
- import { IDict, IKernelExecutor, JupyterPackFramework } from '../type';
3
- export declare abstract class KernelExecutor implements IKernelExecutor {
2
+ import { IKernelExecutor } from '../type';
3
+ export declare class KernelExecutor implements IKernelExecutor {
4
4
  constructor(options: KernelExecutor.IOptions);
5
5
  get isDisposed(): boolean;
6
- abstract disposePythonServer(): Promise<void>;
7
- abstract reloadPythonServer(options: {
8
- entryPath?: string;
9
- initCode?: string;
10
- }): Promise<void>;
11
- abstract getResponseFunctionFactory(options: {
12
- urlPath: string;
13
- method: string;
14
- headers: IDict;
15
- params?: string;
16
- content?: string;
17
- }): string;
18
- init(options: {
19
- entryPath?: string;
20
- initCode?: string;
21
- instanceId: string;
22
- kernelClientId: string;
23
- }): Promise<void>;
24
- openWebsocketFunctionFactory(options: {
25
- instanceId: string;
26
- kernelId: string;
27
- wsUrl: string;
28
- protocol?: string;
29
- }): string | undefined;
30
- sendWebsocketMessageFunctionFactory(options: {
31
- instanceId: string;
32
- kernelId: string;
33
- wsUrl: string;
34
- message: string;
35
- }): string | undefined;
36
- openWebsocket(options: {
37
- instanceId: string;
38
- kernelId: string;
39
- wsUrl: string;
40
- protocol?: string;
41
- }): Promise<void>;
42
- sendWebsocketMessage(options: {
43
- instanceId: string;
44
- kernelId: string;
45
- wsUrl: string;
46
- message: string;
47
- }): Promise<void>;
48
- getResponse(options: {
49
- method: string;
50
- urlPath: string;
51
- headers: IDict;
52
- requestBody?: ArrayBuffer;
53
- params?: string;
54
- }): Promise<IDict>;
55
6
  executeCode(code: KernelMessage.IExecuteRequestMsg['content'], waitForResult?: boolean): Promise<string | null>;
56
7
  dispose(): void;
57
- protected buildBaseURL(options: {
58
- instanceId: string;
59
- kernelClientId: string;
60
- framework: JupyterPackFramework;
61
- }): string;
62
- protected _baseUrl: string | undefined;
63
8
  private _isDisposed;
64
9
  private _sessionConnection;
65
- private _wsPatch;
66
10
  }
67
11
  export declare namespace KernelExecutor {
68
12
  interface IOptions {
@@ -1,77 +1,12 @@
1
- import { PageConfig, URLExt } from '@jupyterlab/coreutils';
2
1
  import stripAnsi from 'strip-ansi';
3
- import { arrayBufferToBase64, base64ToArrayBuffer, base64ToString, isBinaryContentType } from '../tools';
4
- import websocketPatch from '../websocket/websocket.js?raw';
5
2
  export class KernelExecutor {
6
3
  constructor(options) {
7
4
  this._isDisposed = false;
8
5
  this._sessionConnection = options.sessionConnection;
9
- this._wsPatch = websocketPatch.replaceAll('"use strict";', '');
10
6
  }
11
7
  get isDisposed() {
12
8
  return this._isDisposed;
13
9
  }
14
- async init(options) {
15
- const patchCode = `
16
- from jupyterpack.common import patch_all
17
- patch_all()
18
- `;
19
- await this.executeCode({ code: patchCode });
20
- }
21
- openWebsocketFunctionFactory(options) {
22
- return undefined;
23
- }
24
- sendWebsocketMessageFunctionFactory(options) {
25
- return undefined;
26
- }
27
- async openWebsocket(options) {
28
- const code = this.openWebsocketFunctionFactory(options);
29
- if (code) {
30
- await this.executeCode({ code });
31
- }
32
- }
33
- async sendWebsocketMessage(options) {
34
- const code = this.sendWebsocketMessageFunctionFactory(options);
35
- if (code) {
36
- await this.executeCode({ code });
37
- }
38
- }
39
- async getResponse(options) {
40
- var _a;
41
- const { method, urlPath, requestBody, params, headers } = options;
42
- const content = requestBody ? arrayBufferToBase64(requestBody) : undefined;
43
- const code = this.getResponseFunctionFactory({
44
- method,
45
- urlPath,
46
- headers,
47
- params,
48
- content
49
- });
50
- const raw = await this.executeCode({ code }, true);
51
- if (!raw) {
52
- throw new Error(`Missing response for ${urlPath}`);
53
- }
54
- const jsonStr = raw.replaceAll("'", '');
55
- const obj = JSON.parse(jsonStr);
56
- const responseHeaders = JSON.parse(atob(obj.headers));
57
- const contentType = (_a = responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders['Content-Type']) !== null && _a !== void 0 ? _a : responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders['content-type'];
58
- let responseContent;
59
- if (isBinaryContentType(contentType)) {
60
- responseContent = base64ToArrayBuffer(obj.content);
61
- }
62
- else {
63
- responseContent = base64ToString(obj.content);
64
- }
65
- if (contentType && contentType.toLowerCase() === 'text/html') {
66
- responseContent = responseContent.replace('<head>', `<head>\n<script>\n${this._wsPatch}\n</script>\n`);
67
- }
68
- const decodedObj = {
69
- status_code: obj.status_code,
70
- headers: responseHeaders,
71
- content: responseContent
72
- };
73
- return decodedObj;
74
- }
75
10
  async executeCode(code, waitForResult) {
76
11
  var _a;
77
12
  const kernel = (_a = this._sessionConnection) === null || _a === void 0 ? void 0 : _a.kernel;
@@ -130,11 +65,4 @@ export class KernelExecutor {
130
65
  this._isDisposed = true;
131
66
  this._sessionConnection.dispose();
132
67
  }
133
- buildBaseURL(options) {
134
- const { instanceId, kernelClientId, framework } = options;
135
- const fullLabextensionsUrl = PageConfig.getOption('fullLabextensionsUrl');
136
- const baseURL = URLExt.join(fullLabextensionsUrl, 'jupyterpack/static', instanceId, framework, kernelClientId, '/');
137
- this._baseUrl = baseURL;
138
- return baseURL;
139
- }
140
68
  }
@@ -0,0 +1,14 @@
1
+ import { BasePythonServer } from '../baseServer';
2
+ export declare class ShinyServer extends BasePythonServer {
3
+ init(options: {
4
+ entryPath?: string;
5
+ initCode?: string;
6
+ instanceId: string;
7
+ kernelClientId: string;
8
+ }): Promise<void>;
9
+ disposePythonServer(): Promise<void>;
10
+ reloadPythonServer(options: {
11
+ entryPath?: string;
12
+ initCode?: string;
13
+ }): Promise<void>;
14
+ }
@@ -0,0 +1,49 @@
1
+ import { JupyterPackFramework } from '../../type';
2
+ import { BasePythonServer } from '../baseServer';
3
+ export class ShinyServer extends BasePythonServer {
4
+ async init(options) {
5
+ await super.init(options);
6
+ const { instanceId, kernelClientId, entryPath } = options;
7
+ const baseURL = this.buildBaseURL({
8
+ instanceId,
9
+ kernelClientId,
10
+ framework: JupyterPackFramework.SHINY
11
+ });
12
+ const bootstrapCode = `
13
+ from jupyterpack.common import set_base_url_env
14
+ set_base_url_env("${baseURL}")
15
+ from jupyterpack.shiny import patch_shiny
16
+ patch_shiny()
17
+ `;
18
+ await this.kernelExecutor.executeCode({ code: bootstrapCode });
19
+ if (entryPath) {
20
+ const loaderCode = `
21
+ from jupyterpack.shiny import ShinyServer, get_shiny_app
22
+
23
+
24
+ ${this._server_var} = ShinyServer(get_shiny_app("${entryPath}"), "${baseURL}")
25
+ `;
26
+ await this.kernelExecutor.executeCode({ code: loaderCode });
27
+ }
28
+ }
29
+ async disposePythonServer() {
30
+ await this.kernelExecutor.executeCode({
31
+ code: `${this._server_var}.dispose()`
32
+ });
33
+ for (const element of this._openedWebsockets) {
34
+ await this.closeWebsocket(element);
35
+ }
36
+ }
37
+ async reloadPythonServer(options) {
38
+ const { entryPath } = options;
39
+ if (entryPath) {
40
+ const reloadCode = `
41
+ from jupyterpack.shiny import get_shiny_app
42
+
43
+ await ${this._server_var}.dispose()
44
+ ${this._server_var}.reload(get_shiny_app("${entryPath}"))
45
+ `;
46
+ await this.kernelExecutor.executeCode({ code: reloadCode }, true);
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,13 @@
1
+ import { BasePythonServer } from '../baseServer';
2
+ export declare class StarletteServer extends BasePythonServer {
3
+ init(options: {
4
+ initCode?: string;
5
+ instanceId: string;
6
+ kernelClientId: string;
7
+ }): Promise<void>;
8
+ disposePythonServer(): Promise<void>;
9
+ reloadPythonServer(options: {
10
+ entryPath?: string;
11
+ initCode?: string;
12
+ }): Promise<void>;
13
+ }
@@ -0,0 +1,49 @@
1
+ import { JupyterPackFramework } from '../../type';
2
+ import { BasePythonServer } from '../baseServer';
3
+ export class StarletteServer extends BasePythonServer {
4
+ async init(options) {
5
+ await super.init(options);
6
+ const { initCode, instanceId, kernelClientId } = options;
7
+ const baseURL = this.buildBaseURL({
8
+ instanceId,
9
+ kernelClientId,
10
+ framework: JupyterPackFramework.STARLETTE
11
+ });
12
+ const bootstrapCode = `
13
+ from jupyterpack.common import set_base_url_env
14
+ set_base_url_env("${baseURL}")
15
+ `;
16
+ await this.kernelExecutor.executeCode({ code: bootstrapCode });
17
+ if (initCode) {
18
+ const initCodeWithUrl = initCode.replaceAll('{{base_url}}', baseURL);
19
+ await this.kernelExecutor.executeCode({ code: initCodeWithUrl });
20
+ const loaderCode = `
21
+ from jupyterpack.asgi import AsgiServer
22
+ ${this._server_var} = AsgiServer(app, "${baseURL}")
23
+ `;
24
+ await this.kernelExecutor.executeCode({ code: loaderCode });
25
+ }
26
+ }
27
+ async disposePythonServer() {
28
+ await this.kernelExecutor.executeCode({
29
+ code: `${this._server_var}.dispose()`
30
+ });
31
+ for (const element of this._openedWebsockets) {
32
+ await this.closeWebsocket(element);
33
+ }
34
+ }
35
+ async reloadPythonServer(options) {
36
+ var _a;
37
+ const { initCode } = options;
38
+ if (initCode) {
39
+ await this.kernelExecutor.executeCode({
40
+ code: initCode.replaceAll('{{base_url}}', (_a = this._baseUrl) !== null && _a !== void 0 ? _a : '')
41
+ });
42
+ const reloadCode = `
43
+ await ${this._server_var}.dispose()
44
+ ${this._server_var}.reload(app)
45
+ `;
46
+ await this.kernelExecutor.executeCode({ code: reloadCode }, true);
47
+ }
48
+ }
49
+ }
@@ -10,5 +10,4 @@ export declare class StreamlitServer extends TornadoServer {
10
10
  entryPath?: string;
11
11
  initCode?: string;
12
12
  }): Promise<void>;
13
- protected _SERVER_VAR: string;
14
13
  }