Embedding Shinylive Python Apps in Quarto Documents

Integrate Serverless Interactive Shiny Apps in Your Quarto Content

Learn how to embed Shinylive Python applications directly into your Quarto documents. This tutorial covers the setup of the Shinylive Quarto extension and provides examples of embedding interactive Python apps that run entirely in your browser.

Tools
Author
Affiliation
Published

March 20, 2025

Keywords

embed Shinylive Python, Quarto shiny integration, serverless Shiny in Quarto

Introduction

Interactive, serverless Shiny apps built with Python can be seamlessly integrated into your Quarto documents, allowing you to enrich your blog posts and articles with dynamic, live content. Using the Shinylive Quarto extension, you can embed these apps so that users can interact with them directly on your website.



1. Prerequisites

Before embedding a Shinylive Python app in your Quarto document, ensure that you have the following:

  • Quarto Installed: Download from quarto.org.

  • Shinylive Python Package: Install it from PyPI using:

    pip install shinylive --upgrade
  • Shinylive Quarto Extension: Add the extension to your project by running:

    quarto add quarto-ext/shinylive
  • Document YAML Configuration: In your document (or _quarto.yml), include the shinylive filter:

    filters:
      - shinylive

2. Embedding a Basic Shinylive Python App

To embed a Shinylive Python app, use a code block marked with {shinylive-python}. Include the option #| standalone: true to indicate that the code represents a complete application.

Example: “Hello Shinylive Python” App

Below is an example of a basic interactive Shiny for Python app embedded in a Quarto document:

Source

```{shinylive-python}
#| standalone: true
#| viewerHeight: 650

from shiny import App, ui, render
import numpy as np
import matplotlib.pyplot as plt

# Define the user interface
app_ui = ui.page_fluid(
    ui.input_slider("bins", "Number of bins:", 5, 30, 10, step=1),
    ui.output_plot("histPlot")
)

# Define the server logic
def server(input, output, session):
    @output
    @render.plot
    def histPlot():
        # Generate random data for demonstration
        x = np.random.normal(0, 1, 1000)
        # Create bins based on slider input
        bins = np.linspace(x.min(), x.max(), input.bins() + 1)
        plt.figure(figsize=(8, 4))
        plt.hist(x, bins=bins, color="skyblue", edgecolor="white")
        plt.title("Interactive Histogram of Random Data")
        plt.xlabel("Value")
        plt.ylabel("Frequency")
        plt.show()

# Create the Shinylive app
app = App(app_ui, server)
```

Output

Note

When you run the code block, an interactive app will appear directly in your document. Users can adjust the slider to update the histogram in real time.

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 650

from shiny import App, ui, render
import numpy as np
import matplotlib.pyplot as plt

# Define the user interface
app_ui = ui.page_fluid(
    ui.input_slider("bins", "Number of bins:", 5, 30, 10, step=1),
    ui.output_plot("histPlot")
)

# Define the server logic
def server(input, output, session):
    @output
    @render.plot
    def histPlot():
        # Generate random data for demonstration
        x = np.random.normal(0, 1, 1000)
        # Create bins based on slider input
        bins = np.linspace(x.min(), x.max(), input.bins() + 1)
        plt.figure(figsize=(8, 4))
        plt.hist(x, bins=bins, color="skyblue", edgecolor="white")
        plt.title("Interactive Histogram of Random Data")
        plt.xlabel("Value")
        plt.ylabel("Frequency")
        plt.show()

# Create the Shinylive app
app = App(app_ui, server)

3. Customizing the Embedded App

You can enhance the embedded app by: - Displaying the Code Editor:
Add #| components: [editor, viewer] to show both the source code and the running app. - Changing Layout:
Use #| layout: vertical to stack the editor and viewer vertically. - Adjusting Viewer Height:
Set #| viewerHeight: 420 (or your preferred value) to control the app’s display area.

Example: Editable App

Source
```{shinylive-python}
#| standalone: true
#| components: [editor, viewer]
#| layout: vertical
#| viewerHeight: 650

from shiny import App, ui, render
import numpy as np
import matplotlib.pyplot as plt

app_ui = ui.page_fluid(
    ui.input_slider("bins", "Number of bins:", 5, 30, 10, step=1),
    ui.output_plot("histPlot")
)

def server(input, output, session):
    @output
    @render.plot
    def histPlot():
        x = np.random.normal(0, 1, 1000)
        bins = np.linspace(x.min(), x.max(), input.bins() + 1)
        plt.figure(figsize=(8, 4))
        plt.hist(x, bins=bins, color="skyblue", edgecolor="white")
        plt.title("Interactive Histogram of Random Data")
        plt.xlabel("Value")
        plt.ylabel("Frequency")
        plt.show()

app = App(app_ui, server)
```
Note

This example provides an editor and viewer side-by-side, allowing users to modify the code and instantly see the results.

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| components: [editor, viewer]
#| layout: horizontal
#| viewerHeight: 650

from shiny import App, ui, render
import numpy as np
import matplotlib.pyplot as plt

app_ui = ui.page_fluid(
    ui.input_slider("bins", "Number of bins:", 5, 30, 10, step=1),
    ui.output_plot("histPlot")
)

def server(input, output, session):
    @output
    @render.plot
    def histPlot():
        x = np.random.normal(0, 1, 1000)
        bins = np.linspace(x.min(), x.max(), input.bins() + 1)
        plt.figure(figsize=(8, 4))
        plt.hist(x, bins=bins, color="skyblue", edgecolor="white")
        plt.title("Interactive Histogram of Random Data")
        plt.xlabel("Value")
        plt.ylabel("Frequency")
        plt.show()

app = App(app_ui, server)

4. Tips and Best Practices

  • Ensure Extension Installation:
    Confirm that the Shinylive Quarto extension is added to your project and that the shinylive filter is included in your YAML header.
  • Optimize Viewer Settings:
    Use viewerHeight and layout options to adapt the app’s display to your document’s design.
  • Test Locally:
    Always preview your embedded app locally before publishing your document.
  • Check Asset Paths:
    Ensure that all asset paths are correctly configured so that the app loads smoothly.

Further Reading

Conclusion

Embedding Shinylive Python apps in your Quarto documents lets you offer a dynamic, interactive experience directly within your blog posts or articles. By following this tutorial, you’ve learned how to integrate a fully functional Shinylive app, customize its appearance, and provide a seamless interactive experience for your readers. Continue exploring further reading resources to deepen your knowledge and enhance your interactive content.

Back to top

Reuse

Citation

BibTeX citation:
@online{kassambara2025,
  author = {Kassambara, Alboukadel},
  title = {Embedding {Shinylive} {Python} {Apps} in {Quarto}
    {Documents}},
  date = {2025-03-20},
  url = {https://www.datanovia.com/learn/interactive/python/shinylive/quarto-integration.html},
  langid = {en}
}
For attribution, please cite this work as:
Kassambara, Alboukadel. 2025. “Embedding Shinylive Python Apps in Quarto Documents.” March 20, 2025. https://www.datanovia.com/learn/interactive/python/shinylive/quarto-integration.html.