Resources

Winston Chang | Running Shiny without a server | RStudio (2022)

Shiny for Python has the ability to be deployed without a server that runs Python. These applications can be served by any web hosting service. They are easily deployed and can scale to handle large amounts of traffic. This mode of deployment is called Shinylive. It works by running Python in the user’s web browser, using Pyodide, which is a version of Python that is compiled to WebAssembly. Shinylive opens up new possibilities for how Shiny applications can be used. In this talk I discuss the advantages and the limitations of Shinylive applications. Session: Some of my best friends use Python

Oct 24, 2022
19 min

image: thumbnail.jpg

Transcript#

This transcript was generated automatically and may contain errors.

So today I'm going to be talking about Shiny for Python without a server running Python.

So Shiny for R has been around for 10 years now, it's kind of hard to believe. And if you want to deploy one of these applications, you have to have a server, oops, whoa, sorry this clicker is a little sensitive, you have to have a server running R running Shiny.

Yesterday Joe announced Shiny for Python. And if you want to deploy one of these apps, you have to have a server running Python running Shiny.

But there's another option where you can have a server that's running nothing.

The early days of Shiny

Now before I go in-depth explaining what that means, I want to tell a story about the early days of Shiny. So this was back in 2013. Shiny had been around for about a year. And we had a server that was available where people could deploy their applications. And people were putting all sorts of interesting stuff there because there's, you know, scientists are using R and Shiny and they're doing all sorts of cool different things.

One of the applications that showed up was a quiz by somebody who was a graduate student in statistics at the time, named Josh Katz. So long time users of Shiny know what this is about. This is one of the questions that he had on the quiz. So what do you call the insect that flies around in the summer and has a rear section that glows in the dark? You could answer this, lightning bug, firefly. I use them interchangeably or other.

So people would go to this, they'd select their answer, and it would display a map. So in the green areas here, this is where people tend to say firefly, the blue areas are where people tend to say lightning bug, and the red areas are where people use those two words interchangeably.

How do you pronounce mayonnaise? So with three syllables, mayonnaise, with two syllables, mayonnaise, or I use both interchangeably. So here's the map. In red is where people tend to say mayonnaise, and in blue is where people say mayonnaise, and the green is where people use them interchangeably, but there doesn't seem to be a lot on this map.

So you'd answer a lot of these questions, and at the end, it would generate a map for you showing how similar your personal dialect is to your regional dialects in the United States. Now, this isn't my map, but this is actually pretty close to me. The red is where your dialect is more similar to the regional dialect. So in this case, it's most similar to Northern California, and blue is where it's least similar.

Now these maps were all generated dynamically, and that was a little bit computationally expensive, but when you're dealing with, like, four or five people, that's not, you know, four or five simultaneous users, that's not a big deal, but this got out into some I believe it got out into some linguistics blog, and then it got picked up by the media. This is Business Insider. There was an article that ended up here, and my understanding actually was that this was the most popular article on their website that year.

So it got picked up here and some other outlets, and it ended up driving a lot of traffic to our server. So at some point, we had thousands of simultaneous users, and our server went down, and we had to spin up new servers in AWS to handle all that computational load. And this was back before we had these automated scaling and hosting systems that we have now. So that was a very manual process, ended up being very expensive. We spent thousands of dollars running all these servers. But we survived.

But you know, this raises an interesting question, which is, wouldn't it be nice if we didn't have to do all that computation on the server?

Options for moving computation off the server

So what are some ways of not doing the computation on the server? One thing you can do is maybe you can precompute the results. So sometimes you can do this. And sometimes you can't. So some of those maps could have been pregenerated, and actually Josh changed his app to do that, but that final one with your personalized map could not be.

What about doing computation on the client? Well, you have a couple options here. So one is to do the computation in the web browser. But if you know something about web browsers, you know that the only language they understand is JavaScript. So therefore, you must write your application in JavaScript. And that can be a problem if you're doing data science, because a lot of the tools that you're used to might not exist in JavaScript.

So how about another option? Send the code and data to the client and let the user run the code on their computer. So in order to do this, though, you need to duplicate your computing environment on their computer. And doing this, duplicating your computing environment is difficult, and it's a lot of work. And you can't reasonably expect somebody to take that survey, that fun survey, and have to install R or Python and a whole bunch of packages just to do that.

WebAssembly and Pyodide

Well, this is actually the story of how things were back then, but things have changed. So this part here about web browsers can only run JavaScript, that's actually no longer true. And the corollary is also not true anymore.

