jupyterpack 0.4.0 → 0.5.2
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.
- package/README.md +107 -3
- package/lib/document/widgetFactory.js +3 -1
- package/lib/pythonServer/baseServer.d.ts +78 -0
- package/lib/pythonServer/baseServer.js +175 -0
- package/lib/pythonServer/dash/dashServer.d.ts +4 -17
- package/lib/pythonServer/dash/dashServer.js +14 -22
- package/lib/pythonServer/dash/deps.d.ts +2 -0
- package/lib/pythonServer/dash/deps.js +4 -0
- package/lib/pythonServer/index.d.ts +3 -3
- package/lib/pythonServer/index.js +5 -1
- package/lib/pythonServer/kernelExecutor.d.ts +2 -58
- package/lib/pythonServer/kernelExecutor.js +0 -72
- package/lib/pythonServer/shiny/deps.d.ts +2 -0
- package/lib/pythonServer/shiny/deps.js +4 -0
- package/lib/pythonServer/shiny/shinyServer.d.ts +10 -0
- package/lib/pythonServer/shiny/shinyServer.js +54 -0
- package/lib/pythonServer/starlette/starletteServer.d.ts +13 -0
- package/lib/pythonServer/starlette/starletteServer.js +49 -0
- package/lib/pythonServer/streamlit/deps.d.ts +2 -0
- package/lib/pythonServer/streamlit/deps.js +10 -0
- package/lib/pythonServer/streamlit/streamlitServer.d.ts +4 -9
- package/lib/pythonServer/streamlit/streamlitServer.js +16 -15
- package/lib/pythonServer/tornado/tornadoServer.d.ts +2 -24
- package/lib/pythonServer/tornado/tornadoServer.js +10 -35
- package/lib/pythonWidget/pythonWidgetModel.js +2 -0
- package/lib/swConnection/mainConnectionManager.d.ts +4 -4
- package/lib/swConnection/mainConnectionManager.js +23 -12
- package/lib/tools.d.ts +1 -0
- package/lib/tools.js +8 -0
- package/lib/type.d.ts +27 -9
- package/lib/type.js +2 -0
- package/lib/websocket/websocket.js +5 -1
- package/package.json +1 -1
- package/src/document/widgetFactory.ts +3 -1
- package/src/pythonServer/baseServer.ts +285 -0
- package/src/pythonServer/dash/dashServer.ts +18 -35
- package/src/pythonServer/dash/deps.ts +6 -0
- package/src/pythonServer/index.ts +9 -5
- package/src/pythonServer/kernelExecutor.ts +3 -156
- package/src/pythonServer/shiny/deps.ts +6 -0
- package/src/pythonServer/shiny/shinyServer.ts +63 -0
- package/src/pythonServer/starlette/starletteServer.ts +59 -0
- package/src/pythonServer/streamlit/deps.ts +12 -0
- package/src/pythonServer/streamlit/streamlitServer.ts +19 -20
- package/src/pythonServer/tornado/tornadoServer.ts +11 -55
- package/src/pythonWidget/pythonWidgetModel.ts +5 -2
- package/src/swConnection/mainConnectionManager.ts +28 -20
- package/src/tools.ts +9 -0
- package/src/type.ts +34 -12
- package/src/websocket/websocket.ts +9 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { JupyterPackFramework } from '../../type';
|
|
2
|
+
import { BasePythonServer } from '../baseServer';
|
|
3
|
+
|
|
4
|
+
export class StarletteServer extends BasePythonServer {
|
|
5
|
+
async init(options: {
|
|
6
|
+
initCode?: string;
|
|
7
|
+
instanceId: string;
|
|
8
|
+
kernelClientId: string;
|
|
9
|
+
}) {
|
|
10
|
+
await super.init(options);
|
|
11
|
+
const { initCode, instanceId, kernelClientId } = options;
|
|
12
|
+
const baseURL = this.buildBaseURL({
|
|
13
|
+
instanceId,
|
|
14
|
+
kernelClientId,
|
|
15
|
+
framework: JupyterPackFramework.STARLETTE
|
|
16
|
+
});
|
|
17
|
+
const bootstrapCode = `
|
|
18
|
+
from jupyterpack.common import set_base_url_env
|
|
19
|
+
set_base_url_env("${baseURL}")
|
|
20
|
+
`;
|
|
21
|
+
await this.kernelExecutor.executeCode({ code: bootstrapCode });
|
|
22
|
+
if (initCode) {
|
|
23
|
+
const initCodeWithUrl = initCode.replaceAll('{{base_url}}', baseURL);
|
|
24
|
+
await this.kernelExecutor.executeCode({ code: initCodeWithUrl });
|
|
25
|
+
const loaderCode = `
|
|
26
|
+
from jupyterpack.asgi import AsgiServer
|
|
27
|
+
${this._server_var} = AsgiServer(app, "${baseURL}")
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
await this.kernelExecutor.executeCode({ code: loaderCode });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async disposePythonServer(): Promise<void> {
|
|
35
|
+
await this.kernelExecutor.executeCode({
|
|
36
|
+
code: `${this._server_var}.dispose()`
|
|
37
|
+
});
|
|
38
|
+
for (const element of this._openedWebsockets) {
|
|
39
|
+
await this.closeWebsocket(element);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async reloadPythonServer(options: {
|
|
44
|
+
entryPath?: string;
|
|
45
|
+
initCode?: string;
|
|
46
|
+
}): Promise<void> {
|
|
47
|
+
const { initCode } = options;
|
|
48
|
+
if (initCode) {
|
|
49
|
+
await this.kernelExecutor.executeCode({
|
|
50
|
+
code: initCode.replaceAll('{{base_url}}', this._baseUrl ?? '')
|
|
51
|
+
});
|
|
52
|
+
const reloadCode = `
|
|
53
|
+
await ${this._server_var}.dispose()
|
|
54
|
+
${this._server_var}.reload(app)
|
|
55
|
+
`;
|
|
56
|
+
await this.kernelExecutor.executeCode({ code: reloadCode }, true);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { JupyterPackFramework } from '../../type';
|
|
2
|
-
import {
|
|
1
|
+
import { IPythonServerInitOptions, JupyterPackFramework } from '../../type';
|
|
2
|
+
import { BasePythonServer } from '../baseServer';
|
|
3
|
+
import { DEPENDENCIES } from './deps';
|
|
4
|
+
|
|
5
|
+
export class StreamlitServer extends BasePythonServer {
|
|
6
|
+
async init(options: IPythonServerInitOptions) {
|
|
7
|
+
const mergedOptions: IPythonServerInitOptions = {
|
|
8
|
+
...options,
|
|
9
|
+
dependencies: this.mergeDependencies(options.dependencies, DEPENDENCIES)
|
|
10
|
+
};
|
|
11
|
+
await super.init(mergedOptions);
|
|
3
12
|
|
|
4
|
-
export class StreamlitServer extends TornadoServer {
|
|
5
|
-
async init(options: {
|
|
6
|
-
entryPath?: string;
|
|
7
|
-
initCode?: string;
|
|
8
|
-
instanceId: string;
|
|
9
|
-
kernelClientId: string;
|
|
10
|
-
}) {
|
|
11
13
|
const { instanceId, kernelClientId, entryPath } = options;
|
|
12
14
|
if (!entryPath) {
|
|
13
15
|
throw new Error(
|
|
@@ -21,25 +23,24 @@ export class StreamlitServer extends TornadoServer {
|
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
const patchCode = `
|
|
24
|
-
from jupyterpack.common import set_base_url_env, patch_tornado
|
|
25
|
-
patch_all()
|
|
26
|
+
from jupyterpack.common import set_base_url_env, patch_tornado
|
|
26
27
|
patch_tornado()
|
|
27
28
|
set_base_url_env("${baseURL}")
|
|
28
29
|
`;
|
|
29
|
-
await this.executeCode({ code: patchCode });
|
|
30
|
+
await this.kernelExecutor.executeCode({ code: patchCode });
|
|
30
31
|
|
|
31
32
|
const bootstrapCode = `
|
|
32
33
|
from jupyterpack.streamlit import patch_streamlit
|
|
33
34
|
patch_streamlit()
|
|
34
35
|
`;
|
|
35
|
-
await this.executeCode({ code: bootstrapCode });
|
|
36
|
+
await this.kernelExecutor.executeCode({ code: bootstrapCode });
|
|
36
37
|
|
|
37
38
|
const stCode = `
|
|
38
39
|
from jupyterpack.streamlit import StreamlitServer, create_streamlit_app
|
|
39
40
|
__jupyterpack_st_server, __jupyterpack_tor_app = await create_streamlit_app("${entryPath}", "${baseURL}")
|
|
40
|
-
${this.
|
|
41
|
+
${this._server_var} = StreamlitServer(__jupyterpack_tor_app, "${baseURL}", __jupyterpack_st_server)
|
|
41
42
|
`;
|
|
42
|
-
await this.executeCode({ code: stCode });
|
|
43
|
+
await this.kernelExecutor.executeCode({ code: stCode });
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
async reloadPythonServer(options: {
|
|
@@ -51,17 +52,15 @@ export class StreamlitServer extends TornadoServer {
|
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
const reloadCode = `
|
|
54
|
-
${this.
|
|
55
|
+
${this._server_var}.dispose()
|
|
55
56
|
__jupyterpack_st_server, __jupyterpack_tor_app = await create_streamlit_app("${entryPath}", "${this._baseUrl}")
|
|
56
|
-
${this.
|
|
57
|
+
${this._server_var}.reload(__jupyterpack_tor_app, __jupyterpack_st_server)
|
|
57
58
|
`;
|
|
58
|
-
await this.executeCode(
|
|
59
|
+
await this.kernelExecutor.executeCode(
|
|
59
60
|
{
|
|
60
61
|
code: reloadCode
|
|
61
62
|
},
|
|
62
63
|
true
|
|
63
64
|
);
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
protected _SERVER_VAR = '__jupyterpack_streamlit_server';
|
|
67
66
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { KernelExecutor } from '../kernelExecutor';
|
|
1
|
+
import { JupyterPackFramework } from '../../type';
|
|
2
|
+
import { BasePythonServer } from '../baseServer';
|
|
4
3
|
|
|
5
|
-
export class TornadoServer extends
|
|
4
|
+
export class TornadoServer extends BasePythonServer {
|
|
6
5
|
async init(options: {
|
|
7
6
|
initCode?: string;
|
|
8
7
|
instanceId: string;
|
|
@@ -22,76 +21,33 @@ export class TornadoServer extends KernelExecutor {
|
|
|
22
21
|
patch_tornado()
|
|
23
22
|
|
|
24
23
|
`;
|
|
25
|
-
await this.executeCode({ code: bootstrapCode });
|
|
24
|
+
await this.kernelExecutor.executeCode({ code: bootstrapCode });
|
|
26
25
|
if (initCode) {
|
|
27
26
|
const initCodeWithUrl = initCode.replaceAll('{{base_url}}', baseURL);
|
|
28
|
-
await this.executeCode({ code: initCodeWithUrl });
|
|
27
|
+
await this.kernelExecutor.executeCode({ code: initCodeWithUrl });
|
|
29
28
|
const loaderCode = `
|
|
30
29
|
from jupyterpack.tornado import TornadoServer
|
|
31
|
-
${this.
|
|
30
|
+
${this._server_var} = TornadoServer(app, "${baseURL}")
|
|
32
31
|
`;
|
|
33
32
|
|
|
34
|
-
await this.executeCode({ code: loaderCode });
|
|
33
|
+
await this.kernelExecutor.executeCode({ code: loaderCode });
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
getResponseFunctionFactory(options: {
|
|
39
|
-
urlPath: string;
|
|
40
|
-
method: string;
|
|
41
|
-
headers: IDict;
|
|
42
|
-
params?: string;
|
|
43
|
-
content?: string;
|
|
44
|
-
}) {
|
|
45
|
-
const { method, urlPath, headers, params, content } = options;
|
|
46
|
-
const code = `await ${this._SERVER_VAR}.get_response("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
|
|
47
|
-
return code;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
openWebsocketFunctionFactory(options: {
|
|
51
|
-
instanceId: string;
|
|
52
|
-
kernelId: string;
|
|
53
|
-
wsUrl: string;
|
|
54
|
-
protocol?: string;
|
|
55
|
-
}): string {
|
|
56
|
-
const { instanceId, kernelId, wsUrl, protocol } = options;
|
|
57
|
-
|
|
58
|
-
const code = `await ${this._SERVER_VAR}.open_ws("${instanceId}", "${kernelId}", "${wsUrl}", ${stringOrNone(protocol)})`;
|
|
59
|
-
return code;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
sendWebsocketMessageFunctionFactory(options: {
|
|
63
|
-
instanceId: string;
|
|
64
|
-
kernelId: string;
|
|
65
|
-
wsUrl: string;
|
|
66
|
-
message: string;
|
|
67
|
-
}): string {
|
|
68
|
-
const { instanceId, kernelId, wsUrl, message } = options;
|
|
69
|
-
const code = `await ${this._SERVER_VAR}.receive_ws_message("${instanceId}", "${kernelId}", "${wsUrl}", '''${message}''')`;
|
|
70
|
-
return code;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async disposePythonServer(): Promise<void> {
|
|
74
|
-
await this.executeCode({
|
|
75
|
-
code: `${this._SERVER_VAR}.dispose()`
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
37
|
async reloadPythonServer(options: {
|
|
80
38
|
entryPath?: string;
|
|
81
39
|
initCode?: string;
|
|
82
40
|
}): Promise<void> {
|
|
83
41
|
const { initCode } = options;
|
|
84
42
|
if (initCode) {
|
|
85
|
-
await this.executeCode({
|
|
43
|
+
await this.kernelExecutor.executeCode({
|
|
86
44
|
code: initCode.replaceAll('{{base_url}}', this._baseUrl ?? '')
|
|
87
45
|
});
|
|
88
46
|
const reloadCode = `
|
|
89
|
-
${this.
|
|
90
|
-
${this.
|
|
47
|
+
${this._server_var}.dispose()
|
|
48
|
+
${this._server_var}.reload(app)
|
|
91
49
|
`;
|
|
92
|
-
await this.executeCode({ code: reloadCode }, true);
|
|
50
|
+
await this.kernelExecutor.executeCode({ code: reloadCode }, true);
|
|
93
51
|
}
|
|
94
52
|
}
|
|
95
|
-
|
|
96
|
-
protected _SERVER_VAR = '__jupyterpack_tornado_server';
|
|
97
53
|
}
|
|
@@ -11,9 +11,9 @@ import { PromiseDelegate } from '@lumino/coreutils';
|
|
|
11
11
|
import { PYTHON_SERVER } from '../pythonServer';
|
|
12
12
|
import { Signal } from '@lumino/signaling';
|
|
13
13
|
import {
|
|
14
|
+
IBasePythonServer,
|
|
14
15
|
IConnectionManager,
|
|
15
16
|
IJupyterPackFileFormat,
|
|
16
|
-
IKernelExecutor,
|
|
17
17
|
IPythonWidgetModel,
|
|
18
18
|
JupyterPackFramework
|
|
19
19
|
} from '../type';
|
|
@@ -135,9 +135,12 @@ export class PythonWidgetModel implements IPythonWidgetModel {
|
|
|
135
135
|
sessionConnection: this._sessionConnection
|
|
136
136
|
}));
|
|
137
137
|
const data = await this._connectionManager.registerConnection(executor);
|
|
138
|
+
|
|
138
139
|
await executor.init({
|
|
139
140
|
initCode: entryContent.content,
|
|
140
141
|
entryPath: spkContent.entry,
|
|
142
|
+
dependencies: spkContent.dependencies,
|
|
143
|
+
disableDependencies: spkContent.disableDependencies,
|
|
141
144
|
...data
|
|
142
145
|
});
|
|
143
146
|
const finish = new PromiseDelegate<void>();
|
|
@@ -203,7 +206,7 @@ export class PythonWidgetModel implements IPythonWidgetModel {
|
|
|
203
206
|
private _connectionManager: IConnectionManager;
|
|
204
207
|
private _contentsManager: Contents.IManager;
|
|
205
208
|
private _jpackModel: IJupyterPackFileFormat;
|
|
206
|
-
private _executor?:
|
|
209
|
+
private _executor?: IBasePythonServer;
|
|
207
210
|
private _localPath: string;
|
|
208
211
|
|
|
209
212
|
private _serverReloaded: Signal<IPythonWidgetModel, void> = new Signal<
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { arrayBufferToBase64 } from '../tools';
|
|
1
|
+
import { arrayBufferToBase64, stringToBase64 } from '../tools';
|
|
2
2
|
import {
|
|
3
|
+
IBasePythonServer,
|
|
3
4
|
IBroadcastMessage,
|
|
4
5
|
IConnectionManager,
|
|
5
|
-
IDict
|
|
6
|
-
IKernelExecutor
|
|
6
|
+
IDict
|
|
7
7
|
} from '../type';
|
|
8
8
|
import { UUID } from '@lumino/coreutils';
|
|
9
9
|
|
|
@@ -16,20 +16,19 @@ import { UUID } from '@lumino/coreutils';
|
|
|
16
16
|
* It's running on the main thread
|
|
17
17
|
*/
|
|
18
18
|
export class ConnectionManager implements IConnectionManager {
|
|
19
|
-
constructor(public instanceId: string) {
|
|
20
|
-
this._wsBroadcastChannel = new BroadcastChannel(
|
|
21
|
-
`/jupyterpack/ws/${instanceId}`
|
|
22
|
-
);
|
|
23
|
-
this._initWsChannel();
|
|
24
|
-
}
|
|
19
|
+
constructor(public instanceId: string) {}
|
|
25
20
|
|
|
26
21
|
async registerConnection(
|
|
27
|
-
|
|
22
|
+
pythonServer: IBasePythonServer
|
|
28
23
|
): Promise<{ instanceId: string; kernelClientId: string }> {
|
|
29
24
|
const uuid = UUID.uuid4();
|
|
30
25
|
|
|
31
|
-
this.
|
|
32
|
-
|
|
26
|
+
this._pythonServers.set(uuid, pythonServer);
|
|
27
|
+
const wsbc = new BroadcastChannel(
|
|
28
|
+
`/jupyterpack/ws/${this.instanceId}/${uuid}`
|
|
29
|
+
);
|
|
30
|
+
this._initWsChannel(wsbc);
|
|
31
|
+
this._wsBroadcastChannelMap.set(`${this.instanceId}/${uuid}`, wsbc);
|
|
33
32
|
return { instanceId: this.instanceId, kernelClientId: uuid };
|
|
34
33
|
}
|
|
35
34
|
|
|
@@ -43,7 +42,7 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
43
42
|
}): Promise<IDict | null> {
|
|
44
43
|
const { urlPath, kernelClientId, method, params, requestBody, headers } =
|
|
45
44
|
options;
|
|
46
|
-
const executor = this.
|
|
45
|
+
const executor = this._pythonServers.get(kernelClientId);
|
|
47
46
|
if (!executor) {
|
|
48
47
|
return null;
|
|
49
48
|
}
|
|
@@ -57,8 +56,8 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
57
56
|
});
|
|
58
57
|
return response;
|
|
59
58
|
}
|
|
60
|
-
private _initWsChannel() {
|
|
61
|
-
|
|
59
|
+
private _initWsChannel(broadcastChannel: BroadcastChannel) {
|
|
60
|
+
broadcastChannel.onmessage = event => {
|
|
62
61
|
const rawData = event.data;
|
|
63
62
|
let data: IBroadcastMessage;
|
|
64
63
|
if (typeof rawData === 'string') {
|
|
@@ -68,13 +67,13 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
const { action, dest, wsUrl, payload } = data;
|
|
71
|
-
const executor = this.
|
|
70
|
+
const executor = this._pythonServers.get(dest);
|
|
72
71
|
if (!executor) {
|
|
73
72
|
console.error(
|
|
74
73
|
'Missing kernel handle for message',
|
|
75
74
|
data,
|
|
76
75
|
dest,
|
|
77
|
-
this.
|
|
76
|
+
this._pythonServers
|
|
78
77
|
);
|
|
79
78
|
return;
|
|
80
79
|
}
|
|
@@ -89,6 +88,14 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
89
88
|
});
|
|
90
89
|
break;
|
|
91
90
|
}
|
|
91
|
+
case 'close': {
|
|
92
|
+
executor.closeWebsocket({
|
|
93
|
+
instanceId: this.instanceId,
|
|
94
|
+
kernelId: dest,
|
|
95
|
+
wsUrl
|
|
96
|
+
});
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
92
99
|
case 'send': {
|
|
93
100
|
let serializedData: string;
|
|
94
101
|
let isBinary: boolean;
|
|
@@ -97,7 +104,8 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
97
104
|
serializedData = arrayBufferToBase64(payload as any);
|
|
98
105
|
isBinary = true;
|
|
99
106
|
} else if (typeof payload === 'string') {
|
|
100
|
-
|
|
107
|
+
// convert string to base64 string to avoid encoding problem
|
|
108
|
+
serializedData = stringToBase64(payload);
|
|
101
109
|
isBinary = false;
|
|
102
110
|
} else {
|
|
103
111
|
console.error('Unknown message type', payload);
|
|
@@ -116,6 +124,6 @@ export class ConnectionManager implements IConnectionManager {
|
|
|
116
124
|
}
|
|
117
125
|
};
|
|
118
126
|
}
|
|
119
|
-
private
|
|
120
|
-
private
|
|
127
|
+
private _pythonServers = new Map<string, IBasePythonServer>();
|
|
128
|
+
private _wsBroadcastChannelMap: Map<string, BroadcastChannel> = new Map();
|
|
121
129
|
}
|
package/src/tools.ts
CHANGED
|
@@ -53,6 +53,15 @@ export function base64ToString(base64: string): string {
|
|
|
53
53
|
return new TextDecoder('utf-8').decode(bytes);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
export function stringToBase64(str: string): string {
|
|
57
|
+
const bytes = new TextEncoder().encode(str);
|
|
58
|
+
let binary = '';
|
|
59
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
60
|
+
binary += String.fromCharCode(bytes[i]);
|
|
61
|
+
}
|
|
62
|
+
return window.btoa(binary);
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
export function stringOrNone(content?: string) {
|
|
57
66
|
return content ? `"${content}"` : 'None';
|
|
58
67
|
}
|
package/src/type.ts
CHANGED
|
@@ -26,7 +26,9 @@ export enum JupyterPackFramework {
|
|
|
26
26
|
REACT = 'react',
|
|
27
27
|
DASH = 'dash',
|
|
28
28
|
STREAMLIT = 'streamlit',
|
|
29
|
-
TORNADO = 'tornado'
|
|
29
|
+
TORNADO = 'tornado',
|
|
30
|
+
SHINY = 'shiny',
|
|
31
|
+
STARLETTE = 'starlette'
|
|
30
32
|
}
|
|
31
33
|
export interface IJupyterPackFileFormat {
|
|
32
34
|
entry: string;
|
|
@@ -36,6 +38,8 @@ export interface IJupyterPackFileFormat {
|
|
|
36
38
|
autoreload?: boolean;
|
|
37
39
|
};
|
|
38
40
|
rootUrl?: string;
|
|
41
|
+
dependencies?: IDependencies;
|
|
42
|
+
disableDependencies?: boolean;
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
export enum MessageAction {
|
|
@@ -49,7 +53,15 @@ export interface IKernelExecutorParams {
|
|
|
49
53
|
params?: string;
|
|
50
54
|
requestBody?: ArrayBuffer;
|
|
51
55
|
}
|
|
56
|
+
|
|
52
57
|
export interface IKernelExecutor extends IDisposable {
|
|
58
|
+
executeCode(
|
|
59
|
+
code: KernelMessage.IExecuteRequestMsg['content'],
|
|
60
|
+
waitForResult?: boolean
|
|
61
|
+
): Promise<string | null>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface IBasePythonServer extends IDisposable {
|
|
53
65
|
getResponse(options: IKernelExecutorParams): Promise<IDict>;
|
|
54
66
|
openWebsocket(options: {
|
|
55
67
|
instanceId: string;
|
|
@@ -57,22 +69,18 @@ export interface IKernelExecutor extends IDisposable {
|
|
|
57
69
|
wsUrl: string;
|
|
58
70
|
protocol?: string;
|
|
59
71
|
}): Promise<void>;
|
|
60
|
-
|
|
72
|
+
closeWebsocket(options: {
|
|
61
73
|
instanceId: string;
|
|
62
74
|
kernelId: string;
|
|
63
75
|
wsUrl: string;
|
|
64
|
-
message: string;
|
|
65
76
|
}): Promise<void>;
|
|
66
|
-
|
|
67
|
-
code: KernelMessage.IExecuteRequestMsg['content'],
|
|
68
|
-
waitForResult?: boolean
|
|
69
|
-
): Promise<string | null>;
|
|
70
|
-
init(options: {
|
|
71
|
-
entryPath?: string;
|
|
72
|
-
initCode?: string;
|
|
77
|
+
sendWebsocketMessage(options: {
|
|
73
78
|
instanceId: string;
|
|
74
|
-
|
|
79
|
+
kernelId: string;
|
|
80
|
+
wsUrl: string;
|
|
81
|
+
message: string;
|
|
75
82
|
}): Promise<void>;
|
|
83
|
+
init(options: IPythonServerInitOptions): Promise<void>;
|
|
76
84
|
disposePythonServer(): Promise<void>;
|
|
77
85
|
reloadPythonServer(options: {
|
|
78
86
|
entryPath?: string;
|
|
@@ -89,7 +97,7 @@ export interface IKernelExecutor extends IDisposable {
|
|
|
89
97
|
|
|
90
98
|
export interface IConnectionManager {
|
|
91
99
|
registerConnection(
|
|
92
|
-
kernelExecutor:
|
|
100
|
+
kernelExecutor: IBasePythonServer
|
|
93
101
|
): Promise<{ instanceId: string; kernelClientId: string }>;
|
|
94
102
|
generateResponse(
|
|
95
103
|
option: { kernelClientId: string } & IKernelExecutorParams
|
|
@@ -114,3 +122,17 @@ export interface IPythonWidgetModel extends IDisposable {
|
|
|
114
122
|
| { success: false; error: string }
|
|
115
123
|
>;
|
|
116
124
|
}
|
|
125
|
+
|
|
126
|
+
export interface IDependencies {
|
|
127
|
+
mamba?: string[];
|
|
128
|
+
pip?: string[];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface IPythonServerInitOptions {
|
|
132
|
+
entryPath?: string;
|
|
133
|
+
initCode?: string;
|
|
134
|
+
instanceId: string;
|
|
135
|
+
kernelClientId: string;
|
|
136
|
+
dependencies?: IDependencies;
|
|
137
|
+
disableDependencies?: boolean;
|
|
138
|
+
}
|
|
@@ -59,7 +59,9 @@
|
|
|
59
59
|
}
|
|
60
60
|
return data;
|
|
61
61
|
};
|
|
62
|
-
const bcWsChannel = new BroadcastChannel(
|
|
62
|
+
const bcWsChannel = new BroadcastChannel(
|
|
63
|
+
`/jupyterpack/ws/${instanceId}/${kernelClientId}`
|
|
64
|
+
);
|
|
63
65
|
|
|
64
66
|
class BroadcastChannelWebSocket implements WebSocket {
|
|
65
67
|
constructor(url: string | URL, protocols?: string | string[]) {
|
|
@@ -109,6 +111,10 @@
|
|
|
109
111
|
cb();
|
|
110
112
|
}
|
|
111
113
|
this._eventHandlers['close'] = [];
|
|
114
|
+
sendTypedMessage({
|
|
115
|
+
action: 'close',
|
|
116
|
+
wsUrl: this.url
|
|
117
|
+
});
|
|
112
118
|
bcWsChannel.removeEventListener('message', this._bcMessageHandler);
|
|
113
119
|
|
|
114
120
|
this.readyState = this.CLOSED;
|
|
@@ -168,10 +174,12 @@
|
|
|
168
174
|
} else {
|
|
169
175
|
data = rawData;
|
|
170
176
|
}
|
|
177
|
+
|
|
171
178
|
const { action, dest, wsUrl, payload } = data;
|
|
172
179
|
if (dest !== kernelClientId || wsUrl !== this.url) {
|
|
173
180
|
return;
|
|
174
181
|
}
|
|
182
|
+
|
|
175
183
|
switch (action) {
|
|
176
184
|
case 'connected': {
|
|
177
185
|
this.readyState = this.OPEN;
|