Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Pyscript and pyodide #7016

Merged
merged 7 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions doc/how_to/wasm/convert.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The ``panel convert`` command has the following options:

This example will demonstrate how to *convert* and *serve* a basic data app locally.

- install the dependencies `pip install panel scikit-learn xgboost`.
- Create a `script.py` file with the following content

```python
Expand Down Expand Up @@ -88,7 +89,8 @@ Using the `--to` argument on the CLI you can control the format of the file that

- **`pyodide`** (default): Run application using Pyodide running in the main thread. This option is less performant than pyodide-worker but produces completely standalone HTML files that do not have to be hosted on a static file server (e.g. Github Pages).
- **`pyodide-worker`**: Generates an HTML file and a JS file containing a Web Worker that runs in a separate thread. This is the most performant option, but files have to be hosted on a static file server.
- **`pyscript`**: Generates an HTML leveraging PyScript. This produces standalone HTML files containing `<py-env>` and `<py-script>` tags containing the dependencies and the application code. This output is the most readable, and should have equivalent performance to the `pyodide` option.
- **`pyscript`**: Generates an HTML leveraging PyScript. This produces standalone HTML files containing `<script type="py">` tags containing the dependencies and the application code. This output is the most readable, and should have equivalent performance to the `pyodide` option.
- **`pyscript-worker`**: Same as `pyscript` except the Python is executed on a Web Worker. This option is slightly less efficient than the `pyodide-worker` option but still ensures that the frontend is not blocked while the code is executing.

## Requirements

Expand Down Expand Up @@ -118,9 +120,9 @@ Progressive web applications (PWAs) provide a way for your web apps to behave al

Once generated, you can inspect the `site.webmanifest` file and modify it to your liking, including updating the favicons in the assets directory.

```{note}
:::{note}
If you decide to enable the `--pwa` ensure that you also provide a unique `--title`. Otherwise the browser caches storing your apps dependencies will end up overwriting each other.
```
:::

## Handling HTTP requests

Expand Down
38 changes: 14 additions & 24 deletions doc/how_to/wasm/standalone.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ To get started with Pyodide simply follow their [Getting started guide](https://
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/pyodide/v{{PYODIDE_VERSION}}/full/pyodide.js"></script>

<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-{{BOKEH_VERSION}}.js"></script>
Expand Down Expand Up @@ -44,7 +46,7 @@ To get started with Pyodide simply follow their [Getting started guide](https://
return f'Amplitude is: {new}'

pn.Row(slider, pn.bind(callback, slider)).servable(target='simple_app');
`);
`);
}
main();
</script>
Expand All @@ -64,44 +66,30 @@ const bk_whl = "https://cdn.holoviz.org/panel/{{PANEL_VERSION}}/dist/wheels/boke
const pn_whl = "https://cdn.holoviz.org/panel/{{PANEL_VERSION}}/dist/wheels/panel-{{PANEL_VERSION}}-py3-none-any.whl"
await micropip.install(bk_whl, pn_whl)
```

:::

### PyScript

PyScript makes it even easier to manage your dependencies, with a `<py-config>` HTML tag. Simply include `panel` in the list of dependencies and PyScript will install it automatically:

```html
<py-config>
packages = [
"panel",
...
]
</py-config>
```

Once installed you will be able to `import panel` in your `<py-script>` tag. Again, make sure you also load Bokeh.js and Panel.js:
A basic, single file pyscript example looks like

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-{{BOKEH_VERSION}}.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-{{BOKEH_VERSION}}.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-{{BOKEH_VERSION}}.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@holoviz/panel@{{PANEL_VERSION}}/dist/panel.min.js"></script>

<link rel="stylesheet" href="https://pyscript.net/releases/{{PYSCRIPT_VERSION}}/pyscript.css" />
<script defer src="https://pyscript.net/releases/{{PYSCRIPT_VERSION}}/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/{{PYSCRIPT_VERSION}}/core.css">
<script type="module" src="https://pyscript.net/releases/{{PYSCRIPT_VERSION}}/core.js"></script>
</head>
<body>
<py-config>
packages = [
"https://cdn.holoviz.org/panel/{{PANEL_VERSION}}/dist/wheels/bokeh-{{BOKEH_VERSION}}-py3-none-any.whl",
"https://cdn.holoviz.org/panel/{{PANEL_VERSION}}/dist/wheels/panel-{{PANEL_VERSION}}-py3-none-any.whl"
]
</py-config>
<div id="simple_app"></div>
<py-script>
<script type="py" config='{"packages": ["https://cdn.holoviz.org/panel/{{PANEL_VERSION}}/dist/wheels/bokeh-{{BOKEH_VERSION}}-py3-none-any.whl", "https://cdn.holoviz.org/panel/{{PANEL_VERSION}}/dist/wheels/panel-{{PANEL_VERSION}}-py3-none-any.whl"]}'>
import panel as pn

pn.extension(sizing_mode="stretch_width")
Expand All @@ -112,12 +100,14 @@ Once installed you will be able to `import panel` in your `<py-script>` tag. Aga
return f'Amplitude is: {new}'

pn.Row(slider, pn.bind(callback, slider)).servable(target='simple_app');
</py-script>
</script>
</body>
</html>
```

The app should look identical to the one above but show a loading spinner while Pyodide is initializing.
The app should look identical to the one above.

The [PyScript](https://docs.pyscript.net) documentation recommends you put your configuration and python code into separate files. You can find such examples in the [PyScript Examples Gallery](https://pyscript.com/@examples?q=panel).

## Rendering Panel components in Pyodide or Pyscript

Expand Down
7 changes: 3 additions & 4 deletions panel/io/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
BOKEH_VERSION = base_version(bokeh.__version__)
PY_VERSION = base_version(__version__)
PYODIDE_VERSION = 'v0.25.0'
PYSCRIPT_VERSION = '2024.2.1'
PYSCRIPT_VERSION = '2024.7.1'
WHL_PATH = DIST_DIR / 'wheels'
PANEL_LOCAL_WHL = WHL_PATH / f'panel-{__version__.replace("-dirty", "")}-py3-none-any.whl'
BOKEH_LOCAL_WHL = WHL_PATH / f'bokeh-{BOKEH_VERSION}-py3-none-any.whl'
Expand Down Expand Up @@ -272,7 +272,6 @@ def script_to_html(
reqs = base_reqs + [
req for req in requirements if req not in ('panel', 'bokeh')
]
print(reqs)
for name, min_version in MINIMUM_VERSIONS.items():
if any(name in req for req in reqs):
reqs = [f'{name}>={min_version}' if name in req else req for req in reqs]
Expand All @@ -290,12 +289,12 @@ def script_to_html(
css_resources = [PYSCRIPT_CSS, PYSCRIPT_CSS_OVERRIDES]
elif not css_resources:
css_resources = []
pyconfig = json.dumps({'packages': reqs, 'plugins': ["!error"]})
pyconfig = json.dumps({'packages': reqs})
if 'worker' in runtime:
plot_script = f'<script type="py" async worker config=\'{pyconfig}\' src="{app_name}.py"></script>'
web_worker = code
else:
plot_script = f'<py-script config=\'{pyconfig}\'>{code}</py-script>'
plot_script = f'<script type=\'py\' config=\'{pyconfig}\'>{code}</script>'
else:
if css_resources == 'auto':
css_resources = []
Expand Down
Loading