So what other language do web browsers support now? Well, there's something called WebAssembly, or it's sometimes abbreviated WASM. This is a binary format for programs that can run in web browsers. It's not a language that you'd write by hand normally. Usually you'd write code in C or C++ or some other languages and compile it to WebAssembly, and then you can run it in the browser at near-native speeds.

So it turns out Python is written in C, and there's actually a port of Python called Pyodide which compiles to WebAssembly and can run in the web browser. And of course, I have to mention WebR, which is a project that George Stagg started and is working on, which is R compiled to WebAssembly. But this is still in the early stages, so I'm not going to talk more about it in this presentation.

So let's go back to doing computation on the client. So this option two here, this problem here, duplicating a computing environment is difficult. Well, actually, if you compile your computing environment to WebAssembly, you can send it to the web browser, and this actually becomes very easy to duplicate the computing environment. So we'll cross that out. And then we have this new combination of options one and two. So we send the code and data and the computing environment in WebAssembly to the client and then run all of that in the web browser.

Introducing shinylive

So we have done this with Shiny. So we've put together Shiny and Python and WebAssembly, and we put it together into something that we are calling shinylive.

So I'm not going to tell you a whole lot more about it right now. I'm just going to show you what you can do with it. So how many people here have gone to the documentation website for Shiny for Python? Okay. So if you did that, that's great, you might have seen something like this. So this is this web page here, and then there's a running application there.

So this is a histogram, you move a slider, and, you know, it regenerates some data and redraws the histogram. Okay. So what you might not have known is that you were already using shinylive. These applications on the website are not hosted on a server that's running Python. These examples are all running inside of the web browser.

So what you might not have known is that you were already using shinylive. These applications on the website are not hosted on a server that's running Python. These examples are all running inside of the web browser.

So you can go and you can make changes to this application. Let's just change this one so it generates a uniform distribution. So I'll take out some of the UI stuff, make some UI modifications. Don't worry about the details about this. You just have to know that I'm changing some code. And after we make those changes, then you can hit the play button, and you can see that now it's generating uniform distribution. So again, all of that, the editor, and this application viewer panel, and Shiny itself, all of that is running inside the web browser. There's no server running Python.

So what are some other fun things you can do with this?

If you start on the main web page, and then there's an examples button. You can click to browse some examples. You don't have to be able to really read it. But on the sidebar, there's some interesting examples there. One of them is a simulation of the moon orbiting the earth.

So what we have here is the code editor and then the running application over there. And again, this is all running inside the web browser. There's no server in the back running Python. So you can make changes to the initial speed of the earth. And then if you do that, you can see how the moon will follow it as it orbits. But let's say, you know, I want to make some changes to this. This app is a little complicated. I want to simplify a little bit.

So you can make these changes right in the browser and rerun the application and try all sorts of new things out. So here we are. We've simplified the application a little bit. I know it looks pretty similar, but it is actually simpler. And maybe we've learned a lot about using Shiny by doing this.

Sharing and deploying shinylive apps

Now, you might want to share this with people, right? Normally to do that, you would have to deploy it to some server that's running Shiny. But there's another option here with shinylive. And I'm going to zoom in a little bit. So there's a share button. And then when you click on that, it will provide these two sharing links. And one of the... The top one says editor URL. And you can copy that URL, send it to somebody, and when they paste it in their web browser, they'll open it up and they will see the application running in their browser as well. And they have that editor panel and the running application.

So this is good if the person you're sending it to is interested in the code and looking at it or modifying it. But maybe the person is not interested in that. Maybe they just want to see the application itself. So there's another link, application URL. You can copy that and send it to them. And then if they put that in their browser, it will open it up and it will be running that application in the full window.

So you might be wondering, like, hey, how much does this cost? How do I sign up for this? And the answer to those questions is it doesn't cost anything and you don't have to sign up for anything to use this. So we'll take a look at this URL. This might help explain things a little bit. So this is what the URL looks like. So it's shinylive.io.py editor and then code equals and then there's this big string. So that string is actually that whole application code encoded into the URL.

And when you make a request, when you send that to somebody and they go visit that, the web browser makes a request just for this first part, the part in blue. So it requests shinylive, hey, send me all this shinylive stuff, the WebAssembly and JavaScript stuff. And Python stuff, of course. It does not send this part to the server. That part is just in their browser. And so the browser then takes shinylive, decodes the application, and then runs it all inside the browser. So that means that the server is just serving these files without having to think about it. It just sends out tons of files. And that's really easy for web servers to do.

