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.
Files changed (50) hide show
  1. package/README.md +107 -3
  2. package/lib/document/widgetFactory.js +3 -1
  3. package/lib/pythonServer/baseServer.d.ts +78 -0
  4. package/lib/pythonServer/baseServer.js +175 -0
  5. package/lib/pythonServer/dash/dashServer.d.ts +4 -17
  6. package/lib/pythonServer/dash/dashServer.js +14 -22
  7. package/lib/pythonServer/dash/deps.d.ts +2 -0
  8. package/lib/pythonServer/dash/deps.js +4 -0
  9. package/lib/pythonServer/index.d.ts +3 -3
  10. package/lib/pythonServer/index.js +5 -1
  11. package/lib/pythonServer/kernelExecutor.d.ts +2 -58
  12. package/lib/pythonServer/kernelExecutor.js +0 -72
  13. package/lib/pythonServer/shiny/deps.d.ts +2 -0
  14. package/lib/pythonServer/shiny/deps.js +4 -0
  15. package/lib/pythonServer/shiny/shinyServer.d.ts +10 -0
  16. package/lib/pythonServer/shiny/shinyServer.js +54 -0
  17. package/lib/pythonServer/starlette/starletteServer.d.ts +13 -0
  18. package/lib/pythonServer/starlette/starletteServer.js +49 -0
  19. package/lib/pythonServer/streamlit/deps.d.ts +2 -0
  20. package/lib/pythonServer/streamlit/deps.js +10 -0
  21. package/lib/pythonServer/streamlit/streamlitServer.d.ts +4 -9
  22. package/lib/pythonServer/streamlit/streamlitServer.js +16 -15
  23. package/lib/pythonServer/tornado/tornadoServer.d.ts +2 -24
  24. package/lib/pythonServer/tornado/tornadoServer.js +10 -35
  25. package/lib/pythonWidget/pythonWidgetModel.js +2 -0
  26. package/lib/swConnection/mainConnectionManager.d.ts +4 -4
  27. package/lib/swConnection/mainConnectionManager.js +23 -12
  28. package/lib/tools.d.ts +1 -0
  29. package/lib/tools.js +8 -0
  30. package/lib/type.d.ts +27 -9
  31. package/lib/type.js +2 -0
  32. package/lib/websocket/websocket.js +5 -1
  33. package/package.json +1 -1
  34. package/src/document/widgetFactory.ts +3 -1
  35. package/src/pythonServer/baseServer.ts +285 -0
  36. package/src/pythonServer/dash/dashServer.ts +18 -35
  37. package/src/pythonServer/dash/deps.ts +6 -0
  38. package/src/pythonServer/index.ts +9 -5
  39. package/src/pythonServer/kernelExecutor.ts +3 -156
  40. package/src/pythonServer/shiny/deps.ts +6 -0
  41. package/src/pythonServer/shiny/shinyServer.ts +63 -0
  42. package/src/pythonServer/starlette/starletteServer.ts +59 -0
  43. package/src/pythonServer/streamlit/deps.ts +12 -0
  44. package/src/pythonServer/streamlit/streamlitServer.ts +19 -20
  45. package/src/pythonServer/tornado/tornadoServer.ts +11 -55
  46. package/src/pythonWidget/pythonWidgetModel.ts +5 -2
  47. package/src/swConnection/mainConnectionManager.ts +28 -20
  48. package/src/tools.ts +9 -0
  49. package/src/type.ts +34 -12
  50. package/src/websocket/websocket.ts +9 -1
