In parallel to the Python 3 port of ViUR, our free application development framework for the Google App Engine platform, we also did some experimenting with an alternative for our PyJS-based administration tool VI. The experiments where successful: [Pyodide](https://github.com/iodide-project/pyodide), a project serving a Python 3.7 interpreter compiled to web-assembly (WASM) provides a flexible, fast and powerful solution to even build web-apps written in pure Python. A first attempot of porting the Vi to Python 3 running on top of Pyodide looks very promising. This is a short presentation about what Pyodide is, what we changed and how future work might look like...
Start presentation
# What is Pyodide?
- Pyodide brings the Python runtime to the browser via WebAssembly
- CPython 3.7 interpreter compiled to WASM
- emscripten SDK + tools used for building
- https://github.com/iodide-project/pyodide
-
# Features
- Transparent [type conversion](https://pyodide.readthedocs.io/en/latest/type_conversions.html) between JavaScript and Python
- 35+ pre-build Python packages, e.g. Jinja2, Pygments, beautifulsoup4, bleach, pytz ...
- [Installing packages from PyPI](https://pyodide.readthedocs.io/en/latest/pypi.html) is possible!
- Python packages (even C-based!) [can be added easily](https://pyodide.readthedocs.io/en/latest/new_packages.html)
- Fast!
-
# Some caveats...
- The pyodide binaries (pyodide runtime + cpython) is ~22 MB of download
- Browser prohibits network sockets
- Cannot be served as static folder in app.yaml right now because of invalid mime-types
- Therefore CSP-rule `unsafe-eval` must be set to allow calling JS from Python (e.g. network.py)
-
# Examples: Run Python from JavaScript
```javascript
// Simple Python
var x = pyodide.runPython("import sys\nsys.version");
console.log(x); // <- 3.7.0 (default, Jul 2 2019, 11:27:08) [Clang 6.0.1 ]
// Asynchronous: First load packages, then run code
pyodide.runPythonAsync(`
from jinja2 import Environment, BaseLoader
tpl = Environment(loader=BaseLoader).from_string("
{{title|upper}}
")
print(tpl.render(title="Hello World"))
`);
```
-
# Examples: Run JavaScript from Python
```python
from js import window, eval as jseval
document = window.document
window.top.title = "Hello World"
jseval("alert('Help me!')")
```
-
# remotePath feature
- Problem: Python packages must be pre-build and packed using `pyodide_build`
- Solution: remotePath-Feature (https://github.com/iodide-project/pyodide/pull/489)
- Let Pyodide look for Python source files as modules
- `pyodide.remotePath` allows setting several locations to remotely look for packages
- Import fetched packages into browser emulated local file system ([emscripten FS](https://emscripten.org/docs/api_reference/Filesystem-API.html))
- Let Python import files as usual from there
- Perfect for debugging, porting and plugins!
```javascript
pyodide.remotePath = ["/", "https://www.viur.is/vi"];
pyodide.runPythonAsync("import vi");
```
-
# Porting the Vi
- basic porting was generally easy and done in a few hours: Edit Python file + F5
- html5, logics and vi itself can later be packaged (for installation with `setuptools`)
- Some minor changes to the ViUR project has to be done (as long as mime-types for static folders are wrong)
- `develop` -> `redesign` -> `pyodide` is current branch order
- https://github.com/viur-framework/vi/tree/pyodide
-
# Perspective
- Vi can be provided as a stand-alone package: Unpack and run!
- Porting of other, existing web-apps needs only a couple of hours, especially using the remotePath-feature
- Pre-compiled packages and pure Python code can be intermixed in projects (e.g. standard & pre-packaged Vi, extended to custom plugins)
- Eventually pre-caching / pre-build possible for faster app startup in mobile apps / app containers?
- The html5 library and ignite could be merged to serve as a general UI toolkit for HTML5-based web-apps written in Python and run on Pyodide
- We can start RIGHT NOW!
-
# Thank you!
Any questions?