theme-preview / app.py
hmb's picture
hmb HF Staff
Update app.py
438bed2 verified
import gradio as gr
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse
import uvicorn
BUILTIN_THEMES = ["default", "base", "soft", "monochrome", "glass", "origin", "citrus", "ocean", "spark"]
def load_theme(theme_id: str):
"""Load theme by ID. Supports built-in and Hub themes."""
if not theme_id or theme_id == "default":
return gr.themes.Default()
# Community theme from Hub (e.g., "gradio/seafoam")
if "/" in theme_id:
try:
return gr.Theme.from_hub(theme_id)
except Exception as e:
print(f"Failed to load '{theme_id}' from Hub: {e}")
return gr.themes.Default()
# Built-in theme
builtin = {
"base": gr.themes.Base,
"soft": gr.themes.Soft,
"monochrome": gr.themes.Monochrome,
"glass": gr.themes.Glass,
"origin": gr.themes.Origin,
"citrus": gr.themes.Citrus,
"ocean": gr.themes.Ocean,
}
theme_cls = builtin.get(theme_id.lower())
return theme_cls() if theme_cls else gr.themes.Default()
def process(text, number, checkbox, radio, dropdown):
return f"""**Results:**
- Text: {text}
- Number: {number}
- Checkbox: {checkbox}
- Radio: {radio}
- Dropdown: {dropdown}"""
def make_demo(theme_id: str):
"""Create a demo app with the specified theme."""
theme = load_theme(theme_id)
display_name = theme_id if "/" in theme_id else theme_id.capitalize()
with gr.Blocks(theme=theme, title=f"Theme: {display_name}") as demo:
gr.Markdown(f"# {display_name} Theme")
gr.Markdown("Preview of Gradio components with this theme.")
with gr.Row():
with gr.Column():
text_input = gr.Textbox(
label="Text Input",
placeholder="Type something here...",
info="A standard text input field"
)
number_input = gr.Slider(
minimum=0,
maximum=100,
value=50,
label="Slider",
info="Drag to select a value"
)
checkbox = gr.Checkbox(
value=True,
label="Enable feature",
info="Toggle this option"
)
with gr.Row():
submit_btn = gr.Button("Submit", variant="primary")
clear_btn = gr.Button("Clear", variant="secondary")
stop_btn = gr.Button("Stop", variant="stop")
with gr.Column():
output = gr.Markdown(label="Output")
radio = gr.Radio(
choices=["Option A", "Option B", "Option C"],
value="Option A",
label="Radio Selection"
)
dropdown = gr.Dropdown(
choices=["Choice 1", "Choice 2", "Choice 3"],
value="Choice 1",
label="Dropdown Menu"
)
with gr.Row():
with gr.Column():
gr.Markdown("### Additional Components")
with gr.Tabs():
with gr.Tab("Tab 1"):
gr.Textbox(label="Tab 1 Content", value="Content in first tab")
with gr.Tab("Tab 2"):
gr.Textbox(label="Tab 2 Content", value="Content in second tab")
with gr.Column():
with gr.Accordion("Advanced Settings", open=False):
gr.Slider(0, 10, 5, label="Advanced Option 1")
gr.Slider(0, 10, 3, label="Advanced Option 2")
gr.Checkbox(label="Advanced Toggle")
with gr.Row():
gr.Number(label="Number Input", value=42)
gr.ColorPicker(label="Color", value="#ff7700")
submit_btn.click(
fn=process,
inputs=[text_input, number_input, checkbox, radio, dropdown],
outputs=output
)
clear_btn.click(
fn=lambda: ("", 50, True, "Option A", "Choice 1", ""),
outputs=[text_input, number_input, checkbox, radio, dropdown, output]
)
return demo
# Pre-build demos for all built-in themes
DEMOS = {tid: make_demo(tid) for tid in BUILTIN_THEMES}
# Hub theme cache
HUB_DEMOS = {}
app = FastAPI()
@app.get("/")
async def root(request: Request):
"""Redirect to appropriate theme path based on query param."""
theme = request.query_params.get("theme", "default").lower()
# Handle hub themes
if "/" in theme:
# URL encode the slash for the path
safe_theme = theme.replace("/", "--")
if safe_theme not in HUB_DEMOS:
try:
HUB_DEMOS[safe_theme] = make_demo(theme)
gr.mount_gradio_app(app, HUB_DEMOS[safe_theme], path=f"/{safe_theme}")
except Exception as e:
print(f"Error creating demo for {theme}: {e}")
return RedirectResponse("/default/")
return RedirectResponse(f"/{safe_theme}/")
# Handle built-in themes
if theme not in DEMOS:
theme = "default"
return RedirectResponse(f"/{theme}/")
# Mount all built-in theme demos
for theme_id, demo in DEMOS.items():
app = gr.mount_gradio_app(app, demo, path=f"/{theme_id}")
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)