Join the R Community at ShinyConf 2023

Shiny for Python Introduction Article Thumbnail

Introducing Shiny for Python – R Shiny Now Available in Python


Shiny has been an R-exclusive framework from day one. Well, not anymore. At the recent RStudio Conference, RStudio’s CTO Joe Cheng announced Shiny for Python. Finally bringing the widely popular web framework to Python.

As of August 2022, you really shouldn’t use Shiny for Python for mission-critical apps in production. The whole library is still in its very early stages, and a lot is expected to change in the future. Nevertheless, there’s no better time to prepare for the future and maybe (just maybe) even say adios to Dash and Streamlit.

Did you know RStudio is rebranding to Posit? Learn why in our latest blog post.

Table of contents:


What is Shiny and Shiny for Python (Py Shiny)?

In case you’re new to the topic, Shiny is a package that makes it easy to build interactive web applications and dashboards. It was previously limited to R programming language, but RStudio PBC (Posit PBC), the creators of Shiny, announced Shiny for Python.

The R/Python packages are available to download on CRAN/PyPi, so getting started boils down to a single shell command.

Shiny applications can be deployed as standalone web pages or embedded into R Markdown documents (R only). Overall, the deployment procedure is simple and can be done for free to an extent.

Deployment sounds like a nightmare? Here are 3 simplified ways to share Shiny apps.

You can also extend Shiny apps with CSS themes, HTML widgets, and JavaScript actions, in case you ever run into the limitations of the core package itself.

Long story short, there’s nothing you can’t do in Shiny. That claim has more weight on the R side of the story as of now, but Python support will only get better with time.

Up next, let’s see how to install the library.

How to Install and Configure Shiny in Python Ecosystem

Installing Shiny in Python is as simple as installing any other Python package since it’s available on PyPi. Run the following command from the shell:

pip install shiny

In addition, you should also install the following packages if you want to follow along with the code:

  • numpy: Fast and efficient math in Python
  • pandas: Python library for handling data
  • matplotlib: A standard visualization library
  • pandas_datareader: Needed to fetch stock prices from the web (only for this article)
  • jinja2: Needed to render Pandas DataFrames in Shiny apps (only for this article)

Run the following command to install them all:

pip install numpy pandas matplotlib pandas_datareader jinja2

Once that’s out of the way, you can use a shell command to set up a directory structure for the Shiny application. For example, the one below will create a folder demo_app with app.py inside it:

shiny create demo_app

Image 1 - Contents of the demo_app directory

Finally, you can run app.py with the following command:

shiny run --reload demo_app/app.py
Image 2 - Running a Shiny for Python application

Image 2 – Running a Shiny for Python application

It will run the Shiny app locally on port 8000. Once opened in the browser, it looks like this:

Image 3 - The default Shiny for Python application

Image 3 – The default Shiny for Python application

The app doesn’t look bad and shows you how easy it is to get started with Shiny in Python. The underlying source code can be found in app.py. Here’s what it contains:

from shiny import App, render, ui

app_ui = ui.page_fluid(
    ui.h2("Hello Shiny!"),
    ui.input_slider("n", "N", 0, 100, 20),
    ui.output_text_verbatim("txt"),
)


def server(input, output, session):
    @output
    @render.text
    def txt():
        return f"n*2 is {input.n() * 2}"


app = App(app_ui, server)

If you have any experience in R Shiny, this Python script will look familiar. Sure, Python doesn’t use $ to access methods and properties, and also uses function decorators for rendering. It’s a different syntax you’ll have to get used to, but it shouldn’t feel like a whole new framework.

Next, we’ll code a Shiny dashboard from scratch to get familiar with the library.

Make Your First Shiny Dashboard in Python

We’re going to make a simple stock monitoring app. It will allow you to select a stock and inspect its 30-day performance, both visually and through a table. The table will show more metrics, such as open and close price, volume, and so on. The chart will show only the adjusted close price per day.

The data is fetched from Yahoo Finance through the pandas_datareader library. It will automatically download single stock data based on a selected stock name, and rerender the table and chart as soon as you make any change.

We’ve also decided to include a bit of custom CSS, so you can see how easy it is to tweak the visuals.

Here’s the full code snippet for app.py:

import matplotlib.pyplot as plt
from datetime import datetime, timedelta
from shiny import App, render, ui, reactive
from pandas_datareader import data as pdr
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.right"] = False


# Configuration
time_end = datetime.now()
time_start = datetime.now() - timedelta(days=30)
tickers = {"AAPL": "Apple", "MSFT": "Microsoft", "GOOG": "Google", "AMZN": "Amazon"}

# App UI - One input to select a ticker and two outputs for chart and table
app_ui = ui.page_fluid(
    # Adjust the styles to center everything
    ui.tags.style("#container {display: flex; flex-direction: column; align-items: center;}"),
    # Main container div
    ui.tags.div(
        ui.h2("Historical Stock Prices"),
        ui.input_select(id="ticker", label="Ticker:", choices=tickers),
        ui.output_plot("viz"),
        ui.output_table("table_data"),
    id="container")
)


# Server logic
def server(input, output, session):
    # Store data as a result of reactive calculation
    @reactive.Calc
    def data():
        df = pdr.get_data_yahoo(input.ticker(), time_start, time_end)
        return df.reset_index()

    # Chart logic
    @output
    @render.plot
    def viz():
        fig, ax = plt.subplots()
        ax.plot(data()["Date"], data()["Adj Close"])
        ax.scatter(data()["Date"], data()["Adj Close"])
        ax.set_title(f"{input.ticker()} historical prices")
        return fig


    # Table logic
    @output
    @render.table
    def table_data():
        return data()


# Connect everything
app = App(app_ui, server)

Once launched, here’s what the dashboard looks like:

Image 4 - Stock monitoring Shiny dashboard

Image 4 – Stock monitoring Shiny dashboard

The app is relatively simple but shows you how to work with UI elements and render tables and charts. You can see how we stored fetched stock data as a reactive expression and used it when rendering both UI elements. That is a preferred way over fetching the data twice.

You now know how to make basic Shiny apps in Python, so let’s wrap things up next.


Summary of Shiny for Python (Py Shiny)

Bringing Shiny to Python is definitely a good step forward for the web framework and RStudio (Posit). The library is still in alpha, so a lot is expected to change in the future. You may find some things buggy, so we don’t advise using it in production environments at the moment. It will get better and more feature-rich with time, so stay tuned to our blog for updates.

P.S. – With Shiny for Python you can also run applications entirely in the browser using an experimental mode: Shinylive. We’ll explore this topic in future posts so be sure to subscribe to our Shiny Weekly newsletter.

What are your thoughts on Shiny for Python? Is it something you’ve been waiting for or you’re happy to stick with R? Please let us know in the comment section below. Also, feel free to continue the discussion on Twitter – @appsilon. We’d love to hear your thoughts.

Want to use R and Python together? Here are 2 packages you must try.