Does anyone know what the simplest possible recipe for running a Python script in a WASM sandbox using Spin is?
I basically want to do something like this:
my-sandbox-cli-tool 'print("hello world")
And have the snippet of Python code I provide run inside a WebAssembly container that runs one of the Python compiled to WASM builds (https://github.com/brettcannon/cpython-wasi-build for example) - with a time limit and restrictions on memory usage, and file system access, and network access.I am on a continued quest to figure out the cleanest way to achieve this, I have so many projects I would want to build on top of this capability!
have you tried e2b.dev? it runs lightweight sandboxes using firecracker, python and third-party packages
disclaimer: i work there
Is that something I can run on my own laptop? It says it's "open source" but the docs seem to be for client libraries that need an API key.
everything, including the infra is open-source (below), but it currently requires more than just your laptop (gcp, nomad, firecracker, postgres, etc.)
this way, we're able to run millions secure sandbox environments
i appreciate asking though and will be forwarding to my team to see if we can come up with a way for users to emulate the execution locally
source code: https://github.com/e2b-dev/infra
My objectives here are pretty specific: I'm building open source Python tools for people to run on their own machines, and I want to add "execute untrusted code" features to those tools (mainly for code written by LLMs) such that people can use those features with a clean 'pip install x' of my software on Mac, Linux and hopefully also Windows.
As such you're probably not the right fit for me, I should be looking more at things like wasmer and wasmtime.
You are a big pyiodide user? Does it provide a trampoline to create another sibling instance?
I love Pyodide in the browser but I've had trouble running it not-in-the-browser, aside from this experiment with Deno: https://til.simonwillison.net/deno/pyodide-sandbox
Sorry for asking a possibly noob question. Doesn't firecracker vms requires bare metal instances? And does gcp support provisioning bare metal instances? Or is it that you are able to run firecracker on normal vm instances in gcp ?
GCP supports nested virtualisation
wasmtime works as long as you make sure to include the lib directory
% wasmtime run --dir .::/ python.wasm -c 'print("hello world")'
hello world
disclaimer: I run a code execution API service (https://riza.io/playground) that does this and more (HTTP, packages, etc.)Wow that's almost what I want.
wget https://github.com/brettcannon/cpython-wasi-build/releases/download/v3.13.0/python-3.13.0-wasi_sdk-24.zip
unzip python-3.13.0-wasi_sdk-24.zip
wasmtime run --dir .::/ python.wasm -c 'print("hello world")'
So far so good! But... it looks like that --dir option mounts the current directory as both readable and writable: wasmtime run --dir .::/ python.wasm -c 'print(len(open("python.wasm", "rb").read()))'
# Outputs 28775526
But malicious code can break the system like this: wasmtime run --dir .::/ python.wasm -c 'open("python.wasm", "wb").write(b"blah")'
And now it fails with an error if you try to run it because we over-wrote python.wasm. Even if I move python.wasm out of the current directory I'd still be able to break things by breaking those other lib files.Although... I guess I could use unix filesystem permissions to make those read-only? That could work.
This is just a limitation of the wasmtime CLI. The full Rust API let's you mount filesystems as read-only. Not sure why it's not exposed as an argument.
Thanks - I just found an open issue for exposing that in the Python API: https://github.com/bytecodealliance/wasmtime-py/issues/251
You might need to wrap the wasmtime command in firejail or bubblewrap with appropriate arguments to get the operation restrictions you want.
While that might be a workable stop gap, there is zero reason why this couldn’t be handle in the wasi shim layer. This is exactly what wasi was designed for.
s/disclaimer/shameless plug/ :P Nothing wrong with it, but not really a disclaimer.
> .::/
whats this magic
Wild speculation based on very little understanding of WASI/WASM:
Perhaps "--dir .::/" means treat the host directory "." as the guest directory "/"?
Having worked heavily with gRPC before I like how syntactically similar WIT is to proto. Looks like its time to start experimenting more with web assembly component interop :).
Component dependency is pretty wild and could massively simplify some complex apps
Yes, its great to see progress in the tooling [1] so that the component building is easier. Although I do like to think of the component model as the "ABI linking model". You can only bind one implementation to an interface import.
[1] https://developer.fermyon.com/spin/v3/writing-apps#declaring...
You still need to cross the JS FFI boundary for wasm, I don't think WebAssembly has a specification for cross language FFI directly between WebAssembly languages.
Wasm components can talk to each other, you do not need the JS FFI boundary.
Can you give an example? Say between a wasm component written in Rust and wasm component written in dart.
One of the biggest goals of the component model is that it doesn't matter what language your component is written in. Composition can happen anytime one component exports an interface and another component imports it. https://component-model.bytecodealliance.org/creating-and-co...
won’t happen. all will crumble with the startups pumping it.
it's already happening
it’s not. it’s being presented as such. but it’s not.
WASM is basically similar to JVM bytecode. So the comparison would be like using compiled code from Java, Scala and/or Kotlin for example.
The source language only determines how the code is expressed in WASM and whether or not it also needs to bundle / compile-in some runtime code baggage for it to work.
I develop the Scala-to-Wasm compiler, and also maintain the JVM backend of Scala. I can tell you that Wasm is very different from JVM bytecode.
The fundamental difference is that the JVM bytecode has an object model. When they talk to each other, Java, Scala and Kotlin do so at the abstraction level of the JVM object model. You can directly call methods between them because virtual dispatch of methods is a concept with semantics in the bytecode.
There's no such thing in Wasm, even with the GC extension. You get structs and arrays, but nothing like methods. If you want virtual dispatch, you encode it yourself using your own design of virtual method tables. That means Java, Scala and Kotlin, despite all having their Wasm GC backend at this point, cannot call each other's methods in Wasm.
Yes, in retrospect I should have mentioned "Components" in my comment and just compared it to "Java" in general instead. I felt that was implied due to the thread and topic of discussion.
From a pragmatic end-user point-of-view explanation, I would still stand by saying WASM Component Model may be similar to working within the JVM multi-language ecosystem. One can work with code compiled from multiple different languages, but the generated code may be different because of the different compilers.
I am confused. You are referring to wasm modules here? And Component Model / WASI / WIT will give us polyglot interface-based programming then, right? Call each other's methods through the WIT interface between components.
Even the component model has nothing to say about the concept of methods. All you have are top-level functions with immutable arguments and immutable results. You can't hold on to an instance of an object created by the other language. You could hold an integer handle, but then you don't get garbage collection across the two languages.
So no, we're still a long way from the abstractions of a JVM, even taking the component model into account.
It's a good step in the direction of better interoperability between languages, though, don't get me wrong.
For the audience that would be looking to use the WASM Component Model, and not be an infrastructure implementer of it, whether or not they meet some definition of a method, the component model does define things called resources [1] that have "methods". You'll hold a "handle" to it like you would in your own programming language with the expected drop and/or GC semantics (once implemented [2]) because code is generated to access it like any other FFI like C/C++.
With that in mind, the other confusing thing one may come across is composition vs linking within your WASM runtime that supports the Component Model. When you hear "composition" think of compile-time merging of libraries such that the bundle may have less unresolved dependencies of WASM code/implemented component interfaces. Anything unresolved needs to be linked at runtime with your WASM runtime of choice, like wasmtime [3]. Pretty interesting reading/potential after reading if you ask me -- sounds like you could implement something like a custom Java classloader hierarchy [4].
But I'd agree with a statement saying it is still a long way for general usage.
[1] https://github.com/WebAssembly/component-model/blob/5a34794d...
[2] https://github.com/WebAssembly/gc
[3] https://github.com/bytecodealliance/wasmtime/blob/ba8131c6bf...
[4] https://www.digitalocean.com/community/tutorials/java-classl...
I like the idea of CLI-first. But then could the tooling make it simple & convenient to run the exact same configuration in a browser ? With the choice of either (a) a shell-like prompt, or (b) an auto-generated basic GUI with the appropriate input widgets ?
Asking a question here that I long wanted to ask. Is it possible to have a python handler function that uses duckdb to query a S3 hosted parquet file and that uses pandas for some data manipulation, run as a WASM app? (leveraging all features of duckdb like predicate pushdown etc)
Maybe something like this? https://duckdb.org/2024/10/02/pyodide.html
Purple and green some to have become the colors of dev tooling. I'm seeing that color scheme everywhere.
I can see that at least Vite also uses those colors.
In part inspired by terminal colors but purple (instead of black) makes it feel more modern and sophisticated.
That's the neat thing about trends, the next wave of colours will always feel more modern and sophisticated.
I really wish there were signs that maybe perhaps wasm components would be usable as such in the browser, sometime in the next handful of years. We have this whole amazing modular code system, but once again like with esm the browser gaps persist and drag on.
We finally in 2024 sort of have esm for workers, for example. But not import-maps, so the distributed esm modules aren't directly usable. This category of "making using the spec actually possible" problems tends to dwell for far too long alas.