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.
- package/README.md +246 -111
- package/lib/document/plugin.js +19 -4
- package/lib/document/spkButton.d.ts +9 -0
- package/lib/document/spkButton.js +22 -0
- package/lib/document/templates/gradio.d.ts +1 -0
- package/lib/document/templates/gradio.js +19 -0
- package/lib/document/templates/index.js +15 -0
- package/lib/document/templates/mesop.d.ts +1 -0
- package/lib/document/templates/mesop.js +23 -0
- package/lib/document/templates/nicegui.d.ts +1 -0
- package/lib/document/templates/nicegui.js +36 -0
- package/lib/document/widgetFactory.js +20 -1
- package/lib/pythonServer/baseServer.d.ts +4 -1
- package/lib/pythonServer/baseServer.js +1 -1
- package/lib/pythonServer/dash/dashServer.js +2 -1
- package/lib/pythonServer/gradio/deps.d.ts +2 -0
- package/lib/pythonServer/gradio/deps.js +13 -0
- package/lib/pythonServer/gradio/gradioServer.d.ts +10 -0
- package/lib/pythonServer/gradio/gradioServer.js +48 -0
- package/lib/pythonServer/index.js +7 -1
- package/lib/pythonServer/mesop/deps.d.ts +2 -0
- package/lib/pythonServer/mesop/deps.js +4 -0
- package/lib/pythonServer/mesop/mesopServer.d.ts +10 -0
- package/lib/pythonServer/mesop/mesopServer.js +37 -0
- package/lib/pythonServer/nicegui/deps.d.ts +2 -0
- package/lib/pythonServer/nicegui/deps.js +4 -0
- package/lib/pythonServer/nicegui/niceguiServer.d.ts +14 -0
- package/lib/pythonServer/nicegui/niceguiServer.js +69 -0
- package/lib/pythonServer/shiny/shinyServer.js +2 -3
- package/lib/pythonServer/starlette/starletteServer.js +2 -1
- package/lib/pythonServer/vizro/vizroServer.d.ts +2 -0
- package/lib/pythonServer/vizro/vizroServer.js +10 -6
- package/lib/pythonWidget/pythonWidgetModel.js +5 -3
- package/lib/tools.d.ts +5 -1
- package/lib/tools.js +33 -0
- package/lib/type.d.ts +8 -3
- package/lib/type.js +3 -0
- package/package.json +2 -1
- package/src/document/plugin.ts +24 -3
- package/src/document/spkButton.ts +34 -0
- package/src/document/templates/gradio.ts +19 -0
- package/src/document/templates/index.ts +15 -0
- package/src/document/templates/mesop.ts +23 -0
- package/src/document/templates/nicegui.ts +36 -0
- package/src/document/widgetFactory.ts +20 -2
- package/src/pythonServer/baseServer.ts +4 -1
- package/src/pythonServer/dash/dashServer.ts +2 -1
- package/src/pythonServer/gradio/deps.ts +14 -0
- package/src/pythonServer/gradio/gradioServer.ts +53 -0
- package/src/pythonServer/index.ts +7 -1
- package/src/pythonServer/mesop/deps.ts +6 -0
- package/src/pythonServer/mesop/mesopServer.ts +43 -0
- package/src/pythonServer/nicegui/deps.ts +5 -0
- package/src/pythonServer/nicegui/niceguiServer.ts +79 -0
- package/src/pythonServer/shiny/shinyServer.ts +2 -3
- package/src/pythonServer/starlette/starletteServer.ts +2 -2
- package/src/pythonServer/vizro/vizroServer.ts +10 -4
- package/src/pythonWidget/pythonWidgetModel.ts +5 -2
- package/src/tools.ts +40 -1
- package/src/type.ts +8 -3
- package/style/icons/gradio.svg +24 -0
- package/style/icons/mesop.svg +9 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
58
|
+
### Using shebang in python script
|
|
61
59
|
|
|
62
|
-
|
|
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
|
-
|
|
66
|
+
The available shebang options are:
|
|
101
67
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
79
|
+
After adding the shebang, you have two options to run your application:
|
|
117
80
|
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
84
|
+
### Using a `.spk` file
|
|
132
85
|
|
|
133
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
package/lib/document/plugin.js
CHANGED
|
@@ -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
|
+
`;
|