Pyodide

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?