BAA1028 - Workflow & Data Management
Enter the world of interactive Python in the browser. Running code directly in the browser opens the door for many new and exciting uses for data science on the web.
This is thanks to the amazing technology brought to you by Pyodide. But first, let’s talk about WebAssembly.
WebAssemby is a low-level, high-performance binary instruction format that allows code to run in web browsers.
Python has had a browser solution for a while. Pyodide compiles the Python interpreter CPython to WebAssembly using Emscripten, making it possible to run Python in the browser.
It is possible to run python code directly in a web browser without the need for traditional servers to execute the code. All that is required is a web server such as GitHub Pages or Netlify.
A server is a type of computer that is operating 24/7 on the internet that is interacting with your own computer.
We can think of servers in two ways:
Note
There are more types of servers available; but, our discussion rests solely on those two.
Note
We can substitute the R logo with Python’s in these diagrams.
Outside of the Python packages built-in to Pyodide, the number of Python packages varies as there is no central repository.
*py3-none-any.whl
), then the package can be used as-is.
basic-colormath
on PyPI*-cp310-cp310-emscripten_3_1_27_wasm32.whl
Install the package:
Import the pyodide class:
const { loadPyodide } = require("pyodide");
let pyodide = await loadPyodide();
await pyodide.runPythonAsync("1+1");
What if you don’t know JavaScript? 😅
pyodide aims to be as quick and easy to use as possible for those familiar with JavaScript web development, which raises the question… what if you don’t know Javascript?
---
title: "quarto demo"
format:
html:
code-fold: true
---
## Meet Quarto
Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see <https://quarto.org>.
```{python}
#| label: plot-penguins
#| echo: false
#| message: false
#| warning: false
import seaborn as sns
import matplotlib.pyplot as plt
from palmerpenguins import load_penguins
penguins = load_penguins()
custom_palette = {"Adelie": "darkorange", "Chinstrap": "purple", "Gentoo": "cyan4"}
plt.figure(figsize=(8, 6))
sns.scatterplot(
data=penguins,
x="flipper_length_mm",
y="bill_length_mm",
hue="species",
style="species",
palette=custom_palette
)
plt.title("Flipper and Bill Length")
plt.suptitle("Dimensions for Penguins at Palmer Station LTER", fontsize=10)
plt.xlabel("Flipper Length (mm)")
plt.ylabel("Bill Length (mm)")
plt.legend(title="Penguin Species")
sns.set_style("whitegrid")
plt.show()
```
Quarto extensions let you customize and extend Quarto’s functionality beyond its built-in features.
For example, there’s a fontawesome extension.
Install the extension:
Add to your Quarto document YAML heading:
Use the extension in the doc:
Results in:
Quarto extension gallery by Mickaël Canouil
Quarto Live allows you to embed WebAssembly-powered code blocks and exercises in Quarto documents through the quarto-live extension. There’s support for Python via Pyodide.
Features include interactive code blocks, exercises with hints and solutions, and rich output like plots. And most importantly, web development skills are not needed to use Pyodide in your content.
Quarto Live embeds WebAssembly powered code blocks and exercises for Python into Quarto documents with HTML-based output formats.
After a short loading period, a Run code button will appear. Python code can be edited and executed in an editor like this one.
Install the extension:
Add to your Quarto document YAML header:
Install the extension:
Add to your Quarto document YAML header:
pyodide
code chunk for Python{quarto-pyodide} Extension in Action
Shiny allows you to create web apps, no web development skills required.
Each Shiny app consists of:
When an input changes, Shiny reacts by rebuilding the outputs that depend on it, and only those outputs.
Updates:
Notice:
ui.Input_
.Notice:
@render.
decoratorPython has a convenient syntax for decorators. So these would do the same thing:
Use an input value to build an output.
To access an input’s value, call input.<id>()
where <id>
is the string you passed to the input, e.g:
Value:
The traditional way of deploying Shiny involves in a separate server and client. A server is a machine, connected to the Internet, that runs 24/7, ready to run your Shiny app. The server runs Python and Shiny, and clients connect via the web browser.
Each client keeps an open websocket connection as long as they are using the application.
Shiny Express is designed to make it significantly easier to get started with Shiny, and to write simple apps with a minimum of boilerplate.
Here’s what a simple “Hello, World” app looks like in Shiny Express:
Ui and server do not have to be separate in Shiny Express
from shiny import render, ui
from shiny.express import input
ui.panel_title("Hello Shiny!")
ui.input_slider("n", "N", 0, 100, 20)
@render.text
def txt():
return f"n*2 is {input.n() * 2}"
ui.panel_title("Hello again Shiny!")
ui.input_slider("z", "Z", 50, 100, 70)
@render.text
def txt2():
return f"Z*3 is {input.z() * 3}"
The ui.input_text()
function creates a text input, and the @render.text
decorator makes the output of the greeting()
function appear on the page.
After installing Shiny with pip install shiny
, you can save this code as app.py
and start the app with shiny run app.py
.
Or, skip the install and try the app in the online editor.
from shiny import reactive
from shiny.express import input, render, ui
from shinywidgets import render_plotly
ui.page_opts(title="Penguins dashboard", fillable=True)
with ui.sidebar():
ui.input_selectize(
"var", "Select variable",
["bill_length_mm", "bill_depth_mm", "flipper_length_mm", "body_mass_g", "year"]
)
ui.input_numeric("bins", "Number of bins", 30)
@reactive.calc
def df():
from palmerpenguins import load_penguins
return load_penguins()[input.var()]
with ui.card(full_screen=True):
@render_plotly
def hist():
import plotly.express as px
p = px.histogram(df(), nbins=input.bins())
p.layout.update(showlegend=False)
return p
While Shiny Express is easy to pick up, it’s powered by Shiny’s proven reactive programming framework, extensive (and growing) suite of components, and deeply customizable approach to UI—just in a more approachable syntax that minimizes the fuss. It’s suitable for writing everything from throwaway prototypes, to realtime dashboards, to cutting edge model demos, to production-quality business workflow apps.
Shiny Express syntax is now supported within Quarto Dashboards! This makes it even easier to create interactive data dashboards with Shiny and Quarto.
---
title: "Palmer Penguins"
format: dashboard
server: shiny
---
```{python}
#| context: setup
import seaborn as sns
from shiny.express import render, ui, input
penguins = sns.load_dataset("penguins")
```
# {.sidebar}
```{python}
species = list(penguins["species"].value_counts().index)
ui.input_checkbox_group(
"species", "Species:",
species, selected = species
)
```
# Plots
```{python}
@render.plot
def depth():
data = penguins[penguins["species"].isin(input.species())]
return sns.displot(
data, x = "bill_depth_mm",
hue = "species", kind = "kde",
fill = True
)
```
On-Prem
There are options for hosting Shiny apps, i.e., hosting their servers, you could have a Server on your laptop. But say you need scalability or additional security for your app, you could pay Posit money to have them host your servers for you with Posit Connect.
There are also cloud-based solutions like shinyapps.io and Posit Connect. There’s a spectrum in terms of number of users, for some, it might just be a few people and for others, we’re talking thousands.
Some web services offer scalability, features, and cost:
But they can’t run traditional Shiny apps!
This is static web hosting. And it’s great in terms of reach and affordabilty. You don’t have to think about servers anymore, you just give them your app files. But, there’s no way to run Shiny apps or dynamic Python code.
Shinylive uses Pyodide to enable fully in-browser Shiny apps without a backend. It offers an online editor, conversion of existing Shiny apps, and embedding Shiny apps in Quarto documents.
With Shinylive, anybody can create their own serverless Shiny apps to run in the browser.
#| standalone: true
#| viewerHeight: 500
library(shiny)
library(bslib)
ui <- page_sidebar(
title = "Simple Shiny App",
theme = bs_theme(bootswatch = "flatly"),
sidebar = sidebar(
numericInput("number", "Enter a number:", value = 5, min = 1, max = 100),
selectInput("color", "Choose color:",
choices = c("red", "blue", "green", "purple"))
),
card(
card_header("Result"),
card_body(
plotOutput("plot")
)
)
)
server <- function(input, output) {
output$plot <- renderPlot({
plot(1:input$number,
col = input$color,
pch = 19,
cex = 2,
main = "Simple Plot",
xlab = "Index",
ylab = "Value")
})
}
shinyApp(ui, server)
All you need to run Shinylive is one of these static web servers. When an application is deployed with Shinylive, Python and Shiny run in the web browser: the browser is effectively both the client and server for the application.
There’s an online Shinylive editor for Python. The editor is on the left, so you can change the app in real time. Build it live! You can share apps via the share button, with a URL that you can sent to someone else.
To convert a Shiny app (see Python docs), install the package:
Converting the app takes an app in the my app directory and produces an output directory site and then you can load the files to a static web hosting service.
Start a web server for the directory:
If you want to preview the app, you can run this and it’ll open it up in a web browser.
To embed a Shiny app with Quarto, install the Quarto extension:
Add to your Quarto document YAML heading:
Insert a code block with {shinylive-python}
Pyodide shines in accessibility. Your content can be hosted on any static web hosting service and you can share with just a URL. Users can run code without installing software. It can be run on tablets or mobile. In terms of ease of deployment, you don’t need a supporting computational python server. You can host your code or app on static web hosting services like GitHub Pages.
No secrets with a Shinylive app. All the source code goes to client, all the data goes to the client, don’t include credentials, don’t include sensitive data.
Huge thanks the following people who have generated and shared most of the content of this lecture:
James Balamuta: Dynamic Interactions for R and Python Using Quarto and WebAssembly
Isabella Velásquez: Interactive R, Python, and Shiny in the Browser with Quarto and Shinylive
Deepsha Menghani: Shiny for Python
Gordon Shotwell, Joe Cheng, Garrett Grolemund, and Andrie de Vries: Getting started with Shiny Express
Thanks for your attention and don’t hesitate to ask if you have any questions!
@damien_dupre
@damien-dupre
https://damien-dupre.github.io
damien.dupre@dcu.ie