Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hey everyone, my name is Sohan Maheshwar. I'm a dev advocate
at Fermion and, and today we're going to show you how
you can build a serverless webassembly app using Python
with this open source framework called Spin. Now if
you're not familiar with what Webassembly is, or if you're
not familiar with what serverless is, no problem. That's what I'm here for.
And by the end of this session, hopefully you'll know how you can get
started with Webassembly. I'm going to start off with
a very build claim, and that is the next wave
of cloud computing will be powered by webassembly.
And this is a rather bold way to start off session.
So hopefully by the end of the session you are convinced as well. In fact,
the creator of Docker Solomon makes had tweeted something to this very
effect about two or three years ago. And in a few
slides I think you will see why. So today we are going to talk
about what webassembly is, how it works,
when to use it, and how this will potentially change cloud computing.
I'm also going to show you two demos, very hands on, going with
the hello world example to can example of AI,
and how you can actually use this. So stay tuned till the end for
both of these demos. So first things first, I always have to context
set what really is webassembly. The boring answer
is it's just another bytecode format. Now the short
history behind it is sometime in the was
this technology introduced called Webassembly, originally meant for
the browsers, it was meant to be faster,
it was meant to be portable, it was meant to be more lightweight.
And even now, companies like Adobe Figma,
Shopify, all of these companies use Webassembly
in their browser. Now, if I
say wasm, it's just another word for Webassembly, short for
Webassembly, basically. And really how it was
designed was for it to be a portable compilation
target. Which means any webassembly module could
run anywhere, right? Any architecture, any OS,
any system, as long as that system could run a particular webassembly
runtime. Now what does that mean?
Well, a few of you all might be familiar with the Java
world and how jvms worked, or Java virtual machines worked,
where essentially you wrote a Java program and this compiled
to something called Java Bytecode. And that
Java bytecode could be executed in any environment
which could run a JVM or a Java virtual machine.
And these jvms could run on ARM processors, on x 86
processors, on Windows, Mac, Linux, whatever, right?
So it wasm fairly portable. Now WASM
was designed with a similar method in mind.
Similar idea in mind. But instead of just sticking
to one language, you can write a program in any language.
Yes. So you can write it in Rust C plus plus javascript,
typescript, zig go, and of course Python as well,
which compiles to something called a webassembly bytecode.
Now this webassembly bytecode is the
new format that I was talking to you about. It is a WASM module,
and that could be executed anywhere that has a webassembly
runtime. And this runtime, like I said, cloud be executed
on ARM x 86, Windows, Mac, Linux, Raspberry PI,
kubernetes, whatever, right? So you can write code in
any program. So that essentially is webassembly.
A couple of more things for you to know. Like I mentioned earlier,
it started off in the browser, but sometime in the
late, I think 2010s, around 2017 18,
there were calls to say, hey, this might actually make sense if you
could run it on the serverless side as well. So we'll talk
about that very soon because that's our focus for today.
And the whole idea really is a compile once and then run
that code on any number of targets because it is so
portable. Now how does this really work? How does
this compile once type thing really works? So you need to know some
basic terminology. So when I say a WASM
module, we use the words guest and host. So a
WASM module essentially is that webassembly program
that you wrote. You wrote a program in some language which converted it into a
WASM module. So for instance, you created a function to add two numbers
or to increment a number by one,
right? So that is a WASM module. Now the theory
behind webassembly is it's secure by default or it's sandboxed
by default, which means no other webassembly
module, no other HTTP request, nothing can access this module
by default. Now this module runs in something called
a runtime or a host, and even
this host can run multiple modules. And for one WASM
module to access something in another WASM module,
it cannot unless given explicit permissions to do so.
There are some things we don't need to get into the weeds of some things,
like shared memory and all of that. But the analogy that
I want to draw here is think of a guest WASM module as
like a room in a hotel that you're staying and the host runtime
is the hotel itself. Now as a guest you have access only to
your room, not to the other rooms of course, but there are some
things that are started like say the gym or a restaurant or a lounge within
that hotel that other guests can also
make use of. So that's the analogy that you can think of.
So essentially with this compile and run, you write your code in any language
which is then compiled to a webassembly or a WaSm
bytecode format. And this can run in any
place that can run a webassembly runtime. So think of it as
a virtual machine that can run a webassembly runtime.
Now we said that it originated in the browser, right?
And because of its lightweight,
because of its performance, because of its security, everyone's like hey,
hold on, this actually might make sense if you want to run it in
the server side as well. But guess what? For something to
run on a server you need access to things like files,
you need access to things like sockets, system clocks, random number generators
and so on. So in the late two thousand and ten s this
thing called Wazi was introduced which stands for webassembly
systems interface, which essentially enabled you to
run webassembly on the server side. And quite frankly,
this was a big turning point towards this shift of how
webassembly can change cloud compute. The TLDR,
of course, is you can now run wasm outside of the browser.
Browser Bowser is Mario character,
but essentially you get access to several operating system like features,
right? So access to files, clocks, random number generators,
all of the things you need to run on a server. The cool
thing is it retains wasm sandboxing,
but it also includes input output. So unless you give
it explicit permissions to access a file or
for a file to access this module, it is security sandboxed
by default. And the good thing is browser is not needed.
So it doesn't depend on a web app or JavaScript,
because we're all Python fans here. If you
take a look at the top 20 languages according to Redmonks
ranking, a chunk of them, actually most of them except things
like CSS of course, or PowerShell have support for Webassembly,
right? So everything from JavaScript, Python, Ruby, typeScript,
all of that, and across things like core Webassembly,
browser Wazi, and even spin the SDK that I'll be talking
about in a bit have access. And this is in a continual
state of evolution where there's even more language support coming
in day by day. So the question is I think, how do
I compile my code webassembly? I know to write code in Python, I know to
write code in rust. What's actually happening now?
The thing is, with compile languages like Rust or C or
C plus plus, it actually is a much easier
process, right? Rust, for instance, has amazing webassembly
support because with Rust you compile it to a webassembly module which
can execute on a webassembly runtime wherever,
right? Similar to how we spoke about. Now this is a compiled language,
so it's already low level in that sense.
But with interpreted languages these are a little more tricky
because with languages such as JavaScript and Python, you are
writing code which are then interpreted to something that's at a lower level,
which can then run like bytecode.
So here's a nice piece of trickery that actually
happens where you write a program in Python that's compiled to webassembly,
that's executed on a webassembly runtime.
So if you take a Python program, but that
needs to be interpreted. So what actually happens is a
bunch of very smart and knowledgeable people have provided
the Python source code, like cpython for instance,
in a webassembly format itself, which is then sort of compiled
along with your program into Webassembly, which then runs
on the Wasm runtime. Now this sounds complicated, but the good
news is you don't have to worry about how any of that works.
If you want to build a program in Python that
converts to webassembly, all you have to do is do the Python bits.
And this particular step of this compiling
the interpreter to WASM, is actually done by hand.
So a bunch of smart people are doing this by hand.
They're testing it out so that devs such as
us can actually just focus on writing code
in Python. So that's how interpreted
languages actually compile to Webassembly,
spoken quite a bit, and I don't think you've seen code
so far. So I'm going to get to code very shortly. How do
you get started with building your first webassembly app?
So I'm going to use this open source project called Spin.
Now, spin is the open source tool for building webassembly and
serverless apps. Check it out. On GitHub.
You can create a new serverless app with just three commands,
I promise, and you can even deploy it in the
cloud with the fourth command. And I'm going to show you how it's
completely open source. So if you'd like to contribute to open source? Go ahead
and do so. In fact, there is a bot called the good first
issue bot, which gives you good first issues that you can
get started with contributing to spin.
It supports 15 plus programming languages, very simple
CLI and developer experience. We have 4.6k
stars on GitHub. We also have a discord channel and things like that. So feel
free to jump in. I think it's a nice community. So yeah,
you can do that. And again, just to give you a sense of what spin
is, completely open source and it's built with open standards supported
by the Bytecode alliance. At a glance,
you get the dev experience around building webassembly apps on
the server side, but you also get things like writing serverless AI. You get
a key value store CLI and also a SQL
database that you can use. Right? And you have different triggers for this.
And we will talk about it very shortly.
So again, enough of me talking. Maybe let's dive straight into the
demo. All of this can be found on developer fermion.com
spin. And like I said, it's completely open source.
So I'm going to open up my terminal right
here.
All right, so I've installed the spin CLi already
and I'm just going to start off with the first of the three commands.
Not spin, but spin. I said three commands. So this is the first of
those three commands, which is to create a new spin app. Right.
We're creating our first serverless web app using Python.
Now you will see there are a bunch of templates for you to get started.
And on the left are triggers, right? Typically triggers are
things like HTTP because with serverless it's completely
event driven. Or you can also have triggers such as
Redis, which is a redis database. Right? So right there
on the right you will see a bunch of languages like C and go and
Python and rust. So those are the different languages for
you to get started to write those webassembly apps.
We are talking about Python today. So I'm going to go ahead and say HTTP
python. I'm saying hello world.
Conf 42. All right, skip the description. There's something
called HTTP Path, which you can specify a
URL upon which your app will be
triggered. So say checkout will trigger a certain module or
add to cart will trigger something else. Here we, let's leave
it as default, which means anything to that URL will give
you or will trigger this app. So I'm
going to hello world, I'm going to CD into this directory
and then just open it in vs code and let's see
how that goes. All right, so a spin
app is fairly simple and the entry point to the app is
this thing called an app manifest or a spin toml.
Now you can see some metadata here. You don't have to worry about that.
This is the trigger that we added where we say here
by default, hit this particular component which
the code to which we will be writing very soon. And there is some description
of that component as well. So you can see the wasm file
and you can see the command to create,
to convert it from python to wasm using this
thing called pytovasm. Again, we as developers don't have to worry
about how pytovasm works. We just know that some people have
created this pytovasm and we can focus on writing our python code.
Now, serverless is completely event driven, right? So you get
a request and you have to send a response.
Now this is the simplest hello world possible. So there is
a request coming in. We are sending a response of 200k saying hello
Conf 42. Right. And I'm going to save
that. Now, we added our first command, which was
spin new. I'm going to build my program by saying spin
build. Right. You can see how fast that was. I haven't sped
up the video or anything. That is literally it. And now
I can just say spin up, which is to test
the app locally. Now this is part of a good developer experience
where you can test something locally before pushing it to
the crowd cloud with my pronunciations today.
So I can just do a simple curl to this.
I sorry,
I'm just going to do that again. I'm going
to do a spin up so that it's running locally.
Right. That's spin up running locally. And I'm just doing a curl
command. Curl minus I, right.
And as you can see, the response returned is hello Conf 42.
So in three commands we went from nothing to creating
app that is running locally. And it's
a serverless webassembly app written in Python. The cool thing
is with the fourth command I can deploy this to the fermion cloud.
So actually have this app that's running in the
cloud for anyone to access. Now how this essentially works is it
takes that particular wasm file that has been created,
which I'll show you now, and it pushes it to the cloud.
So if I do,
let me do ls, you can see ls.
Oh, if I do ls minus La, you can actually
see an app wasm that's created here, which is about
a couple of megabytes, and if you do a
Nanoapp wasm, you will see the bytecode
format, which for us it's mostly gibberish. Right? It doesn't make sense,
but that's essentially what the webassembly runtime is reading.
So yeah, it's deployed to the cloud. In fact, I can go
to this website right now and I will hopefully be
able to see the
output. Right, there we go. You can see. Hello conf fourty two.
So like I said, in four commands we have gone from nothing to deploying an
app in the cloud in hardly any time.
Cool. So let's get back to this.
So four things that make Webassembly great, right? So the first one
is binary size itself. Why is webassembly a big deal?
Why is it going to be the next wave of cloud compute? Well,
at scale, things like binary size makes a big difference, because that changes
your deploy times, it changes your startup times, it changes
your carbon footprint.
There was a benchmark done in rust, and hello World was
just about two mb, and then ahead of time compiled
rust. Webassembly app was only about 300 kb.
We just saw in our demo as well. The app WASM file was about 2.5
mb, which was a simple file. So these are very, very small apps.
The same thing using, if you're running it
in flask, say on Docker or something, is a much bigger file.
So Webassembly is lightweight, and it's designed to be so
startup times are comparable with natively compiled code.
It's not the same, of course it's going to be slightly slower. Again,
with Rust it was about 2.3 x slower than native, but those are
near native compile times, which make a lot of sense, especially when you're building
at scale. We mentioned earlier about how
Webassembly is portable, which means you can build this once
and run it anywhere. That app wasm will run
on any runtime which supports Webassembly, right?
So the same, just in time build will work across operating systems,
platform architectures, different systems and so on.
And like I mentioned, it's designed to be security sandboxed
by default. So the approach is a very capability based
security model. Any HTTP request using in or
going out or coming in has to be explicitly given. Any access
to files in or out, again has to be explicitly given,
which makes this very secure by default.
When I said the next wave of cloud computing will be powered by webassembly,
how will this change? Yeah, sure, it has all these cool things. But how will
this really change cloud computing? Well, my prediction
is, and I've been working a lot with emerging tech for the
last ten years, is that it will change things gradually and
then suddenly, because there are so many
things that we are seeing in how cloud computing is evolving right
now. If you see the evolution of it,
we've gone from a pre cloud era where we had this server
running down the hallway in this room that was cooled by multiple air
conditioners, where you had to take care of everything from the
hardware to the security, the physical security,
but to the kernel, the drivers, the operating system, and of
course, your app. Good old days. We don't want to go there
anymore. As we evolved towards things like virtual
machines, we saw where the physical security
and the space we didn't really need to care about. A cloud provider
gave that to us. We could focus on things like our
app, but also we had to take care of updating our os and
security and our utilities.
That has changed a bit with containers, and now that is changing with
serverless, where you can focus only on your business
logic and your app, you don't need to worry about scaling
up, about scaling down, about updates, any of that. Right? The host
takes care of most of that. You as a dev, focus only on
your business logic. So talking about how that changes
containers, well, sorry, how that changes cloud computing, well, we won't
see any more clunky containers. I'm sure we're all familiar with
things like Docker and Kubernetes. These are widely used in
enterprises, in startups wherever, right?
And it's a known fact that with containers,
there is a huge underutilization of opensource that
actually happen. So, excuse me. Even in
a study of the top 50 public software companies, it's estimated
about $100 billion of market value is lost because of
the cloud impact on margins. What this basically means
is when we are provisioning for cloud computing space,
we typically provision for the peaks and not the average,
right? We're like, hey, what if there is so much usage on our app?
This is the peak usage on our app that happens once a month,
so we have to provision for that much. But guess what?
Your average usage is way below, and that's what's running
most of the time. So there's all of these resources
that are being underutilized with webassembly. You can actually
scale to zero in no time, right? You can scale up and scale down
in no time. And it's so lightweight, so you can pack a
container with far more number of app than you are doing currently,
thereby utilizing your resources better.
And as a company scales, or as you deploy more
and more apps into a container, this starts making a lot
more sense, right? We're talking about again, running in the cloud
at scale. You start saving costs, you're faster, you're more
agile, you can do things
quicker as well with microservices. So this starts
making sense again. So webassembly is using to change this
part, and the second is it could potentially
fix serverless as well. Now, serverless is gaining
a lot of traction in the last few years with services like Lambda
and Azure functions and so on. There are a few problems that
I see with things like serverless.
One is of course, serverless in the public cloud has
a cold start problem, if you're not familiar. Basically how serverless
works is there is an event that goes to a function that's running
somewhere, and then that program starts, executes, and then sends
a response back. But with how services
such as lambda and Azure functions are actually structured.
There is something called a cold start time, which means there is a finite amount
of time between the request being sent and the program actually
starting up. And it could take even about two to 3 seconds
with AWS Lambda. But typically we see maybe about 500
milliseconds as the cloud start time. This is not ideal for
many use cases where speed is of the essence,
and people have like complex and expensive workarounds
by warming up an instance by sending pings once in a while,
which these costs are borne by you as the customer. So that's
not just coding complexity, but also costs.
With Webassembly you can actually,
because of its small size and its fast startup time, we are actually
able to cold start a module on every execution in just
about two milliseconds, right? So that is a significant
difference between, say, an AWS lambda, and again,
this is due to the properties of webassembly as well as
our tech stack, where we're able to do this and then scale it
down back to zero. So if your function has run something,
that's all you're charged for. So broadly,
these are a couple of ways that the cloud will potentially change with
the adoption of webassembly. I did
promise you two demos, so I'm going to show you another demo, and this time
the usage of serverless again, but again,
using AI. So llms or large language models
are the talk of town. Everyone's talking about it. So I did
say spin gives you access to LLM as well.
We have access to the llama two language model, right?
And again with just like five lines of code. I'm going to show you a
simple hello worldish app, but that one that is actually
using AI. So I've written the program already.
It's pretty simple. All you have to do is import
couple of libraries, especially spin LLM.
And again, remember we are doing this serverlessly. So request comes in,
request goes out. Now we have to call
this function called LLM infer and mention the large language
model which is llama to chat, followed by
the text itself. So I'm just saying, can you tell me a joke about cats
have no idea what output this will send and if it's successful,
it'll actually return the text. If there's an error, it'll return the error.
So ten lines of code, but really it's like two lines of
code that you need to know, right? It's literally that simple.
The one small change to your spin toml from earlier is
I mentioned the AI model that I want to speak to.
This is cool because as and when we have support for
different models, you can just swap this out for a different model
name or potentially even bring your own model and you
don't have to recreate everything from scratch and so on.
So I am going to go back here and
do the same steps again. Remember, just spin build. And now
I can run this locally or I can run it in the
cloud. This is using a large language model though, so if I
run it locally it can take about 10 minutes
to actually process it because I'm running it on a MacBook. There is
a pretty cool plugin that someone's written for spin where
you can run this program locally, but talk to a large
language model that's running in the cloud. So I'm going to
do that. I've done one step of a runtime
config, but let's open the browser and see
how this goes and see if it's fast as well. Hitting enter now and
in maybe a second or two. Yes. So there we
go. These are the cat jokes. Why did the cat go to the vet
to get its positive diagnosis?
What did you call a group of cats playing instruments? A musical band?
Well, I didn't say the jokes are good, but well, it is a joke.
That's what the AI decided was funny. So who are we to judge?
Again, this is completely serverless. I didn't need to have a
large language model running on a server in the cloud consistently,
right? It made a request to a large language model that processed,
it sent a request back to me and that's it again.
You saw the speeds, the scale up and scale down, and this is just the
tip of the iceberg. The one thing that I'm super excited
about in the webassembly and serverless webassembly world
is something called the component model.
So software, when we build software now, the process
itself is kind of weird, because, for instance,
you're writing an app in JavaScript and you need two things. You need a
YAml parser and a date formatter. But guess what? There are
no great YAml parsers in JavaScript. There are no date formatters.
Great date formatters in JS. So you write your
own, right, or you write one, or you use one that is not very good.
Basically it's very inefficient. But there are great rust
YAml passes, because rust is very good at parsing lots of data, and Python
is very good with numbers. So there's an amazing Python date formatter.
So what if there was a way for you to, in your JavaScript
app, use a Rust YAml parser and a Python date formatter?
Well, with the component model, which is live, and you can try it out,
this is actually possible. The idea is all of these
languages convert to a webassembly module. So if you define
can interface that allows you to talk to interface
where these modules can talk to each other, then you can theoretically
have an app composed of different modules in different languages.
And it's not just theory, because there are enough examples now of languages
written in different, sorry, programs written
in different languages. So you could write something in Rust Python C
plus plus, which should compile to a webassembly module and talk to
each other. And you could compose an application this way.
So you have a component a, which has a core webassembly module,
which exports a function, and component b wants to import
that same function. So you can join the two together,
they can be in rust, go Python, whatever, and thereby you
create a new component called c. So this is
possible now, and as unbelievable as it sounds,
it literally is possible. You should check it out with Python.
Specifically, I want to shout out the work done on something called
componentize PI, which is a tool to convert a Python
application to a webassembly component. It takes something
called a wit file or wasm interface type file,
which determines the imports and exports. It makes the
name of something called a world, which is a very abstract
concept, but a place where these imports can export
and those exports can import. It takes the name of a module
which targets that world, and a list of directories in
which you can find this module. It's super. A few
people who work at Fermyon have contributed to this, and again,
it's completely open source, so check it out. It's part of the Bytecode
alliance on GitHub.com slash Bytecode alliance slash componentize
by all right, that's it for my presentation
today. I think I just about made time. Feel free
to join our Discord server or get started with spin. I'd love to
see what you're building with Webassembly. We do a lot of cool stuff on
YouTube and Discord, so join us there. Feel free to connect with
me on LinkedIn if you like this presentation. Hope you learned something new today,
and I look forward to seeing what you're building with Webassembly and spin.
Till then, enjoy out the rest of the conference and see you soon.