Slide 1

Slide 1 text

Joe Cheng (@jcheng) Posit PBC 
 PyData Seattle 2023 Shiny for Python Data-centric web applications in Python

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

About Shiny • Create interactive apps and dashboards in Python • Designed primarily with data scientists in mind • No HTML, CSS, or JavaScript skills required • Easy-to-use “reactive programming” approach to interactivity • But also designed with me in mind • Fully leverage HTML, CSS, and JavaScript skills if you have them • Reactive programming is powerful, fl exible, and deep—you’ll never outgrow it

Slide 4

Slide 4 text

from shiny import App, render, ui import numpy as np import matplotlib.pyplot as plt app_ui = ui.page_f i xed( ui.input_slider("n", "N", 0, 100, 20), ui.output_plot("plot"), ) def server(input, output, session) : @output @render.plot(alt="A histogram") def plot() : x = 100 + 15 * np.random.randn(input.n()) plt.hist(x, bins=7, density=True) app = App(app_ui, server) Anatomy of a Shiny app User interface Generates HTML to send to the browser Server logic Runs on the server, providing interactivity App object UI + server + options

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

app_ui = ui.page_f i xed( ui.tags.h3("Air mass calculator"), ui.div( ui.markdown( """This Shiny app uses [Astropy](https: / /w ww .astropy.org/) to calculate t altitude (degrees above the horizon) and airmass (the amount of atmospher air along your line of sight to an object) of one or more astronomical objects, over a given evening, at a given geographic location. """ ), class_="mb-5", ), ui.row( ui.column( 8, ui.output_ui("timeinfo"), ui.output_plot("plot", height="800px"), class_="order-2 order - sm-1", ), ui.column( 4,

Slide 8

Slide 8 text

class_="order-2 order - sm-1", ), ui.column( 4, ui.panel_well( ui.input_date("date", "Date"), class_="pb-1 mb-3", ), ui.panel_well( ui.input_text_area( "objects", "Target object(s)", "M1, NGC35, PLX299", rows=3 ), class_="pb-1 mb-3", ), ui.panel_well( location_ui("location"), class_="mb-3", ), class_="order-1 order - sm-2", ), ), )

Slide 9

Slide 9 text

app_ui = ui.page_f i xed( ui.tags.h3("Air mass calculator"), ui.div( ui.markdown( """This Shiny app uses [Astropy](https: / /w ww .astropy.org/) to calculate the altitude (degrees above the horizon) and airmass (the amount of atmospheric air along your line of sight to an object) of one or more astronomical objects, over a given evening, at a given geographic location. """ ), class_="mb-5", ), ui.row( ui.column( 8, ui.output_ui("timeinfo"), ui.output_plot("plot", height="800px"), class_="order-2 order - sm-1", ), ui.column( 4, ui.panel_well( ui.input_date("date", "Date"), class_="pb-1 mb-3", ), ui.panel_well( ui.input_text_area( "objects", "Target object(s)", "M1, NGC35, PLX299", rows=3 ), class_="pb-1 mb-3", ), ui.panel_well( location_ui("location"), class_="mb-3", ), class_="order-1 order - sm-2", ), ), )

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

“Just so easy” script.py Streamlit st.slider() st.write() st.pyplot() Shiny app_ui = def server() : app = App()

Slide 13

Slide 13 text

Streamlit documentation, “Main concepts” “Streamlit’s architecture allows you to write apps the same way you write plain Python scripts. To unlock this, Streamlit apps have a unique data flow: any time something must be updated on the screen, Streamlit reruns your entire Python script from top to bottom.”

Slide 14

Slide 14 text

Streamlit is easy, until it’s not • Simple Streamlit apps: top-to-bottom execution model • Yes, it really is that easy! • Nice output; hard to create bad-looking apps • Slow performance and limited interactivity • Less-simple Streamlit apps: top-to-bottom execution model plus caching, callbacks, and Session State • Danger zone: tricky to get right, leads to subtle bugs and complexity explosion

Slide 15

Slide 15 text

Streamlit is easy, until it’s not

Slide 16

Slide 16 text

Reactivity is approachable and scalable

Slide 17

Slide 17 text

Down the reactive programming rabbit hole Ten years in, we’re still fi nding new techniques that “fall out” of reactive programming • Inputs/outputs • Selective suppression of reactive signals (isolate()) • Event handlers (@event) • Time-based reactivity (invalidate_later) • Dynamic dependency graphs • Pause/resume outputs and actions • Streaming inputs • File monitoring/database polling • Reactives as monads • Higher-order reactives • Reduce (over time, not space) • Throttle/debounce • Suppressing duplicate values

Slide 18

Slide 18 text

Demos chat_ai: Chat AI package for Shiny for Python https://github.com/wch/chat_ai

Slide 19

Slide 19 text

Demos Brownian motion

Slide 20

Slide 20 text

Shinylive: Shiny + WebAssembly • Full stack Python web apps, powered entirely within the browser • Demo: https://shinylive.io/py/examples/#cpu-info • Share via shinylive.io, or deploy on any static web host • Can be easily embedded within Quarto documents • Also powers all of our documentation

Slide 21

Slide 21 text

Shiny UI Editor

Slide 22

Slide 22 text

Thank you! Learn more at https://shiny.posit.co/py/ Examples Articles API docs Code samples at https://github.com/jcheng5/PyDataSeattle-2023