wasmerio / wasmer-python

πŸπŸ•Έ WebAssembly runtime for Python
https://wasmer.io
MIT License
2.03k stars 79 forks source link
python python-extension rust wasm webassembly

Wasmer logo Wasmer Python PyPI version Wasmer Python Documentation Wasmer PyPI downloads Wasmer Slack #python Channel

A complete and mature WebAssembly runtime for Python based on Wasmer.

Features

Documentation: browse the detailed API documentation full of examples.

Examples and tutorials: browse the examples/ directory, it's the best place for a complete introduction!

Install

To install the wasmer Python package, and let's say the wasmer_compiler_cranelift compiler, just run those commands in your shell:

$ pip install wasmer wasmer_compiler_cranelift

Usage

from wasmer import engine, Store, Module, Instance

store = Store()

# Let's compile the module to be able to execute it!
module = Module(store, """
(module
  (type (func (param i32 i32) (result i32)))
  (func (export "sum") (type 0) (param i32) (param i32) (result i32)
    local.get 0
    local.get 1
    i32.add))
""")

# Now the module is compiled, we can instantiate it.
instance = Instance(module)

# Call the exported `sum` function.
result = instance.exports.sum(5, 37)

print(result) # 42!

And then, finally, enjoy by running:

$ python examples/appendices/simple.py

We highly recommend to read the examples/ directory, which contains a sequence of examples/tutorials. It's the best place to learn by reading examples.

Quick Introduction

The wasmer package brings the required API to execute WebAssembly modules. In a nutshell, wasmer compiles the WebAssembly module into compiled code, and then executes it. wasmer is designed to work in various environments and platforms: From nano single-board computers to large and powerful servers, including more exotic ones. To address those requirements, Wasmer provides 2 engines and 3 compilers.

Succinctly, an engine is responsible to drive the compilation and the execution of a WebAssembly module. By extension, a headless engine can only execute a WebAssembly module, i.e. a module that has previously been compiled, or compiled, serialized and deserialized. By default, the wasmer package comes with 2 headless engines:

  1. wasmer.engine.Universal, the compiled machine code lives in memory,
  2. wasmer.engine.Native, the compiled machine code lives in a shared object file (.so, .dylib, or .dll), and is natively executed.

Because wasmer does not embed compilers in its package, engines are headless, i.e. they can't compile WebAssembly module; they can only execute them. Compilers live in their own standalone packages. Let's briefly introduce them:

Compiler package Description PyPi
wasmer_compiler_singlepass Super fast compilation times, slower execution times. Not prone to JIT-bombs. Ideal for blockchains On PyPi Downloads
wasmer_compiler_cranelift Fast compilation times, fast execution times. Ideal for development On PyPi Downloads
wasmer_compiler_llvm Slow compilation times, very fast execution times (close to native, sometimes faster). Ideal for Production On PyPi Downloads

We generally recommend wasmer_compiler_cranelift for development purposes and wasmer_compiler_llvm in production.

Learn more by reading the documentation of the wasmer.engine submodule.

Supported platforms

We try to provide wheels for as many platforms and architectures as possible. For the moment, here are the supported platforms and architectures:

Platform Architecture Triple Packages
Linux amd64 x86_64-unknown-linux-gnu wasmer βœ…
wasmer_compiler_singlepass βœ…
wasmer_compiler_cranelift βœ…
wasmer_compiler_llvm βœ…
aarch64 aarch64-unknown-linux-gnu wasmer βœ…
wasmer_compiler_singlepass ❌ 1
wasmer_compiler_cranelift βœ…
wasmer_compiler_llvm βœ…
Darwin amd64 x86_64-apple-darwin wasmer βœ…
wasmer_compiler_singlepass βœ…
wasmer_compiler_cranelift βœ…
wasmer_compiler_llvm βœ…
Windows amd64 x86_64-pc-windows-msvc wasmer βœ…
wasmer_compiler_singlepass βœ…
wasmer_compiler_cranelift βœ…
wasmer_compiler_llvm ❌ 2

Notes:

Wheels are all built for the following Python versions:

Learn about the β€œfallback” py3-none-any wheel ### `py3-none-any.whl` A special `wasmer-$(version)-py3-none-any` wheel is built as a fallback. The `wasmer` library will be installable, but it will raise an `ImportError` exception saying that β€œWasmer is not available on this system”. This wheel will be installed if none matches before (learn more by reading the [PEP 425, Compatibility Tags for Built Distributions](https://www.python.org/dev/peps/pep-0425/)).

Development

The Python extension is written in Rust, with pyo3 and maturin.

First, you need to install Rust and Python. We will not make you the affront to explain to you how to install Python (if you really need, check pyenv). For Rust though, we advise to use rustup, then:

$ rustup install stable

To set up your environment, you'll need just, and then, install the prelude of this project:

$ cargo install just
$ just --list # to learn about all the available recipes
$ just prelude

It will install pyo3 and maturin for Python and for Rust. It will also install virtualenv.

Then, simply run:

$ source .env/bin/activate
$ just build api
$ just build compiler-cranelift
$ python examples/appendices/simple.py

Testing

To build all tests you'll need LLVM 12.0 in your system. We recommend either installing prepackaged libraries with llvm.sh or building it yourself with llvmenv.

Build all the packages and run the tests:

$ just build-all
$ just test

What is WebAssembly?

Quoting the WebAssembly site:

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

About speed:

WebAssembly aims to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms.

About safety:

WebAssembly describes a memory-safe, sandboxed execution environment […].

License

The entire project is under the MIT License. Please read the LICENSE file.