๐Ÿ› Enable Coding Playground

This guide will show you how to convert your Gradio app into a coding playground embedded in your Quarto document. Along the way, you will also learn how to specify custom options for your embedded app that the quarto-gradio extension will understand and apply.

Specifying Attributes

Fortunately, the @gradio/lite library does all the heavy lifting for us under the hood. All we need to do is to pass the playground attribute to the internal <gradio-lite/> HTML tag, as the Gradio Lite documentation describes.

The quarto-gradio extension allows you to specify attributes both at the document level in YAML metadata and at the code block level using the #| prefix in comments.

Document Level

Specifying attributes in the document frontmatter is the easiest way to apply configuration to all Gradio apps in your document.

---
filters:
  - gradio

gradio:
  attributes:
    playground: true
---

```{python}
import gradio as gr

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

Thanks to the presence of playground: true in the gradio.attributes metadata, our Gradio app will be rendered in its interactive mode.

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()

The extension reads all key-value pairs from gradio.attributes and passes them to the <gradio-lite/> tag as HTML attributes.

That is, the following YAML metadata

gradio:
  attributes:
    playground: true

will prompt the extension to generate the following HTML tag:

<gradio-lite playground>...</gradio-lite>

Code Block Level

In some cases it is desired to specify attributes on a per-code block basis. This can be done using the #| prefix in comments. An important details is that attribute names must be prefixed with gr- to avoid conflicts with other Quarto attributes.

---
filters:
  - gradio
---

```{python}
#| gr-playground: true
#| gr-layout: vertical
import gradio as gr

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

Just as above, the playground attribute is recognized by the extension and it makes sure that the Gradio app is rendered in its interactive mode. In addition, as the layout attribute is specified to be vertical via #| gr-layout: vertical, the code editor and the resulting app are laid out vertically instead of the default horizontal layout.

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()

Use Case: Online Coding Challenge

Thanks to this embedding mechanism, it is straightforward to create online coding challenges and bite-sized exercises backed by a Gradio UI. If you use Quarto for educational content where writing Python in any way is required, this might be a good way to make your content more interactive and keep your audience engaged.

Challenge: Reverse Words

In this coding challenge, youโ€™ll implement a function that reverses each word in a sentence while maintaining word order. For example, โ€œHello Worldโ€ should become โ€œolleH dlroWโ€. Try implementing the reverse_words function below!

Code
import gradio as gr

def reverse_words(sentence):
    # You should implement: "Hello World" -> "olleH dlroW"
    # return " ".join(word[::-1] for word in sentence.split())
    return "CHANGE ME"

def check_solution(user_input):
    correct = " ".join(word[::-1] for word in user_input.split())
    user_result = reverse_words(user_input)
    return user_result, correct, "โœ… Correct!" if user_result == correct else "โŒ Try again!"

with gr.Blocks() as demo:
    gr.Markdown("# Reverse Words Challenge")
    input_text = gr.Textbox(label="Sentence", value="Hello World")
    output_user = gr.Textbox(label="Your Output")
    output_correct = gr.Textbox(label="Expected")
    result = gr.Textbox(label="Result")
    gr.Button("Check").click(check_solution, input_text, [output_user, output_correct, result])

demo.launch()
import gradio as gr def reverse_words(sentence): # You should implement: "Hello World" -> "olleH dlroW" # return " ".join(word[::-1] for word in sentence.split()) return "CHANGE ME" def check_solution(user_input): correct = " ".join(word[::-1] for word in user_input.split()) user_result = reverse_words(user_input) return user_result, correct, "โœ… Correct!" if user_result == correct else "โŒ Try again!" with gr.Blocks() as demo: gr.Markdown("# Reverse Words Challenge") input_text = gr.Textbox(label="Sentence", value="Hello World") output_user = gr.Textbox(label="Your Output") output_correct = gr.Textbox(label="Expected") result = gr.Textbox(label="Result") gr.Button("Check").click(check_solution, input_text, [output_user, output_correct, result]) demo.launch()

Next Steps

So far, than only non-standard Python module our examples used was gradio. We clearly want to take advantage of Pythonโ€™s rich ecosystem of libraries, so in the next guide we will cover how to install custom Python packages to our in-browser Python environment.