Web Assembly¶
Nitro apps can be run entirely in-browser using Nitride, an application runtime for web browsers built atop Pyodide.
This means that, in most cases, you can take your existing Nitro app, and repackage it for web browsers so that your application can be used without hosting it on a server or cloud.
Info
Pyodide is a port of CPython to WebAssembly, and makes it possible to install and run Python packages in the browser.
Getting started¶
Download and unzip the Nitride (Nitro + Pyodide) distribution (named nitride_[VERSION].zip
, for example nitride_0.11.0.zip
).
The distribution contains the following files:
.
├── favicon.ico # Icon.
├── nitride.js # Python runtime.
├── static # Static assets.
│ ├── css # Built-in styles.
│ └── js # Front-end.
└── styles.css # Custom styles.
Additionally, the distribution contains several examples, explained later:
.
├── example_basic.html
├── example_bokeh.html
├── example_bokeh.py
├── example_bokeh_util.py
├── example_entrypoint.html
├── example_hello.py
└── index.html
To run the above examples, you'll need to access them from a web server (and not directly from your computer's file system).
The simplest way to do that is to open a new terminal, change to the above directory, and launch Python's built-in web server:
You can then access the examples at https://localhost:8000/.
Embedding Python in HTML¶
The simplest way to create an in-browser Nitro app is embed Python in HTML using a <script type="text/python">
tag.
<script type="text/python">
from h2o_nitro import AsyncView as View, box
async def main(view: View):
name = await view(box('What is your name?', value='Boaty McBoatface'))
feel = await view(box(f'How do you feel today, {name}?', value='intrigued'))
await view(f'What a coincidence, {name}, I feel {feel}, too!')
nitro = View(main, title='Hello Nitro!', caption='v1.0')
</script>
Loading external modules¶
Although the above technique works, it's more convenient to write programs in .py
modules and load them dynamically.
You can do this easily by adding a <script type="application/nitro">
tag containing a YAML configuration that describes your app.
The configuration below loads example_hello.py
dynamically and executes it (the entrypoint
).
from h2o_nitro import AsyncView as View, box
async def main(view: View):
name = await view(box('What is your name?', value='Boaty McBoatface'))
feel = await view(box(f'How do you feel today, {name}?', value='intrigued'))
await view(f'What a coincidence, {name}, I feel {feel}, too!')
nitro = View(main, title='Hello Nitro!', caption='v1.0')
Loading external packages¶
To load external packages and referenced modules, use packages
, bundles
, and files
.
packages
is a list of package names from the Pyodide repository.bundles
is a list of pure-Python packages.- To include a package from PyPI, provide the name of the package (e.g.
numpy
orpandas
). - To include a wheel file, provide the path to the
.whl
file (e.g.path/to/my/awesome_package-0.42.0-py3-none-any.whl
).
- To include a package from PyPI, provide the name of the package (e.g.
files
is a list of.py
Python modules to download and use.
In the example below, we run example_bokeh.py, which depends on example_bokeh_util.py, numpy
, pandas
and bokeh
.
<script type="application/nitro">
language: python
packages:
- numpy
- pandas
- bokeh
bundles:
- h2o-nitro-bokeh
files:
- example_bokeh_util.py
entrypoint: example_bokeh.py
</script>
Reference¶
Here are all the configuration options supported by <script type="application/nitro">
:
#
# The programming language to use:
#
language: python
#
# The Pyodide runtime to use for executing Python in the browser:
#
runtime: "https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js"
#
# The pre-built packages to load from the Pyodide repository:
# (See https://pyodide.org/en/stable/usage/packages-in-pyodide.html)
#
packages:
- numpy
- pandas
- bokeh
#
# Additional packages to load, if unavailable in the Pyodide repository:
# (Can be names of pure Python packages in PyPI, or paths to wheel files.)
#
bundles:
- nitro-bokeh-plugin
- "path/to/my/awesome_package-0.42.0-py3-none-any.whl"
#
# Additional Python modules or files to copy into the Wasm virtual filesystem:
#
files:
- utils.py
- path/to/something/else.py
#
# The main Python module to load and execute:
#
entrypoint: main.py
#
# Whether the dependencies in the entrypoint module should be
# detected and loaded automatically:
#
autoload: false