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, 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...
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
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)
- 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?