jupyterpack 0.5.6 → 0.6.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 (63) hide show
  1. package/README.md +246 -111
  2. package/lib/document/plugin.js +19 -4
  3. package/lib/document/spkButton.d.ts +9 -0
  4. package/lib/document/spkButton.js +22 -0
  5. package/lib/document/templates/gradio.d.ts +1 -0
  6. package/lib/document/templates/gradio.js +19 -0
  7. package/lib/document/templates/index.js +15 -0
  8. package/lib/document/templates/mesop.d.ts +1 -0
  9. package/lib/document/templates/mesop.js +23 -0
  10. package/lib/document/templates/nicegui.d.ts +1 -0
  11. package/lib/document/templates/nicegui.js +36 -0
  12. package/lib/document/widgetFactory.js +20 -1
  13. package/lib/pythonServer/baseServer.d.ts +4 -1
  14. package/lib/pythonServer/baseServer.js +1 -1
  15. package/lib/pythonServer/dash/dashServer.js +2 -1
  16. package/lib/pythonServer/gradio/deps.d.ts +2 -0
  17. package/lib/pythonServer/gradio/deps.js +13 -0
  18. package/lib/pythonServer/gradio/gradioServer.d.ts +10 -0
  19. package/lib/pythonServer/gradio/gradioServer.js +48 -0
  20. package/lib/pythonServer/index.js +7 -1
  21. package/lib/pythonServer/mesop/deps.d.ts +2 -0
  22. package/lib/pythonServer/mesop/deps.js +4 -0
  23. package/lib/pythonServer/mesop/mesopServer.d.ts +10 -0
  24. package/lib/pythonServer/mesop/mesopServer.js +37 -0
  25. package/lib/pythonServer/nicegui/deps.d.ts +2 -0
  26. package/lib/pythonServer/nicegui/deps.js +4 -0
  27. package/lib/pythonServer/nicegui/niceguiServer.d.ts +14 -0
  28. package/lib/pythonServer/nicegui/niceguiServer.js +69 -0
  29. package/lib/pythonServer/shiny/shinyServer.js +2 -3
  30. package/lib/pythonServer/starlette/starletteServer.js +2 -1
  31. package/lib/pythonServer/vizro/vizroServer.d.ts +2 -0
  32. package/lib/pythonServer/vizro/vizroServer.js +10 -6
  33. package/lib/pythonWidget/pythonWidgetModel.js +5 -3
  34. package/lib/tools.d.ts +5 -1
  35. package/lib/tools.js +33 -0
  36. package/lib/type.d.ts +8 -3
  37. package/lib/type.js +3 -0
  38. package/package.json +2 -1
  39. package/src/document/plugin.ts +24 -3
  40. package/src/document/spkButton.ts +34 -0
  41. package/src/document/templates/gradio.ts +19 -0
  42. package/src/document/templates/index.ts +15 -0
  43. package/src/document/templates/mesop.ts +23 -0
  44. package/src/document/templates/nicegui.ts +36 -0
  45. package/src/document/widgetFactory.ts +20 -2
  46. package/src/pythonServer/baseServer.ts +4 -1
  47. package/src/pythonServer/dash/dashServer.ts +2 -1
  48. package/src/pythonServer/gradio/deps.ts +14 -0
  49. package/src/pythonServer/gradio/gradioServer.ts +53 -0
  50. package/src/pythonServer/index.ts +7 -1
  51. package/src/pythonServer/mesop/deps.ts +6 -0
  52. package/src/pythonServer/mesop/mesopServer.ts +43 -0
  53. package/src/pythonServer/nicegui/deps.ts +5 -0
  54. package/src/pythonServer/nicegui/niceguiServer.ts +79 -0
  55. package/src/pythonServer/shiny/shinyServer.ts +2 -3
  56. package/src/pythonServer/starlette/starletteServer.ts +2 -2
  57. package/src/pythonServer/vizro/vizroServer.ts +10 -4
  58. package/src/pythonWidget/pythonWidgetModel.ts +5 -2
  59. package/src/tools.ts +40 -1
  60. package/src/type.ts +8 -3
  61. package/style/icons/gradio.svg +24 -0
  62. package/style/icons/mesop.svg +9 -0
  63. package/style/icons/nicegui.svg +26 -0