Now, you might be thinking, well, sharing Shiny apps with a URL, that might be fun. But maybe the app and data is too big to make a reasonably sized URL. I mean, browsers can actually handle, from testing I found, really large URLs these days, like even in the megabytes. You don't typically want to send a huge URL like that. Maybe it feels weird to encode an app in a giant URL. That just seems strange. Or maybe, if I can get this clicker to work, maybe I don't want to depend on the server at Shinyapps.io, which I don't have any control over.

Well, I have control over it, but you don't. So another option is to deploy your shinylive application. So in order to do this, there's two steps. The first is to save your shinylive assets and application files to a directory and then upload that directory to a web hosting service like GitHub Pages or Netlify, Amazon S3, or CloudFlare Pages. If you're old school, you can use an Apache web server. Or you can deploy to RStudio Connect, which is useful because it provides authentication and access control if you don't want the whole world to be able to see the application.

And let me show you how this works. So it's pretty simple. All right, so let's say I have my application files in a directory called myapp. Then there's a command line tool that comes with Shiny for Python called Shiny. And you say Shiny static myapp site. So site is the directory that we're writing it to. And it downloads and copies the shinylive assets and puts them in there. And then it also copies the application files and puts them in there. And so now we have a directory, we'll take a look here, a directory called site. And then we can test, hey, can I actually serve this site directory and have people run my application? So we'll just run the simple web server, Python web server, and look at visit localhost. And then it will load the application right here. All right, now at this point, this is when you can take that set of files and just upload it to your static web hosting service, whatever that may be.

Deployment model comparison

Let's take a look at the deployment model here. So for traditional Shiny app deployment, you have a server that's running R or running Python. And computers connect to it. And when they connect to it, they maintain this open connection. The user interacts with it a little bit. It sends data to the server. The server does some computation, and it sends some information back. For shinylive app deployment, you have a server that doesn't run R or Python. When the user connects to it, it sends Python and the app code and Shiny, of course, to those computers. And all of that stuff runs inside of those client computers. And it's very easy for a server to just send those files. That's not a computationally intensive thing to do. So you can serve a lot of users this way.

Benefits and limitations

Let's talk about the benefits of shinylive, to summarize. So the entire application runs on the client instead of the server, so there's no computational load on the server. It's really easy to share these applications. It's easy to deploy them to a static web hosting service. And it's easy to scale them, because that's what these static web hosting services do. That's their bread and butter, and it's very cheap. And it works on devices without Python installed, so like Chromebooks or iPads or phones. And this is not just for viewing the application, but you can even edit the applications and play with them on there.

So it's not all sunshine and rainbows. There's also a few drawbacks and limitations. So one is that not all packages are available on Pyodide. So Pyodide contains a lot of packages in the Python scientific stack, including pandas and matplotlib, but not all packages for Python. You can install packages from PyPI if they're written in pure Python and don't have any compiled code. So hopefully this situation will improve in the future, but that's what it is right now.

The code and data for the application is sent to the web browser, so there's no secrets. Somebody can, in principle, look at all the code and data for your application, if they can see your app. It's not good for large amounts of data, like if you've got 100 megabytes of data that your application is operating on, you probably don't want to send that to somebody's web browser. That's a lot. It's not unheard of, but that is a lot.

So the download size, for a basic application, the browser will download about 13 megabytes of stuff, and if you're loading packages from there, like pandas, it's just going to go up from there. But fortunately, browser caching will speed up subsequent visits. So the first time somebody views it, it might be slow, and especially in this conference Wi-Fi, the first time you visit one of these may be a little bit slow, but then in later visits it should be really, really fast. And finally, the browser security sandbox restricts network connectivity.

But the good news is, if shinylive doesn't work for your application, you always have the option to do a traditional Shiny app deployment. You can learn this one framework, Shiny, and when it's appropriate, deploy it with shinylive, and if that doesn't work for you, you can deploy it with a traditional deployment, just by learning one framework.

So this is where you can learn more about it, shiny.rstudio.com.py. There's a link at the top for shinylive. So also, it's still experimental. Please keep that in mind. We're still learning a lot about it, and, you know, so we can't wait to see what you're going to do with it, because we want to learn what kinds of possibilities people, what the possibilities are, and hopefully you'll be able to teach us that. And of course, I know everyone is thinking about this, yes, we're hoping to do this with Shiny for R, but there's a lot of work that needs to be done before we can get started on this. Thank you.