Create and Deploy a Python Shiny Express Application to Connect Cloud
videoimage: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
Hello, I'm Daniel. I'm one of the data science educators here at Posit. Today, I want to show you how to create a Shiny dashboard in Python from scratch and deploy it to connect cloud for free. So let's get started. We're going to be using Positron to create the application and a project that we're going to be working with today. The first thing that we're going to do is create a new folder for our project.
The next thing I want to do is use UV in Python to set up our Python environment. We can use UV init to create the environment and its packages. And right now we won't need the main.py file so we can delete it. Next, we can use UV add to add the packages we'll need for this project. Here, we'll be using the Shiny palmer penguins and plot nine libraries to make our dashboard.
Now that I'm in package and the environment's all set up, we want to make sure that Positron has the right environment loaded. In the top right of Positron, you can click on the interpreter session logo and choose the folder that you just have opened. This will load up the environment that we just created so we can start coding with the packages that we just installed.
App preview and initial code setup
Here's the application that we'll be making today. It is a histogram of the palmer penguins data set. Looking at the build link, we have a series of radio buttons at the top that allow us to toggle between Adelie, Gentoo, and chinstrap penguins. As we select a different penguin, the selected penguin values in the histogram will be highlighted.
So let's come back to Positron. The first thing I like to do when I'm designing in a Shiny application from the beginning is to just get the raw code working outside the context of a dashboard. So let's go and do that. I'll create a new file called code.py. And here, we'll make sure that we can get the code for our histogram already. This way, we can separate the code that we're writing from the dashboarding components. So if something goes wrong, it makes it a little bit easier to debug our problem. First, the package that we're going to use for our Palmer's penguin data set is the Palmer's penguin package. Next, we can load the actual data set. And here, we have the actual Palmer's penguins data set loaded.
Next, we want to go and create an actual histogram. To do that, we'll use the plot nine library. We can then use the ggplot function to go and plot our histogram.
Here's our base histogram showing the bill length across all of the penguins. Let's clean up the theme a little bit. We can do this by using the theme underscore minimal font. Next, let's go add a bit of color to the base histogram so we can see the other penguin that gets selected when it's overlaid on top.
Great. Now let's go and write the code so we can select a species of penguin and collect just the subset of data for that selected species. Since we know that we're going to put this into a dashboard, it's a good idea to make sure that you have a variable that serves as a placeholder where UI components in the dashboard can go and update and change. This way, you don't have to go around into your code and change multiple things. All you need to do is specify a variable and reuse that variable across the application later on. Right now, I'm selecting the Gintu penguin. So let's also write the code to subset our data for the Gintu penguins.
Now let's go and take the selected data frame and overlay it on top of our base histogram. Let's go pick a different color for the overlay. Here you can see we now have the ability to overlay one color on top of another. If we want, we can change the species of penguin, run our code, and you'll see that we'll get another histogram for that selected penguin. The problem here is each dataset has its own different range, so the bin widths are not consistent. So let's go and change that.
Great. Now we have the baseline application that we can use to create a dashboard. Now we have the species variable that we can change from different dashboard components to change the overlay that represents the subset of the species we've selected.
Exploring Shiny components
Here's the official Shiny for Python website. What we can do is click on components and go to the components gallery. We'll look at all the different types of inputs and outputs that we can make for our application. Here's a section just looking at the input components. What we're looking for right now are radio buttons. Radio buttons are a type of input component that allows us to choose one option from a menu of other options. Radio buttons are particularly useful if you have a few options and don't need that much space on the application, so you can fill all of the options all at once. The general rule of thumb I have, if it's something below five options or fewer, I might think about radio buttons instead of using a dropdown.
The general rule of thumb I have, if it's something below five options or fewer, I might think about radio buttons instead of using a dropdown.
The components library gives you a bit of example code to run the actual component, but here in this example, we'll just type it all out from scratch. Let's go and create the base Shiny dashboard code right now. We'll create a new file and call it app.py. When a file begins with the prefix app, Shiny and Positron can run the application by pressing the little play button at the very top. First, let's go and use the radio button from Shiny. The first thing we're going to do is load up Shiny Express.
This gives us access for all of the input UI components that we'll be creating. The component we'll be making is going to be the input radio button. To create a UI component, we first have to give it an ID. This ID is something that we can use to look up the value that gets selected by this particular component. Next is the label that we can use to give the component a title on the application. Finally, the last thing we need to give it are the various options.
Now let's go and run the Shiny application. To do so, in Positron, you can click the little play button while you are looking at the app.py file, and we'll go use Shiny to run the application.
Here's our current Shiny application. It's got a label for species, and as we click the different choices, we can refer to the different options that we can use to run the application. As we click the different choices, we can refer to these individual selected options by looking at the species ID. We'll do that in a little bit. Back to the Shiny for Python documentation page, we can click on reference and look at the various Shiny for Python references available to us. Here we can look at radio buttons. One of the parameters for the radio button is the inline argument. This allows us to put in radio buttons that show up horizontally instead of vertically.
By default, it's selected to false. Let's change that and set the inline to true. When we save the file, and because we are running the Shiny application through the button, it will auto-reload the application as it saves. Here you can see after we put in the inline option to be equals to true, the species are now listed horizontally. Great! Now let's go and put in the actual code for our dashboard. We can borrow a lot from the existing code that we have.
Building the dashboard
We can go and change the import order. We're loading our data set. We're selecting our species. We're filtering our data and loading the application. You can see here just by showing the figure in our Shiny application now, it's causing the application to fail. And it's because this figure doesn't know how to get rendered in a dashboard application. To help with that, we can go back to the Shiny for Python documentation page and go back to the components gallery.
And scroll down to the section for outputs. Shiny for Python supports various outputs. The output that we're going to be looking at is going to be around matplotlib. Many static plotting libraries are all built on top of matplotlib. So the documentation from matplotlib in Shiny will work for matplotlib, seaborn, plot9, etc. Here's the example matplotlib code. And looking at the component gallery documentation, the main thing that we need to do is call this render.plot decorator. We also need to put in our figure into a function.
Let's go and make those changes to our application. The first thing that we're going to need is to import the render module. From there, we can go and use the render plot decorator. This tells Shiny Express that in this area of the application, we wanted to go and render a plot. In order to render the plot, we need to tell Shiny, here is the code that we want it to run in order to render the plot. We can do that by wrapping everything into a function.
Our function is being run, but we have to remember that we have to return an actual figure. Great. Here's the actual figure that's rendering in our dashboard. The next thing we want to do is hook up the actual input components to the actual figure. Right now, we have a separate set of just the radial button input components, but our species is hard-coded to Chinstrap at the moment. What we need to do now is connect the radial button to the actual figure. Because the data that gets filtered is also connected to the species that gets selected, this code also now needs to move into the function that is creating our figure.
We haven't really made any changes to the actual figure yet, and we haven't made the connection from the radial button to the actual rendered plot. In Shiny, there's a special object that keeps track of all of the input components and their IDs so you can use it to capture those values. That object name is called input. We have to import it from Shiny Express. What that allows us to do is use input and the actual plot. It allows us to use input and the ID species to get the value from the radial button that we have selected. Now, since when we started our application, we made a placeholder that we can use for our radial button, we can now use the input value for the species variable.
We do that by calling input and then the ID of the component that we want to capture. We have a radial button with the ID species, and we can capture its selected value by using input.species. We're using it inside our render plot function such that Shiny knows that these two components can react to one another. Here, you can see our application still isn't reacting to one another. That's because when we go and call input.species, we actually need to call it as a function. This is a key component into how Shiny applications run. When you want to go and get the actual value from an input component, you have to call it with a set of round parentheses as a function. Now, you can see our Adelie, Gintu, and Chinstrap penguins are all reacting in our application.
This is a key component into how Shiny applications run. When you want to go and get the actual value from an input component, you have to call it with a set of round parentheses as a function.
Here's the full Shiny application that we just created. We import the packages that we're going to be using. We created our radial buttons at the very top. We have our data set that gets loaded. We now have a figure that gets rendered underneath the radial buttons. We are telling Shiny that we are expecting a figure to be loaded. Here is the code that Shiny will use to render the figure. When it goes and renders the figure, it will go and first find and get the value of the species ID, which is the value that is selected in our radial button. Use that value to subset our data frame and use the full penguins data set along with the selected filter data set to render the figure.
Deploying to Connect Cloud
Now, let's go and take this application and deploy it to Connect Cloud. Connect Cloud can do deployments based off of a GitHub repository. So, we're going to have to do a few things. First, we need to go and turn our current project into a Git repository. Then, we need to push our current repository to a GitHub repository.
Usually, if you know you're going to do a deployment or put your code on GitHub, it's typically much easier to create a GitHub repository first and clone it down to your computer and then start working on your project. In this part of the example, I have to go and create my Git repository locally and on the remote and then hook up all the plumbing to make it work.
Now, let's stop the application and do all of the work that we need to get this published onto Connect Cloud. First, we need to deploy our application. First, we need to turn this project into a Git repo. Now, let's go and commit the files to Git. All the files that we have created in this project are the files we do want to commit and send to GitHub. Next, we need to go and create a GitHub repository to send the code from our local machine to the remote. Typically, if you know that you're going to have a project already on GitHub, it's much easier to go through this process first before creating the application. In other words, you shouldn't need to run Git and Net if you know that you're already going to start your work on GitHub.
Here, I'll name my repository app-template because in this example, we've already created a Git repository on our local machine. In GitHub, it's really important that you make sure you don't start from a template, you don't add a readme, you do not add a gitignore, and you do not add a license. We already have files committed, so all you need to do is click on the green click repository.
Next, I'm going to copy the Git repository URL and set it as a remote in Positron. Next, if I look at Git status, we know that we're on branch name, there's nothing to commit, and our working tree is clean. Finally, we can push our changes from our local machine to GitHub.
What this will do is now have our repository on GitHub. If we go back to the repo, hit refresh, all of our code will be there. Next, we can go and deploy our application to Posit Connect Cloud by going to connect.posit.cloud. You can sign up for a free account, and it can deploy all sorts of different data science artifacts. Here, we'll be deploying a Shiny application.
Once you're logged into Posit Connect Cloud, you should have the option to click the publish button to publish an application. You're going to need to install the GitHub app into your GitHub account. Once the GitHub application is linked to your GitHub account, you should be able to click on Shiny and select your repository. We're going to select the app-penguin repository. The branch that the file is deployed on is on the main branch.
Currently, Connect Cloud only works with requirements.txt files. So, we're going to need to go and create this requirements.txt file in order to have Connect Cloud install all of the dependencies it needs to deploy our application. Let's go back to Positron and the application we just made. In order to create a requirements.txt file, all we need to do is run uv pip freeze requirements.txt. What this will do is it will create a requirements.txt file, linking all of the packages and the versions into a file that can be used to install on Connect Cloud.
Now, we're going to add and commit this file. And then, I'm going to push the changes back up. Now, when we go and select the same options again, Connect Cloud will recognize everything that it needs to go and deploy this application. The last thing we need to do is hit publish.
And there you go. Now, you have a ready-to-use application that you can use to deploy your application. And there you go. Now, you have the application that we just created locally, and we pushed it to GitHub and use Posit Connect Cloud to deploy this application. You now have a publicly available application that you can share with anyone. And there you have it, a Shiny dashboard that you have created from scratch on your local machine and got it working and deployed it to Connect Cloud. And now, you have something that you can share with other people.
Thanks for watching this video. Stay tuned for more tips, tricks, and tutorials on how you can be more effective with your data science work.