package/README.md CHANGED
@@ -21,14 +21,15 @@
21
21
  - [**Textual**](https://github.com/Textualize/textual)
22
22
  - [**Vizro**](https://github.com/mckinsey/vizro)
23
23
  - [**FastHTML**](https://github.com/AnswerDotAI/fasthtml)
24
+ - [**Gradio**](https://github.com/gradio-app/gradio)
25
+ - [**Mesop**](https://github.com/mesop-dev/mesop)
26
+ - [**NiceGUI**](https://github.com/zauberzeug/nicegui)
24
27
 
25
- You can also use `jupyterpack` to serve any [**Flask**](https://github.com/pallets/flask), [**Starlette**](https://github.com/Kludex/starlette) or [**Tornado**](https://github.com/tornadoweb/tornado) application.
28
+ You can also use `jupyterpack` to serve any [**Flask**](https://github.com/pallets/flask), [**Starlette**](https://github.com/Kludex/starlette) or [**Tornado**](https://github.com/tornadoweb/tornado) application. Example of each framework can be found in the [demo](https://github.com/trungleduc/jupyterpack/tree/main/demo/files) folder.
26
29
 
27
30
  - **JavaScript Web Apps**: Bundle and serve JavaScript web applications using in-browser bundlers.
28
31
 
29
- Example of each framework can be found in the [demo](https://github.com/trungleduc/jupyterpack/tree/main/demo/files) folder.
30
-
31
- - ** Direct link to your app**: Share your app with others by generating a direct link to your app. This link can be shared with anyone and will open your app in the browser (see the [toolbar buttons](https://github.com/trungleduc/jupyterpack/edit/main/README.md#toolbar-buttons)).
32
+ - **Direct link to your app**: Share your app with others by generating a direct link to your app. This link can be shared with anyone and will open your app in the browser (see the [toolbar buttons](https://github.com/trungleduc/jupyterpack/edit/main/README.md#toolbar-buttons)).
32
33
 
33
34
  ## Installation
34
35
 
@@ -52,121 +53,39 @@ You can try it online by clicking on this badge:
52
53
 
53
54
  `jupyterpack` currently supports only `xeus-python` kernel and does **not** support `pyodide-kernel`. You can refer to the `xeus-python` [official documentation](https://jupyterlite-xeus.readthedocs.io/en/stable/deploy.html) for the base setup of JupyterLite with `xeus-python` kernel.
54
55
 
55
- ### Framework-specific setup
56
-
57
- At runtime, `jupyterpack` can automatically install the dependencies required by the supported frameworks.
58
- Alternatively, you can preinstall framework dependencies directly into your JupyterLite build. When dependencies are preinstalled, runtime installation can be skipped by setting `disableDependencies` to `true` in your `.spk` file.
56
+ ## Usage
59
57
 
60
- Below are example environment.yml files for each supported framework.
58
+ ### Using shebang in python script
61
59
 
62
- - **Dash**
60
+ You can use `jupyterpack` to run your application script by adding the following shebang to the top of your Python script:
63
61
 
64
- ```yaml
65
- name: xeus-kernels
66
- channels:
67
- - https://repo.prefix.dev/emscripten-forge-dev
68
- - https://repo.prefix.dev/conda-forge
69
- dependencies:
70
- - xeus-python
71
- - jupyterpack
72
- - dash
73
- - werkzeug>=2.2,<3.0
74
- - blinker>=1.5.0,<2
75
- - cachetools>=4.0,<7
76
- - pip:
77
- - pyodide_http
78
62
  ```
79
-
80
- - **Streamlit**
81
-
82
- ```yaml
83
- name: xeus-kernels
84
- channels:
85
- - https://repo.prefix.dev/emscripten-forge-dev
86
- - https://repo.prefix.dev/conda-forge
87
- dependencies:
88
- - xeus-python
89
- - jupyterpack
90
- - blinker>=1.5.0,<2
91
- - cachetools>=4.0,<7
92
- - protobuf
93
- - altair
94
- - pyarrow
95
- - pip:
96
- - streamlit>=1.50.0
97
- - pyodide_http
63
+ #! jupyterpack.<name-of-the-used-framework>
98
64
  ```
99
65
 
100
- - **Shiny**
66
+ The available shebang options are:
101
67
 
102
- ```yaml
103
- name: xeus-kernels
104
- channels:
105
- - https://repo.prefix.dev/emscripten-forge-dev
106
- - https://repo.prefix.dev/conda-forge
107
- dependencies:
108
- - xeus-python
109
- - jupyterpack
110
- - pip:
111
- - shiny
112
- - shinychat
113
- - pyodide_http
114
- ```
68
+ - `#! jupyterpack.dash` for Dash
69
+ - `#! jupyterpack.streamlit` for Streamlit
70
+ - `#! jupyterpack.panel` for Panel
71
+ - `#! jupyterpack.shiny` for Shiny
72
+ - `#! jupyterpack.textual` for Textual
73
+ - `#! jupyterpack.vizro` for Vizro
74
+ - `#! jupyterpack.fasthtml` for Fasthtml
75
+ - `#! jupyterpack.gradio` for Gradio
76
+ - `#! jupyterpack.mesop` for Mesop
77
+ - `#! jupyterpack.nicegui` for NiceGUI
115
78
 
116
- - **Panel**
79
+ After adding the shebang, you have two options to run your application:
117
80
 
118
- ```yaml
119
- name: xeus-kernels
120
- channels:
121
- - https://repo.prefix.dev/emscripten-forge-dev
122
- - https://repo.prefix.dev/conda-forge
123
- dependencies:
124
- - xeus-python
125
- - jupyterpack
126
- - panel
127
- - pip:
128
- - pyodide_http
129
- ```
81
+ 1. **Open from file browser**: Right-click the Python file in JupyterLab and select `Open with` > `Jupyterpack`.
82
+ 2. **Using toolbar buttons**: Open the Python file using the `Editor` then click on `Open with Jupyterpack` button in the toolbar.
130
83
 
131
- - **Texual**
84
+ ### Using a `.spk` file
132
85
 
133
- ```yaml
134
- name: xeus-kernels
135
- channels:
136
- - https://repo.prefix.dev/emscripten-forge-dev
137
- - https://repo.prefix.dev/conda-forge
138
- dependencies:
139
- - xeus-python
140
- - jupyterpack
141
- - textual
142
- - textual-serve
143
- - pip:
144
- - pyodide_http
145
- ```
86
+ Instead of using a shebang, you can create a `.spk` file to define your application. Using a `spk` file is useful when you want to specify additional configurations or dependencies for your application.
146
87
 
147
- - **Vizro**
148
-
149
- ```yaml
150
- name: xeus-kernels
151
- channels:
152
- - https://repo.prefix.dev/emscripten-forge-dev
153
- - https://repo.prefix.dev/conda-forge
154
- dependencies:
155
- - xeus-python
156
- - jupyterpack
157
- - werkzeug>=2.2,<3.0
158
- - blinker>=1.5.0,<2
159
- - cachetools>=4.0,<7
160
- - vizro
161
- - pip:
162
- - pyodide_http
163
- ```
164
-
165
- ## Usage
166
-
167
- ### Create a `.spk` file
168
-
169
- To use `jupyterpack`, you need to create a `.spk` file that defines your web application. Here's an example structure of a React application:
88
+ Here's an example structure of a React application:
170
89
 
171
90
  ```bash
172
91
  my_app/
@@ -283,6 +202,10 @@ interface IJupyterPackFileFormat {
283
202
 
284
203
  ## Framework-specific configurations
285
204
 
205
+ Each framework requires specific setup and runtime configuration. This section covers framework-specific requirements and how `Jupyterpack` handles dependencies.
206
+
207
+ By default, `Jupyterpack` automatically installs framework dependencies at runtime when you run your application. However, you can optimize startup time by preinstalling dependencies directly into your JupyterLite build. When dependencies are preinstalled, disable automatic installation by setting `disableDependencies: true` in your `.spk` file.
208
+
286
209
  ### Dash application
287
210
 
288
211
  Same as the React application, here is the structure of a Dash application:
@@ -308,12 +231,50 @@ Do **not** call `app.run_server()` yourself — `jupyterpack` is responsible for
308
231
 
309
232
  As with React applications, double-clicking the `.spk` file will open the Dash app in a new JupyterLab tab.
310
233
 
234
+ Here is the environment file for Dash applications:
235
+
236
+ ```yaml
237
+ name: xeus-kernels
238
+ channels:
239
+ - https://repo.prefix.dev/emscripten-forge-dev
240
+ - https://repo.prefix.dev/conda-forge
241
+ dependencies:
242
+ - xeus-python
243
+ - jupyterpack
244
+ - dash
245
+ - werkzeug>=2.2,<3.0
246
+ - blinker>=1.5.0,<2
247
+ - cachetools>=4.0,<7
248
+ - pip:
249
+ - pyodide_http
250
+ ```
251
+
311
252
  ### Streamlit application
312
253
 
313
- There is no special requirement for Streamlit applications, just write your code as a standard Streamlit application and do **not** start the server manually — `jupyterpack` will handle execution and serving automatically.
254
+ There are no special requirements for Streamlit applications, just write your code as a standard Streamlit application and do **not** start the server manually — `jupyterpack` will handle execution and serving automatically.
314
255
 
315
256
  Opening the `.spk` file will launch the Streamlit app in a new JupyterLab tab.
316
257
 
258
+ Since `streamlit` can't be installed using `conda`, you need to install in in the `pip` section. Here is the environment file for Streamlit applications:
259
+
260
+ ```yaml
261
+ name: xeus-kernels
262
+ channels:
263
+ - https://repo.prefix.dev/emscripten-forge-dev
264
+ - https://repo.prefix.dev/conda-forge
265
+ dependencies:
266
+ - xeus-python
267
+ - jupyterpack
268
+ - blinker>=1.5.0,<2
269
+ - cachetools>=4.0,<7
270
+ - protobuf
271
+ - altair
272
+ - pyarrow
273
+ - pip:
274
+ - streamlit>=1.50.0
275
+ - pyodide_http
276
+ ```
277
+
317
278
  ### Shiny application
318
279
 
319
280
  `jupyterpack` supports both **Shiny Express** and **Shiny Core** applications.
@@ -323,21 +284,195 @@ Opening the `.spk` file will launch the Streamlit app in a new JupyterLab tab.
323
284
 
324
285
  In both cases, the server is managed by `jupyterpack`, and opening the `.spk` file will launch the app in JupyterLab.
325
286
 
287
+ Here is the environment file for Shiny applications:
288
+
289
+ ```yaml
290
+ name: xeus-kernels
291
+ channels:
292
+ - https://repo.prefix.dev/emscripten-forge-dev
293
+ - https://repo.prefix.dev/conda-forge
294
+ dependencies:
295
+ - xeus-python
296
+ - jupyterpack
297
+ - pip:
298
+ - shiny
299
+ - shinychat
300
+ - pyodide_http
301
+ ```
302
+
326
303
  ### Panel application
327
304
 
328
- There is no special requirement for Panel applications, just write your code as a standard Panel application and call `.servable()` on the layout you want to serve.
305
+ There are no special requirements for Panel applications, just write your code as a standard Panel application and call `.servable()` on the layout you want to serve.
306
+
307
+ Here is the environment file for Panel applications:
308
+
309
+ ```yaml
310
+ name: xeus-kernels
311
+ channels:
312
+ - https://repo.prefix.dev/emscripten-forge-dev
313
+ - https://repo.prefix.dev/conda-forge
314
+ dependencies:
315
+ - xeus-python
316
+ - jupyterpack
317
+ - panel
318
+ - pip:
319
+ - pyodide_http
320
+ ```
329
321
 
330
322
  ### Textual application
331
323
 
332
324
  You must define your Textual application as a variable named `app` and do not call `app.run()` yourself — `jupyterpack` is responsible for starting and managing the server lifecycle.
333
325
 
326
+ Here is the environment file for Textual applications:
327
+
328
+ ```yaml
329
+ name: xeus-kernels
330
+ channels:
331
+ - https://repo.prefix.dev/emscripten-forge-dev
332
+ - https://repo.prefix.dev/conda-forge
333
+ dependencies:
334
+ - xeus-python
335
+ - jupyterpack
336
+ - textual
337
+ - textual-serve
338
+ - pip:
339
+ - pyodide_http
340
+ ```
341
+
334
342
  ### Vizro application
335
343
 
336
- There is no special requirement for Vizro applications, just write your code as a standard Vizro application and call `Vizro().build(...).run()` to serve your dashboard.
344
+ There are no special requirements for Vizro applications, just write your code as a standard Vizro application and call `Vizro().build(...).run()` to serve your dashboard.
345
+
346
+ Here is the environment file for Vizro applications:
347
+
348
+ ```yaml
349
+ name: xeus-kernels
350
+ channels:
351
+ - https://repo.prefix.dev/emscripten-forge-dev
352
+ - https://repo.prefix.dev/conda-forge
353
+ dependencies:
354
+ - xeus-python
355
+ - jupyterpack
356
+ - werkzeug>=2.2,<3.0
357
+ - blinker>=1.5.0,<2
358
+ - cachetools>=4.0,<7
359
+ - vizro
360
+ - pip:
361
+ - pyodide_http
362
+ ```
337
363
 
338
364
  ### FastHTML application
339
365
 
340
- JupyterPack only supports async handlers with FastHTML. You must convert all synchronous handlers to async, and you should not call `serve()` yourself — jupyterpack is responsible for starting and managing the server lifecycle.
366
+ There are no special requirements for FastHTML applications, just write your code as a standard FastHTML application. You should not call `serve()` yourself — jupyterpack is responsible for starting and managing the server lifecycle.
367
+ Here is the environment file for FastHTML applications:
368
+
369
+ ```yaml
370
+ name: xeus-kernels
371
+ channels:
372
+ - https://repo.prefix.dev/emscripten-forge-dev
373
+ - https://repo.prefix.dev/conda-forge
374
+ dependencies:
375
+ - xeus-python
376
+ - jupyterpack
377
+ - fastapi
378
+ - fastcore
379
+ - fastlite
380
+ - itsdangerous
381
+ - oauthlib
382
+ - beautifulsoup4
383
+ - pip:
384
+ - python-fasthtml
385
+ - uvicorn
386
+ - pyodide_http
387
+ ```
388
+
389
+ ### Gradio application
390
+
391
+ There are no special requirements for Gradio applications, just write your code as a standard Vizro application and call the `launch` method to serve your dashboard.
392
+
393
+ Due to the setup of Gradio, you need to put `gradio` and `gradio-client` in the pip section of the `environment.yml` file. For the remaininng dependencies, they are handled by `jupyterpack` automatically, but you can also specify them in the `environment.yml` file to improve the loading time. Here is the example of the `environment.yml` file for Gradio.
394
+ Here is the environment file for Gradio applications:
395
+
396
+ ```yaml
397
+ name: xeus-kernels
398
+ channels:
399
+ - https://repo.prefix.dev/emscripten-forge-dev
400
+ - https://repo.prefix.dev/conda-forge
401
+ dependencies:
402
+ - xeus-python
403
+ - jupyterpack
404
+ - fastapi
405
+ - pillow
406
+ - huggingface_hub
407
+ - aiofiles
408
+ - safehttpx
409
+ - semantic_version
410
+ - pydub
411
+ - tomlkit
412
+ - pip:
413
+ - gradio
414
+ - gradio-client
415
+ - pyodide_http
416
+ ```
417
+
418
+ ### Mesop application
419
+
420
+ There are no special requirements for Mesop applications. Just write your code as a standard Mesop application, and opening the `.spk` file will launch the app in JupyterLab.
421
+
422
+ Since Mesop is not available in the conda-forge channel. You need to install it via pip.
423
+ Here is the environment file for Mesop applications:
424
+
425
+ ```yaml
426
+ name: xeus-kernels
427
+ channels:
428
+ - https://repo.prefix.dev/emscripten-forge-dev
429
+ - https://repo.prefix.dev/conda-forge
430
+ dependencies:
431
+ - xeus-python
432
+ - jupyterpack
433
+ - flask
434
+ - absl-py
435
+ - deepdiff>=8.6.1,<9
436
+ - msgpack
437
+ - pydantic
438
+ - python-dotenv
439
+ - sqlalchemy
440
+ - pip:
441
+ - mesop
442
+ - flask-sock
443
+ - pyodide_http
444
+ ```
445
+
446
+ ### NiceGUI application
447
+
448
+ There are no special requirements for NiceGUI applications. Jupyterpack supports creating pages using the page decorator, root function and script mode.
449
+
450
+ Due to the setup of NiceGUI, you need to include it into the `pip` section of the environment file. Here is an example environment file for NiceGUI applications:
451
+
452
+ ```yaml
453
+ name: xeus-kernels
454
+ channels:
455
+ - https://repo.prefix.dev/emscripten-forge-dev
456
+ - https://repo.prefix.dev/conda-forge
457
+ dependencies:
458
+ - xeus-python
459
+ - jupyterpack
460
+ - python-multipart
461
+ - python-socketio
462
+ - pydantic >=1.10.21,<3.0
463
+ - fastapi
464
+ - rich
465
+ - markdown2
466
+ - itsdangerous
467
+ - ifaddr
468
+ - jinja2
469
+ - docutils
470
+ - vbuild
471
+ - wait_for2
472
+ - pip:
473
+ - nicegui
474
+ - pyodide_http
475
+ ```
341
476
 
342
477
  ## License
343
478
 
@@ -2,14 +2,16 @@ import { WidgetTracker } from '@jupyterlab/apputils';
2
2
  import { ILauncher } from '@jupyterlab/launcher';
3
3
  import { IDocumentManager } from '@jupyterlab/docmanager';
4
4
  import { IConnectionManagerToken, IJupyterpackDocTrackerToken } from '../token';
5
- import { dashIcon, decodeSpk, fasthtmlIcon, logoIcon, panelIcon, shinyIcon, streamlitIcon, textualIcon, vizroIcon } from '../tools';
5
+ import { dashIcon, decodeSpk, fasthtmlIcon, gradioIcon, logoIcon, mesopIcon, niceguiIcon, panelIcon, shinyIcon, streamlitIcon, textualIcon, vizroIcon } from '../tools';
6
6
  import { JupyterPackFramework } from '../type';
7
7
  import { addCommands, addLauncherCommands } from './commands';
8
8
  import { JupyterPackWidgetFactory } from './widgetFactory';
9
9
  import { spkFactory } from './templates/spk';
10
10
  import { newFile } from './templates';
11
+ import { SpkButtonExtention } from './spkButton';
11
12
  const FACTORY = 'jupyterpack';
12
13
  const CONTENT_TYPE = 'jupyterpack';
14
+ const PY_CONTENT_TYPE = 'jupyterpack-py';
13
15
  export const spkPlugin = {
14
16
  id: 'jupyterpack:spkplugin',
15
17
  requires: [IConnectionManagerToken],
@@ -23,7 +25,7 @@ export const spkPlugin = {
23
25
  const widgetFactory = new JupyterPackWidgetFactory({
24
26
  name: FACTORY,
25
27
  modelName: 'text',
26
- fileTypes: [CONTENT_TYPE],
28
+ fileTypes: [CONTENT_TYPE, PY_CONTENT_TYPE],
27
29
  defaultFor: [CONTENT_TYPE],
28
30
  commands: app.commands,
29
31
  manager: app.serviceManager,
@@ -42,6 +44,15 @@ export const spkPlugin = {
42
44
  contentType: CONTENT_TYPE,
43
45
  icon: logoIcon
44
46
  });
47
+ app.docRegistry.addFileType({
48
+ name: PY_CONTENT_TYPE,
49
+ displayName: 'PY',
50
+ mimeTypes: ['text/x-python'],
51
+ extensions: ['.py', '.PY'],
52
+ fileFormat: 'text',
53
+ contentType: PY_CONTENT_TYPE,
54
+ icon: logoIcon
55
+ });
45
56
  widgetFactory.widgetCreated.connect((_, widget) => {
46
57
  widget.title.icon = logoIcon;
47
58
  widget.context.pathChanged.connect(() => {
@@ -49,6 +60,8 @@ export const spkPlugin = {
49
60
  });
50
61
  tracker.add(widget);
51
62
  });
63
+ const spkButtonExt = new SpkButtonExtention(app.commands);
64
+ app.docRegistry.addWidgetExtension('Editor', spkButtonExt);
52
65
  return tracker;
53
66
  }
54
67
  };
@@ -57,7 +70,6 @@ export const launcherPlugin = {
57
70
  id: 'jupyterpack:spklauncher',
58
71
  optional: [ILauncher],
59
72
  autoStart: true,
60
- provides: IJupyterpackDocTrackerToken,
61
73
  activate: (app, launcher) => {
62
74
  if (!launcher) {
63
75
  return;
@@ -96,7 +108,10 @@ export const launcherPlugin = {
96
108
  [JupyterPackFramework.PANEL]: panelIcon,
97
109
  [JupyterPackFramework.TEXTUAL]: textualIcon,
98
110
  [JupyterPackFramework.VIZRO]: vizroIcon,
99
- [JupyterPackFramework.FASTHTML]: fasthtmlIcon
111
+ [JupyterPackFramework.FASTHTML]: fasthtmlIcon,
112
+ [JupyterPackFramework.GRADIO]: gradioIcon,
113
+ [JupyterPackFramework.MESOP]: mesopIcon,
114
+ [JupyterPackFramework.NICEGUI]: niceguiIcon
100
115
  };
101
116
  Object.entries(iconMap).forEach(([framework, icon], index) => {
102
117
  addLauncherCommands({
@@ -0,0 +1,9 @@
1
+ import { ToolbarButton } from '@jupyterlab/apputils';
2
+ import { DocumentRegistry } from '@jupyterlab/docregistry';
3
+ import { CommandRegistry } from '@lumino/commands';
4
+ import { Widget } from '@lumino/widgets';
5
+ export declare class SpkButtonExtention implements DocumentRegistry.IWidgetExtension<Widget, DocumentRegistry.IModel> {
6
+ constructor(commands: CommandRegistry);
7
+ createNew(panel: Widget): ToolbarButton;
8
+ private _commands;
9
+ }
@@ -0,0 +1,22 @@
1
+ import { ToolbarButton } from '@jupyterlab/apputils';
2
+ import { logoIcon } from '../tools';
3
+ export class SpkButtonExtention {
4
+ constructor(commands) {
5
+ this._commands = commands;
6
+ }
7
+ createNew(panel) {
8
+ const button = new ToolbarButton({
9
+ className: 'spkButton',
10
+ icon: logoIcon,
11
+ tooltip: 'Open with JupyterPack',
12
+ onClick: () => {
13
+ this._commands.execute('docmanager:open', {
14
+ factory: 'jupyterpack',
15
+ path: panel.context.localPath
16
+ });
17
+ }
18
+ });
19
+ panel.toolbar.addItem('openWithSpk', button);
20
+ return button;
21
+ }
22
+ }
@@ -0,0 +1 @@
1
+ export declare const GRADIO_APP = "\n# This example is taken from the Panel official documentation (https://github.com/gradio-app/gradio?tab=readme-ov-file#building-your-first-demo)\n\nimport gradio as gr\n\n\ndef greet(name, intensity):\n return \"Hello, \" + name + \"!\" * int(intensity)\n\n\ndemo = gr.Interface(\n fn=greet,\n inputs=[\"text\", \"slider\"],\n outputs=[\"text\"],\n)\n\ndemo.launch()\n\n";
@@ -0,0 +1,19 @@
1
+ export const GRADIO_APP = `
2
+ # This example is taken from the Panel official documentation (https://github.com/gradio-app/gradio?tab=readme-ov-file#building-your-first-demo)
3
+
4
+ import gradio as gr
5
+
6
+
7
+ def greet(name, intensity):
8
+ return "Hello, " + name + "!" * int(intensity)
9
+
10
+
11
+ demo = gr.Interface(
12
+ fn=greet,
13
+ inputs=["text", "slider"],
14
+ outputs=["text"],
15
+ )
16
+
17
+ demo.launch()
18
+
19
+ `;
@@ -8,6 +8,9 @@ import { STREAMLIT_APP } from './streamlit';
8
8
  import { TEXTUAL_APP } from './textual';
9
9
  import { VIZRO_APP } from './vizro';
10
10
  import { FASTHTML_APP } from './fasthtml';
11
+ import { GRADIO_APP } from './gradio';
12
+ import { MESOP_APP } from './mesop';
13
+ import { NICEGUI_APP } from './nicegui';
11
14
  export async function generateAppFiles(options) {
12
15
  const { contentsManager, framework, cwd } = options;
13
16
  const newPath = await newDirectory({
@@ -50,6 +53,18 @@ export async function generateAppFiles(options) {
50
53
  appContent = FASTHTML_APP;
51
54
  break;
52
55
  }
56
+ case JupyterPackFramework.GRADIO: {
57
+ appContent = GRADIO_APP;
58
+ break;
59
+ }
60
+ case JupyterPackFramework.MESOP: {
61
+ appContent = MESOP_APP;
62
+ break;
63
+ }
64
+ case JupyterPackFramework.NICEGUI: {
65
+ appContent = NICEGUI_APP;
66
+ break;
67
+ }
53
68
  default:
54
69
  break;
55
70
  }
@@ -0,0 +1 @@
1
+ export declare const MESOP_APP = "\n# This example is taken from the mesop official repository (https://github.com/mesop-dev/mesop?tab=readme-ov-file#write-your-first-mesop-app-in-less-than-10-lines-of-code)\n\nimport mesop as me\nimport mesop.labs as mel\n\n\n@me.page(\n path=\"/\",\n title=\"Text to Text Example\"\n)\ndef app():\n mel.text_to_text(\n upper_case_stream,\n title=\"Text to Text Example\",\n )\n\n\ndef upper_case_stream(s: str):\n return \"Echo: \" + s.capitalize()\n\n\n";
@@ -0,0 +1,23 @@
1
+ export const MESOP_APP = `
2
+ # This example is taken from the mesop official repository (https://github.com/mesop-dev/mesop?tab=readme-ov-file#write-your-first-mesop-app-in-less-than-10-lines-of-code)
3
+
4
+ import mesop as me
5
+ import mesop.labs as mel
6
+
7
+
8
+ @me.page(
9
+ path="/",
10
+ title="Text to Text Example"
11
+ )
12
+ def app():
13
+ mel.text_to_text(
14
+ upper_case_stream,
15
+ title="Text to Text Example",
16
+ )
17
+
18
+
19
+ def upper_case_stream(s: str):
20
+ return "Echo: " + s.capitalize()
21
+
22
+
23
+ `;
@@ -0,0 +1 @@
1
+ export declare const NICEGUI_APP = "\n#! jupyterpack.nicegui\n# This example is taken from https://nicegui.io/#single-page_applications\n\nfrom nicegui import ui\n\n\ndef root():\n ui.sub_pages(\n {\n \"/\": table_page,\n \"/map/{lat}/{lon}\": map_page,\n }\n ).classes(\"w-full\")\n\n\ndef table_page():\n ui.table(\n rows=[\n {\"name\": \"New York\", \"lat\": 40.7119, \"lon\": -74.0027},\n {\"name\": \"London\", \"lat\": 51.5074, \"lon\": -0.1278},\n {\"name\": \"Tokyo\", \"lat\": 35.6863, \"lon\": 139.7722},\n ]\n ).on(\n \"row-click\",\n lambda e: ui.navigate.to(f\"/map/{e.args[1]['lat']}/{e.args[1]['lon']}\"),\n )\n\n\ndef map_page(lat: float, lon: float):\n ui.leaflet(center=(lat, lon), zoom=10)\n ui.link(\"Back to table\", \"/\")\n\n\nui.run(root)\n";
@@ -0,0 +1,36 @@
1
+ export const NICEGUI_APP = `
2
+ #! jupyterpack.nicegui
3
+ # This example is taken from https://nicegui.io/#single-page_applications
4
+
5
+ from nicegui import ui
6
+
7
+
8
+ def root():
9
+ ui.sub_pages(
10
+ {
11
+ "/": table_page,
12
+ "/map/{lat}/{lon}": map_page,
13
+ }
14
+ ).classes("w-full")
15
+
16
+
17
+ def table_page():
18
+ ui.table(
19
+ rows=[
20
+ {"name": "New York", "lat": 40.7119, "lon": -74.0027},
21
+ {"name": "London", "lat": 51.5074, "lon": -0.1278},
22
+ {"name": "Tokyo", "lat": 35.6863, "lon": 139.7722},
23
+ ]
24
+ ).on(
25
+ "row-click",
26
+ lambda e: ui.navigate.to(f"/map/{e.args[1]['lat']}/{e.args[1]['lon']}"),
27
+ )
28
+
29
+
30
+ def map_page(lat: float, lon: float):
31
+ ui.leaflet(center=(lat, lon), zoom=10)
32
+ ui.link("Back to table", "/")
33
+
34
+
35
+ ui.run(root)
36
+ `;