@@ -0,0 +1,2 @@
1
+ import { IDependencies } from '../../type';
2
+ export declare const DEPENDENCIES: IDependencies;
@@ -0,0 +1,4 @@
1
+ export const DEPENDENCIES = {
2
+ mamba: [],
3
+ pip: ['shiny', 'shinychat']
4
+ };
@@ -0,0 +1,10 @@
1
+ import { IPythonServerInitOptions } from '../../type';
2
+ import { BasePythonServer } from '../baseServer';
3
+ export declare class ShinyServer extends BasePythonServer {
4
+ init(options: IPythonServerInitOptions): Promise<void>;
5
+ disposePythonServer(): Promise<void>;
6
+ reloadPythonServer(options: {
7
+ entryPath?: string;
8
+ initCode?: string;
9
+ }): Promise<void>;
10
+ }
@@ -0,0 +1,54 @@
1
+ import { JupyterPackFramework } from '../../type';
2
+ import { BasePythonServer } from '../baseServer';
3
+ import { DEPENDENCIES } from './deps';
4
+ export class ShinyServer extends BasePythonServer {
5
+ async init(options) {
6
+ const mergedOptions = {
7
+ ...options,
8
+ dependencies: this.mergeDependencies(options.dependencies, DEPENDENCIES)
9
+ };
10
+ await super.init(mergedOptions);
11
+ const { instanceId, kernelClientId, entryPath } = options;
12
+ const baseURL = this.buildBaseURL({
13
+ instanceId,
14
+ kernelClientId,
15
+ framework: JupyterPackFramework.SHINY
16
+ });
17
+ const bootstrapCode = `
18
+ from jupyterpack.common import set_base_url_env
19
+ set_base_url_env("${baseURL}")
20
+ from jupyterpack.shiny import patch_shiny
21
+ patch_shiny()
22
+ `;
23
+ await this.kernelExecutor.executeCode({ code: bootstrapCode });
24
+ if (entryPath) {
25
+ const loaderCode = `
26
+ from jupyterpack.shiny import ShinyServer, get_shiny_app
27
+
28
+
29
+ ${this._server_var} = ShinyServer(get_shiny_app("${entryPath}"), "${baseURL}")
30
+ `;
31
+ await this.kernelExecutor.executeCode({ code: loaderCode });
32
+ }
33
+ }
34
+ async disposePythonServer() {
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
+ async reloadPythonServer(options) {
43
+ const { entryPath } = options;
44
+ if (entryPath) {
45
+ const reloadCode = `
46
+ from jupyterpack.shiny import get_shiny_app
47
+
48
+ await ${this._server_var}.dispose()
49
+ ${this._server_var}.reload(get_shiny_app("${entryPath}"))
50
+ `;
51
+ await this.kernelExecutor.executeCode({ code: reloadCode }, true);
52
+ }
53
+ }
54
+ }
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ import { IDependencies } from '../../type';
2
+ export declare const DEPENDENCIES: IDependencies;
@@ -0,0 +1,10 @@
1
+ export const DEPENDENCIES = {
2
+ mamba: [
3
+ 'pyarrow',
4
+ 'altair',
5
+ 'blinker>=1.5.0,<2',
6
+ 'cachetools>=4.0,<7',
7
+ 'protobuf'
8
+ ],
9
+ pip: ['streamlit==1.50.0']
10
+ };
@@ -1,14 +1,9 @@
1
- import { TornadoServer } from '../tornado/tornadoServer';
2
- export declare class StreamlitServer extends TornadoServer {
3
- init(options: {
4
- entryPath?: string;
5
- initCode?: string;
6
- instanceId: string;
7
- kernelClientId: string;
8
- }): Promise<void>;
1
+ import { IPythonServerInitOptions } from '../../type';
2
+ import { BasePythonServer } from '../baseServer';
3
+ export declare class StreamlitServer extends BasePythonServer {
4
+ init(options: IPythonServerInitOptions): Promise<void>;
9
5
  reloadPythonServer(options: {
10
6
  entryPath?: string;
11
7
  initCode?: string;
12
8
  }): Promise<void>;
13
- protected _SERVER_VAR: string;
14
9
  }
@@ -1,11 +1,13 @@
1
1
  import { JupyterPackFramework } from '../../type';
2
- import { TornadoServer } from '../tornado/tornadoServer';
3
- export class StreamlitServer extends TornadoServer {
4
- constructor() {
5
- super(...arguments);
6
- this._SERVER_VAR = '__jupyterpack_streamlit_server';
7
- }
2
+ import { BasePythonServer } from '../baseServer';
3
+ import { DEPENDENCIES } from './deps';
4
+ export class StreamlitServer extends BasePythonServer {
8
5
  async init(options) {
6
+ const mergedOptions = {
7
+ ...options,
8
+ dependencies: this.mergeDependencies(options.dependencies, DEPENDENCIES)
9
+ };
10
+ await super.init(mergedOptions);
9
11
  const { instanceId, kernelClientId, entryPath } = options;
10
12
  if (!entryPath) {
11
13
  throw new Error('Missing streamlit entry path, please check your SPK file');
@@ -16,23 +18,22 @@ export class StreamlitServer extends TornadoServer {
16
18
  framework: JupyterPackFramework.STREAMLIT
17
19
  });
18
20
  const patchCode = `
19
- from jupyterpack.common import set_base_url_env, patch_tornado, patch_all
20
- patch_all()
21
+ from jupyterpack.common import set_base_url_env, patch_tornado
21
22
  patch_tornado()
22
23
  set_base_url_env("${baseURL}")
23
24
  `;
24
- await this.executeCode({ code: patchCode });
25
+ await this.kernelExecutor.executeCode({ code: patchCode });
25
26
  const bootstrapCode = `
26
27
  from jupyterpack.streamlit import patch_streamlit
27
28
  patch_streamlit()
28
29
  `;
29
- await this.executeCode({ code: bootstrapCode });
30
+ await this.kernelExecutor.executeCode({ code: bootstrapCode });
30
31
  const stCode = `
31
32
  from jupyterpack.streamlit import StreamlitServer, create_streamlit_app
32
33
  __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
+ ${this._server_var} = StreamlitServer(__jupyterpack_tor_app, "${baseURL}", __jupyterpack_st_server)
34
35
  `;
35
- await this.executeCode({ code: stCode });
36
+ await this.kernelExecutor.executeCode({ code: stCode });
36
37
  }
37
38
  async reloadPythonServer(options) {
38
39
  const { entryPath } = options;
@@ -40,11 +41,11 @@ export class StreamlitServer extends TornadoServer {
40
41
  return;
41
42
  }
42
43
  const reloadCode = `
43
- ${this._SERVER_VAR}.dispose()
44
+ ${this._server_var}.dispose()
44
45
  __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
+ ${this._server_var}.reload(__jupyterpack_tor_app, __jupyterpack_st_server)
46
47
  `;
47
- await this.executeCode({
48
+ await this.kernelExecutor.executeCode({
48
49
  code: reloadCode
49
50
  }, true);
50
51
  }
@@ -1,34 +1,12 @@
1
- import { IDict } from '../../type';
2
- import { KernelExecutor } from '../kernelExecutor';
3
- export declare class TornadoServer extends KernelExecutor {
1
+ import { BasePythonServer } from '../baseServer';
2
+ export declare class TornadoServer 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
- openWebsocketFunctionFactory(options: {
17
- instanceId: string;
18
- kernelId: string;
19
- wsUrl: string;
20
- protocol?: string;
21
- }): string;
22
- sendWebsocketMessageFunctionFactory(options: {
23
- instanceId: string;
24
- kernelId: string;
25
- wsUrl: string;
26
- message: string;
27
- }): string;
28
- disposePythonServer(): Promise<void>;
29
8
  reloadPythonServer(options: {
30
9
  entryPath?: string;
31
10
  initCode?: string;
32
11
  }): Promise<void>;
33
- protected _SERVER_VAR: string;
34
12
  }
@@ -1,11 +1,6 @@
1
- import { stringOrNone } from '../../tools';
2
1
  import { JupyterPackFramework } from '../../type';
3
- import { KernelExecutor } from '../kernelExecutor';
4
- export class TornadoServer extends KernelExecutor {
5
- constructor() {
6
- super(...arguments);
7
- this._SERVER_VAR = '__jupyterpack_tornado_server';
8
- }
2
+ import { BasePythonServer } from '../baseServer';
3
+ export class TornadoServer extends BasePythonServer {
9
4
  async init(options) {
10
5
  await super.init(options);
11
6
  const { initCode, instanceId, kernelClientId } = options;
@@ -20,49 +15,29 @@ export class TornadoServer extends KernelExecutor {
20
15
  patch_tornado()
21
16
 
22
17
  `;
23
- await this.executeCode({ code: bootstrapCode });
18
+ await this.kernelExecutor.executeCode({ code: bootstrapCode });
24
19
  if (initCode) {
25
20
  const initCodeWithUrl = initCode.replaceAll('{{base_url}}', baseURL);
26
- await this.executeCode({ code: initCodeWithUrl });
21
+ await this.kernelExecutor.executeCode({ code: initCodeWithUrl });
27
22
  const loaderCode = `
28
23
  from jupyterpack.tornado import TornadoServer
29
- ${this._SERVER_VAR} = TornadoServer(app, "${baseURL}")
24
+ ${this._server_var} = TornadoServer(app, "${baseURL}")
30
25
  `;
31
- await this.executeCode({ code: loaderCode });
26
+ await this.kernelExecutor.executeCode({ code: loaderCode });
32
27
  }
33
28
  }
34
- getResponseFunctionFactory(options) {
35
- const { method, urlPath, headers, params, content } = options;
36
- const code = `await ${this._SERVER_VAR}.get_response("${method}", "${urlPath}", headers=${JSON.stringify(headers)} , content=${stringOrNone(content)}, params=${stringOrNone(params)})`;
37
- return code;
38
- }
39
- openWebsocketFunctionFactory(options) {
40
- const { instanceId, kernelId, wsUrl, protocol } = options;
41
- const code = `await ${this._SERVER_VAR}.open_ws("${instanceId}", "${kernelId}", "${wsUrl}", ${stringOrNone(protocol)})`;
42
- return code;
43
- }
44
- sendWebsocketMessageFunctionFactory(options) {
45
- const { instanceId, kernelId, wsUrl, message } = options;
46
- const code = `await ${this._SERVER_VAR}.receive_ws_message("${instanceId}", "${kernelId}", "${wsUrl}", '''${message}''')`;
47
- return code;
48
- }
49
- async disposePythonServer() {
50
- await this.executeCode({
51
- code: `${this._SERVER_VAR}.dispose()`
52
- });
53
- }
54
29
  async reloadPythonServer(options) {
55
30
  var _a;
56
31
  const { initCode } = options;
57
32
  if (initCode) {
58
- await this.executeCode({
33
+ await this.kernelExecutor.executeCode({
59
34
  code: initCode.replaceAll('{{base_url}}', (_a = this._baseUrl) !== null && _a !== void 0 ? _a : '')
60
35
  });
61
36
  const reloadCode = `
62
- ${this._SERVER_VAR}.dispose()
63
- ${this._SERVER_VAR}.reload(app)
37
+ ${this._server_var}.dispose()
38
+ ${this._server_var}.reload(app)
64
39
  `;
65
- await this.executeCode({ code: reloadCode }, true);
40
+ await this.kernelExecutor.executeCode({ code: reloadCode }, true);
66
41
  }
67
42
  }
68
43
  }
@@ -109,6 +109,8 @@ export class PythonWidgetModel {
109
109
  await executor.init({
110
110
  initCode: entryContent.content,
111
111
  entryPath: spkContent.entry,
112
+ dependencies: spkContent.dependencies,
113
+ disableDependencies: spkContent.disableDependencies,
112
114
  ...data
113
115
  });
114
116
  const finish = new PromiseDelegate();
@@ -1,4 +1,4 @@
1
- import { IConnectionManager, IDict, IKernelExecutor } from '../type';
1
+ import { IBasePythonServer, IConnectionManager, IDict } from '../type';
2
2
  /**
3
3
  * Manages connections between clients and kernel executors.
4
4
  * This class handles the registration of kernel executors and the generation of responses
@@ -10,7 +10,7 @@ import { IConnectionManager, IDict, IKernelExecutor } from '../type';
10
10
  export declare class ConnectionManager implements IConnectionManager {
11
11
  instanceId: string;
12
12
  constructor(instanceId: string);
13
- registerConnection(kernelExecutor: IKernelExecutor): Promise<{
13
+ registerConnection(pythonServer: IBasePythonServer): Promise<{
14
14
  instanceId: string;
15
15
  kernelClientId: string;
16
16
  }>;
@@ -23,6 +23,6 @@ export declare class ConnectionManager implements IConnectionManager {
23
23
  params?: string;
24
24
  }): Promise<IDict | null>;
25
25
  private _initWsChannel;
26
- private _kernelExecutors;
27
- private _wsBroadcastChannel;
26
+ private _pythonServers;
27
+ private _wsBroadcastChannelMap;
28
28
  }
@@ -1,4 +1,4 @@
1
- import { arrayBufferToBase64 } from '../tools';
1
+ import { arrayBufferToBase64, stringToBase64 } from '../tools';
2
2
  import { UUID } from '@lumino/coreutils';
3
3
  /**
4
4
  * Manages connections between clients and kernel executors.
@@ -11,18 +11,20 @@ import { UUID } from '@lumino/coreutils';
11
11
  export class ConnectionManager {
12
12
  constructor(instanceId) {
13
13
  this.instanceId = instanceId;
14
- this._kernelExecutors = new Map();
15
- this._wsBroadcastChannel = new BroadcastChannel(`/jupyterpack/ws/${instanceId}`);
16
- this._initWsChannel();
14
+ this._pythonServers = new Map();
15
+ this._wsBroadcastChannelMap = new Map();
17
16
  }
18
- async registerConnection(kernelExecutor) {
17
+ async registerConnection(pythonServer) {
19
18
  const uuid = UUID.uuid4();
20
- this._kernelExecutors.set(uuid, kernelExecutor);
19
+ this._pythonServers.set(uuid, pythonServer);
20
+ const wsbc = new BroadcastChannel(`/jupyterpack/ws/${this.instanceId}/${uuid}`);
21
+ this._initWsChannel(wsbc);
22
+ this._wsBroadcastChannelMap.set(`${this.instanceId}/${uuid}`, wsbc);
21
23
  return { instanceId: this.instanceId, kernelClientId: uuid };
22
24
  }
23
25
  async generateResponse(options) {
24
26
  const { urlPath, kernelClientId, method, params, requestBody, headers } = options;
25
- const executor = this._kernelExecutors.get(kernelClientId);
27
+ const executor = this._pythonServers.get(kernelClientId);
26
28
  if (!executor) {
27
29
  return null;
28
30
  }
@@ -35,8 +37,8 @@ export class ConnectionManager {
35
37
  });
36
38
  return response;
37
39
  }
38
- _initWsChannel() {
39
- this._wsBroadcastChannel.onmessage = event => {
40
+ _initWsChannel(broadcastChannel) {
41
+ broadcastChannel.onmessage = event => {
40
42
  const rawData = event.data;
41
43
  let data;
42
44
  if (typeof rawData === 'string') {
@@ -46,9 +48,9 @@ export class ConnectionManager {
46
48
  data = rawData;
47
49
  }
48
50
  const { action, dest, wsUrl, payload } = data;
49
- const executor = this._kernelExecutors.get(dest);
51
+ const executor = this._pythonServers.get(dest);
50
52
  if (!executor) {
51
- console.error('Missing kernel handle for message', data, dest, this._kernelExecutors);
53
+ console.error('Missing kernel handle for message', data, dest, this._pythonServers);
52
54
  return;
53
55
  }
54
56
  switch (action) {
@@ -61,6 +63,14 @@ export class ConnectionManager {
61
63
  });
62
64
  break;
63
65
  }
66
+ case 'close': {
67
+ executor.closeWebsocket({
68
+ instanceId: this.instanceId,
69
+ kernelId: dest,
70
+ wsUrl
71
+ });
72
+ break;
73
+ }
64
74
  case 'send': {
65
75
  let serializedData;
66
76
  let isBinary;
@@ -70,7 +80,8 @@ export class ConnectionManager {
70
80
  isBinary = true;
71
81
  }
72
82
  else if (typeof payload === 'string') {
73
- serializedData = payload;
83
+ // convert string to base64 string to avoid encoding problem
84
+ serializedData = stringToBase64(payload);
74
85
  isBinary = false;
75
86
  }
76
87
  else {
package/lib/tools.d.ts CHANGED
@@ -7,5 +7,6 @@ export declare function removePrefix(path: string, prefix: string): string;
7
7
  export declare function arrayBufferToBase64(buffer: ArrayBuffer): string;
8
8
  export declare function base64ToArrayBuffer(base64: string): Uint8Array;
9
9
  export declare function base64ToString(base64: string): string;
10
+ export declare function stringToBase64(str: string): string;
10
11
  export declare function stringOrNone(content?: string): string;
11
12
  export declare function isBinaryContentType(contentType?: string): boolean;
package/lib/tools.js CHANGED
@@ -44,6 +44,14 @@ export function base64ToString(base64) {
44
44
  const bytes = base64ToArrayBuffer(base64);
45
45
  return new TextDecoder('utf-8').decode(bytes);
46
46
  }
47
+ export function stringToBase64(str) {
48
+ const bytes = new TextEncoder().encode(str);
49
+ let binary = '';
50
+ for (let i = 0; i < bytes.length; i++) {
51
+ binary += String.fromCharCode(bytes[i]);
52
+ }
53
+ return window.btoa(binary);
54
+ }
47
55
  export function stringOrNone(content) {
48
56
  return content ? `"${content}"` : 'None';
49
57
  }
package/lib/type.d.ts CHANGED
@@ -16,7 +16,9 @@ export declare enum JupyterPackFramework {
16
16
  REACT = "react",
17
17
  DASH = "dash",
18
18
  STREAMLIT = "streamlit",
19
- TORNADO = "tornado"
19
+ TORNADO = "tornado",
20
+ SHINY = "shiny",
21
+ STARLETTE = "starlette"
20
22
  }
21
23
  export interface IJupyterPackFileFormat {
22
24
  entry: string;
@@ -26,6 +28,8 @@ export interface IJupyterPackFileFormat {
26
28
  autoreload?: boolean;
27
29
  };
28
30
  rootUrl?: string;
31
+ dependencies?: IDependencies;
32
+ disableDependencies?: boolean;
29
33
  }
30
34
  export declare enum MessageAction {
31
35
  INIT = "INIT"
@@ -38,6 +42,9 @@ export interface IKernelExecutorParams {
38
42
  requestBody?: ArrayBuffer;
39
43
  }
40
44
  export interface IKernelExecutor extends IDisposable {
45
+ executeCode(code: KernelMessage.IExecuteRequestMsg['content'], waitForResult?: boolean): Promise<string | null>;
46
+ }
47
+ export interface IBasePythonServer extends IDisposable {
41
48
  getResponse(options: IKernelExecutorParams): Promise<IDict>;
42
49
  openWebsocket(options: {
43
50
  instanceId: string;
@@ -45,19 +52,18 @@ export interface IKernelExecutor extends IDisposable {
45
52
  wsUrl: string;
46
53
  protocol?: string;
47
54
  }): Promise<void>;
48
- sendWebsocketMessage(options: {
55
+ closeWebsocket(options: {
49
56
  instanceId: string;
50
57
  kernelId: string;
51
58
  wsUrl: string;
52
- message: string;
53
59
  }): Promise<void>;
54
- executeCode(code: KernelMessage.IExecuteRequestMsg['content'], waitForResult?: boolean): Promise<string | null>;
55
- init(options: {
56
- entryPath?: string;
57
- initCode?: string;
60
+ sendWebsocketMessage(options: {
58
61
  instanceId: string;
59
- kernelClientId: string;
62
+ kernelId: string;
63
+ wsUrl: string;
64
+ message: string;
60
65
  }): Promise<void>;
66
+ init(options: IPythonServerInitOptions): Promise<void>;
61
67
  disposePythonServer(): Promise<void>;
62
68
  reloadPythonServer(options: {
63
69
  entryPath?: string;
@@ -72,7 +78,7 @@ export interface IKernelExecutor extends IDisposable {
72
78
  }): string;
73
79
  }
74
80
  export interface IConnectionManager {
75
- registerConnection(kernelExecutor: IKernelExecutor): Promise<{
81
+ registerConnection(kernelExecutor: IBasePythonServer): Promise<{
76
82
  instanceId: string;
77
83
  kernelClientId: string;
78
84
  }>;
@@ -97,3 +103,15 @@ export interface IPythonWidgetModel extends IDisposable {
97
103
  error: string;
98
104
  }>;
99
105
  }
106
+ export interface IDependencies {
107
+ mamba?: string[];
108
+ pip?: string[];
109
+ }
110
+ export interface IPythonServerInitOptions {
111
+ entryPath?: string;
112
+ initCode?: string;
113
+ instanceId: string;
114
+ kernelClientId: string;
115
+ dependencies?: IDependencies;
116
+ disableDependencies?: boolean;
117
+ }
package/lib/type.js CHANGED
@@ -4,6 +4,8 @@ export var JupyterPackFramework;
4
4
  JupyterPackFramework["DASH"] = "dash";
5
5
  JupyterPackFramework["STREAMLIT"] = "streamlit";
6
6
  JupyterPackFramework["TORNADO"] = "tornado";
7
+ JupyterPackFramework["SHINY"] = "shiny";
8
+ JupyterPackFramework["STARLETTE"] = "starlette";
7
9
  })(JupyterPackFramework || (JupyterPackFramework = {}));
8
10
  export var MessageAction;
9
11
  (function (MessageAction) {
@@ -36,7 +36,7 @@
36
36
  }
37
37
  return data;
38
38
  };
39
- const bcWsChannel = new BroadcastChannel(`/jupyterpack/ws/${instanceId}`);
39
+ const bcWsChannel = new BroadcastChannel(`/jupyterpack/ws/${instanceId}/${kernelClientId}`);
40
40
  class BroadcastChannelWebSocket {
41
41
  constructor(url, protocols) {
42
42
  this.onclose = () => {
@@ -128,6 +128,10 @@
128
128
  cb();
129
129
  }
130
130
  this._eventHandlers['close'] = [];
131
+ sendTypedMessage({
132
+ action: 'close',
133
+ wsUrl: this.url
134
+ });
131
135
  bcWsChannel.removeEventListener('message', this._bcMessageHandler);
132
136
  this.readyState = this.CLOSED;
133
137
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyterpack",
3
- "version": "0.4.0",
3
+ "version": "0.5.2",
4
4
  "description": "A JupyterLab extension for serving web app.",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -54,7 +54,9 @@ export class JupyterPackWidgetFactory extends ABCWidgetFactory<JupyterPackDocWid
54
54
  }
55
55
  case JupyterPackFramework.DASH:
56
56
  case JupyterPackFramework.STREAMLIT:
57
- case JupyterPackFramework.TORNADO: {
57
+ case JupyterPackFramework.TORNADO:
58
+ case JupyterPackFramework.STARLETTE:
59
+ case JupyterPackFramework.SHINY: {
58
60
  const model = new PythonWidgetModel({
59
61
  jpackModel,
60
62
  context,