Build a Coding Playground

Add an editable Python source panel to an embedded Gradio app and control the editor layout.

A coding playground places a Python editor beside the Gradio app preview. Readers can change the source and run it again without rebuilding the Quarto document.

Enable one playground

Add gr-playground: true to the Python launch cell:

playground.qmd
---
filters:
  - gradio
execute:
  enabled: false
---

::: {#6a0490f7 .cell gr-playground='true' gr-layout='vertical'}
``` {.python .cell-code}
import gradio as gr

gr.Interface(
    fn=lambda name: f"Hi {name}!",
    inputs="textbox",
    outputs="textbox",
).launch()
```
:::
Code
import gradio as gr

gr.Interface(
    fn=lambda name: f"Hi {name}!",
    inputs="textbox",
    outputs="textbox",
).launch()
import gradio as gr gr.Interface( fn=lambda name: f"Hi {name}!", inputs="textbox", outputs="textbox", ).launch()

Click Run in the editor to start or rerun the app. Change the greeting and run the source again to verify that the preview updates.

gr-layout: vertical stacks the editor above the preview. horizontal places them side by side. Vertical layout is easier to use in a narrow content column.

Enable every playground in a document

Put the attribute in document metadata when every app should expose its source editor:

playgrounds.qmd
---
filters:
  - gradio
execute:
  enabled: false
gradio:
  attributes:
    playground: true
---

::: {#a95c0b5e .cell}
``` {.python .cell-code}
import gradio as gr

gr.Interface(
    fn=lambda name: f"Hi {name}!",
    inputs="textbox",
    outputs="textbox",
).launch()
```
:::
Code
import gradio as gr

gr.Interface(
    fn=lambda name: f"Hi {name}!",
    inputs="textbox",
    outputs="textbox",
).launch()
import gradio as gr gr.Interface( fn=lambda name: f"Hi {name}!", inputs="textbox", outputs="textbox", ).launch()

Document metadata supplies a default to every app. A cell option on a launch cell overrides the matching document-wide attribute:

#| gr-playground: false
demo.launch()

The gr- prefix belongs to the authored cell option. The filter removes it and emits the playground attribute on <gradio-lite>.

Use playgrounds for exercises

The editor can hold a small exercise and its runnable checks:

In this exercise, implement a function that reverses each word while preserving word order. For example, Hello World becomes olleH dlroW.

Code
import gradio as gr

def reverse_words(sentence):
    return "CHANGE ME"

def check_solution(user_input):
    expected = " ".join(word[::-1] for word in user_input.split())
    result = reverse_words(user_input)
    status = "Correct" if result == expected else "Try again"
    return result, expected, status

with gr.Blocks() as demo:
    gr.Markdown("# Reverse Words Exercise")
    input_text = gr.Textbox(label="Sentence", value="Hello World")
    output_user = gr.Textbox(label="Your output")
    output_expected = gr.Textbox(label="Expected")
    status = gr.Textbox(label="Status")
    gr.Button("Check").click(
        check_solution,
        input_text,
        [output_user, output_expected, status],
    )

demo.launch()
import gradio as gr def reverse_words(sentence): return "CHANGE ME" def check_solution(user_input): expected = " ".join(word[::-1] for word in user_input.split()) result = reverse_words(user_input) status = "Correct" if result == expected else "Try again" return result, expected, status with gr.Blocks() as demo: gr.Markdown("# Reverse Words Exercise") input_text = gr.Textbox(label="Sentence", value="Hello World") output_user = gr.Textbox(label="Your output") output_expected = gr.Textbox(label="Expected") status = gr.Textbox(label="Status") gr.Button("Check").click( check_solution, input_text, [output_user, output_expected, status], ) demo.launch()

Keep the starting code small and make the expected interaction explicit. The Python source is delivered to every reader, so a playground is not a place for hidden solutions or secrets.

Runtime behavior

The playground uses the same frozen Gradio Lite runtime as an embedded app. Running edited code recreates the app inside the browser environment. Package installation, worker isolation, network access, and compatibility constraints still apply.

See the configuration reference for attribute scope and precedence. Read Runtime and Trust before adding remote packages or changing the runtime.