Extism Host SDK for Elixir
Read the docs on hexdocs.pm.
You can find this package on hex.pm
def deps do
[
{:extism, "1.0.0"}
]
end
Note: You do not need to install the Extism Runtime shared object, but you will need a rust toolchain installed to build this package. See Install Rust to install for your platform.
This guide should walk you through some of the concepts in Extism and this Elixir library.
Note: You should be able to follow this guide by copy pasting the code into
iex
usingiex -S mix
.
The primary concept in Extism is the plug-in. You can think of a plug-in as a code module stored in a .wasm
file.
Since you may not have an Extism plug-in on hand to test, let's load a demo plug-in from the web:
url = "https://github.com/extism/plugins/releases/latest/download/count_vowels.wasm"
manifest = %{wasm: [%{url: url}]}
{:ok, plugin} = Extism.Plugin.new(manifest, false)
Note: See the Manifest docs as it has a rich schema and a lot of options.
This plug-in was written in Rust and it does one thing, it counts vowels in a string. As such, it exposes one "export" function: count_vowels
. We can call exports using Extism.Plugin#call/3:
{:ok, output} = Extism.Plugin.call(plugin, "count_vowels", "Hello, World!")
# => {"count": 3, "total": 3, "vowels": "aeiouAEIOU"}
All exports have a simple interface of bytes-in and bytes-out. This plug-in happens to take a string and return a JSON encoded string with a report of results.
Plug-ins may be stateful or stateless. Plug-ins can maintain state b/w calls by the use of variables. Our count vowels plug-in remembers the total number of vowels it's ever counted in the "total" key in the result. You can see this by making subsequent calls to the export:
{:ok, output} = Extism.Plugin.call(plugin, "count_vowels", "Hello, World!")
# => {"count": 3, "total": 6, "vowels": "aeiouAEIOU"}
{:ok, output} = Extism.Plugin.call(plugin, "count_vowels", "Hello, World!")
# => {"count": 3, "total": 9, "vowels": "aeiouAEIOU"}
These variables will persist until this plug-in is freed or you initialize a new one.
TODO: Implement config
Plug-ins may optionally take a configuration object. This is a static way to configure the plug-in. Our count-vowels plugin takes an optional configuration to change out which characters are considered vowels. Example:
{:ok, output} = Extism.Plugin.call(plugin, "count_vowels", "Yellow, World!")
# => {"count": 3, "total": 3, "vowels": "aeiouAEIOU"}
{:ok, plugin} = Extism.Plugin.new(manifest, false, %{"vowels": "aeiouyAEIOUY"})
{:ok, output} = Extism.Plugin.call(plugin, "count_vowels", "Yellow, World!")
plugin.call("count_vowels", "Yellow, World!")
# => {"count": 4, "total": 4, "vowels": "aeiouAEIOUY"}
We don't offer host function support in this library yet. If it is something you need, please file an issue!