The WebAssembly Interface Types was removed in favor of wit-bindgen
as discussed here: https://github.com/bytecodealliance/wasmtime/issues/677#issuecomment-1024087373.
I am trying to compile the old markdown demo using interface types support available at https://github.com/bytecodealliance/wasmtime-demos, and import the wasm
file in a python runtime. While the compilation works, I am unable to import the module since the feature was removed. Therefore I am trying to rewrite it with wit-bindgen
: https://github.com/bytecodealliance/wit-bindgen
This is my project setup:
Cargo.toml
[package]
name = "markdown"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ['cdylib']
[dependencies]
pulldown-cmark = "0.5.3"
wit-bindgen-rust = { git = "https://github.com/bytecodealliance/wit-bindgen" }
src/render.wit
render: func(name: string) -> string
src/lib.rs
use pulldown_cmark::{html, Parser};
wit_bindgen_rust::export!("./src/render.wit");
struct Render;
impl render::Render for Render {
fn render(input: String) -> String {
let parser = Parser::new(&input);
let mut html_output = String::new();
html::push_html(&mut html_output, parser);
return html_output;
}
}
I can compile this with cargo build
and move the wasm
file to the root directory with cp /target/wasm32-unknown-unknown/release/markdown.wasm .
. The python bindings file bindings.py
is generated by issuing wit-bindgen wasmtime-py --import src/render.wit
.
How do I finally import the wasm
file in python? I have tried the following:
import wasmtime.loader
import markdown
but this gives me the error:
File ~/.local/lib/python3.10/site-packages/wasmtime/loader.py:72, in _WasmtimeLoader.exec_module(self, module)
70 break
71 field_name = wasm_import.name
---> 72 imported_module = importlib.import_module(module_name)
73 item = imported_module.__dict__[field_name]
74 if not isinstance(item, Func) and \
75 not isinstance(item, Table) and \
76 not isinstance(item, Global) and \
77 not isinstance(item, Memory):
File /usr/lib/python3.10/importlib/__init__.py:126, in import_module(name, package)
124 break
125 level += 1
--> 126 return _bootstrap._gcd_import(name[level:], package, level)
ModuleNotFoundError: No module named '__wbindgen_placeholder__'
I believe this is because the bindings.py
file is not being used. How do i specify it using python-wasmtime
?
I recently did something similar with wit-bindgen and python.
In your Python code you can do something like this to make it work:
from wasmtime import Engine, Store, Config, Module, Linker, WasiConfig
from md import bindings
config = Config()
engine = Engine(config)
store = Store(engine)
store.set_wasi(WasiConfig())
module = Module.from_file(engine, path)
linker = Linker(engine)
linker.define_wasi()
markdown = bindings.Markdown(store, linker, module)
res = markdown.render(store, text)
You can also take a look here for the full example: https://github.com/olavvatne/python-webassembly-rust