LPX55
Add dynamic tab rendering for Extra Space, SAM2.1 Masking Tool, and Custom IFrame Loader with open/close functionality
2680f30
raw
history blame
13.5 kB
import gradio as gr
import gradio.themes
import numpy as np
from style import js_func, css_func
import tempfile
import pandas as pd
def greet(name="Stranger", intensity=1, exclaim=False):
greeting = f"Hello, {name}{'!' * int(intensity)}"
if exclaim:
greeting = greeting.upper()
return greeting
def calculator(num1, operation, num2):
if operation == "add":
result = num1 + num2
elif operation == "subtract":
result = num1 - num2
elif operation == "multiply":
result = num1 * num2
elif operation == "divide":
if num2 == 0:
raise gr.Error("Cannot divide by zero!")
result = num1 / num2
return result
def sepia(input_img):
sepia_filter = np.array([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
])
sepia_img = input_img @ sepia_filter.T
sepia_img = np.clip(sepia_img, 0, 255).astype(np.uint8)
return sepia_img
def download_text(text):
if not text:
text = ""
with tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode="w", encoding="utf-8") as f:
f.write(text)
return f.name
def download_csv(result):
if result is None:
result = ""
df = pd.DataFrame({"Result": [result]})
with tempfile.NamedTemporaryFile(delete=False, suffix=".csv", mode="w", encoding="utf-8") as f:
df.to_csv(f, index=False)
return f.name
theme = gr.Theme.from_hub("LPX55/modal_ai")
with gr.Blocks(theme=theme, js=js_func, css=css_func) as demo:
show_space_tab = gr.State(False)
with gr.Sidebar(width="25vw"):
gr.Markdown("""
# 🤖 API + MCP Demo
_Dynamically load tabs 🤫_
---
**Ways to load the remote SAM2.1 Masking Tool:**
- **gr.load()**: Loads the remote interface at startup, just hidden until shown.
- **iframe**: Loads the remote UI only when you click the button (no API integration).
- **API Proxy**: Upload an image, and the backend will call the remote Space's API and show the result.
- **Open in New Tab**: Opens the remote Space in a new browser tab.
---
**Navigation**
- [Greeting](#greeting)
- [Calculator](#calculator)
- [Sepia Image](#sepia-image)
- [Custom IFrame Loader](#custom-iframe-loader)
---
### [GitHub Repo](https://github.com/yourrepo) | [Docs](https://yourdocs)
---
**Tips:**
- Try the examples in each tab!
- Download your results with the button on the right.
""")
gr.Code(
"""from gradio_client import Client
client = Client("YOUR_URL")
print(client.predict("Alex", 5, False, api_name="/greet"))
""", language="python", label="**API Example:**"
)
gr.Button("Reset All", elem_id="reset-btn")
load_space_btn = gr.Button("Load Extra Space", elem_id="load-space-btn")
load_sam_btn = gr.Button("Load SAM2.1 Masking Tool (gr.load)", elem_id="load-sam-btn")
load_sam_iframe_btn = gr.Button("Load SAM2.1 Masking Tool (iframe)", elem_id="load-sam-iframe-btn")
load_sam_api_btn = gr.Button("Load SAM2.1 Masking Tool (API Proxy)", elem_id="load-sam-api-btn")
open_sam_tab_btn = gr.Button("Open SAM2.1 Masking Tool in New Tab", elem_id="open-sam-tab-btn")
with gr.Tab("Greeting"):
gr.Markdown("## Greeting Generator")
with gr.Row():
with gr.Column():
name = gr.Textbox(label="Name", info="Enter your name", placeholder="e.g. Alex")
intensity = gr.Slider(1, 20, value=3, step=1, label="Intensity", info="How excited should the greeting be?")
with gr.Accordion("Advanced Options", open=False):
exclaim = gr.Checkbox(label="Shout (all caps)", info="Make the greeting all uppercase and add exclamations")
greet_btn = gr.Button("Greet")
with gr.Column():
greet_output = gr.Textbox(label="Greeting", lines=2)
download_greet_btn = gr.DownloadButton(label="Download Greeting", value=download_text, inputs=greet_output)
gr.Examples(
[["Jill", 1, False], ["Sam", 3, True], ["Alex", 5, False]],
inputs=[name, intensity, exclaim],
outputs=greet_output,
fn=greet
)
greet_btn.click(greet, [name, intensity, exclaim], greet_output)
with gr.Tab("Calculator"):
gr.Markdown("## Toy Calculator")
with gr.Row():
with gr.Column():
num1 = gr.Number(label="Number 1", info="First number")
operation = gr.Radio(["add", "subtract", "multiply", "divide"], label="Operation", info="Choose the operation")
num2 = gr.Number(label="Number 2", info="Second number")
calc_btn = gr.Button("Calculate")
with gr.Column():
calc_output = gr.Number(label="Result")
download_calc_btn = gr.DownloadButton(label="Download Result", value=download_csv, inputs=calc_output)
gr.Examples(
[[45, "add", 3], [3.14, "divide", 2], [144, "multiply", 2.5], [0, "subtract", 1.2]],
inputs=[num1, operation, num2],
outputs=calc_output,
fn=calculator
)
calc_btn.click(calculator, [num1, operation, num2], calc_output)
with gr.Tab("Sepia Image"):
gr.Markdown("## Sepia Image Filter")
image_input = gr.Image(label="Input Image", type="numpy")
sepia_btn = gr.Button("Apply Sepia")
image_output = gr.Image(label="Sepia Image")
sepia_btn.click(sepia, image_input, image_output)
# Add state variables for each dynamic tab
extra_space_open = gr.State(True)
sam_tab_open = gr.State(True)
sam_iframe_tab_open = gr.State(True)
sam_api_tab_open = gr.State(True)
custom_iframe_tab_open = gr.State(True)
with gr.Tab("Extra Space", visible=False) as extra_space_tab:
@gr.render(inputs=extra_space_open)
def render_extra_space(is_open):
if is_open:
gr.Markdown("## External Gradio Space")
gr.HTML('<iframe src="https://huggingface.co/spaces/gradio/calculator" width="100%" height="600" style="border:none;"></iframe>')
close_btn = gr.Button("Close Tab")
def close_tab():
return False
close_btn.click(fn=close_tab, outputs=extra_space_open)
else:
gr.Markdown("Tab closed. Click below to reopen.")
reopen_btn = gr.Button("Reopen Tab")
def reopen_tab():
return True
reopen_btn.click(fn=reopen_tab, outputs=extra_space_open)
with gr.Tab("SAM2.1 Masking Tool (gr.load)", visible=False) as sam_tab:
@gr.render(inputs=sam_tab_open)
def render_sam_tab(is_open):
if is_open:
gr.Markdown("## LPX55/SAM2_1-Image-Predictor-Masking-Tool-CPU (gr.load)")
sam_interface = gr.load("LPX55/SAM2_1-Image-Predictor-Masking-Tool-CPU", src="spaces")
close_btn = gr.Button("Close Tab")
def close_tab():
return False
close_btn.click(fn=close_tab, outputs=sam_tab_open)
else:
gr.Markdown("Tab closed. Click below to reopen.")
reopen_btn = gr.Button("Reopen Tab")
def reopen_tab():
return True
reopen_btn.click(fn=reopen_tab, outputs=sam_tab_open)
with gr.Tab("SAM2.1 Masking Tool (iframe)", visible=False) as sam_iframe_tab:
@gr.render(inputs=sam_iframe_tab_open)
def render_sam_iframe_tab(is_open):
if is_open:
gr.Markdown("## LPX55/SAM2_1-Image-Predictor-Masking-Tool-CPU (iframe)")
gr.HTML('<iframe src="https://lpx55-sam2-1-image-predictor-masking-tool-cpu.hf.space" width="100%" height="800" style="border:none;"></iframe>')
close_btn = gr.Button("Close Tab")
def close_tab():
return False
close_btn.click(fn=close_tab, outputs=sam_iframe_tab_open)
else:
gr.Markdown("Tab closed. Click below to reopen.")
reopen_btn = gr.Button("Reopen Tab")
def reopen_tab():
return True
reopen_btn.click(fn=reopen_tab, outputs=sam_iframe_tab_open)
with gr.Tab("SAM2.1 Masking Tool (API Proxy)", visible=False) as sam_api_tab:
@gr.render(inputs=sam_api_tab_open)
def render_sam_api_tab(is_open):
if is_open:
gr.Markdown("## LPX55/SAM2_1-Image-Predictor-Masking-Tool-CPU (API Proxy)")
api_image = gr.Image(label="Input Image")
api_btn = gr.Button("Run Remote Masking")
api_output = gr.Textbox(label="API Response (raw)")
def call_sam_api(image):
import requests
import base64
import json
if image is None:
return "No image uploaded."
with open(image, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
payload = {"data": [img_b64]}
try:
resp = requests.post(
"https://lpx55-sam2-1-image-predictor-masking-tool-cpu.hf.space/run/predict",
json=payload,
timeout=60
)
if resp.status_code == 200:
return json.dumps(resp.json(), indent=2)
else:
return f"Error: {resp.status_code} {resp.text}"
except Exception as e:
return f"Exception: {str(e)}"
api_btn.click(fn=call_sam_api, inputs=api_image, outputs=api_output)
close_btn = gr.Button("Close Tab")
def close_tab():
return False
close_btn.click(fn=close_tab, outputs=sam_api_tab_open)
else:
gr.Markdown("Tab closed. Click below to reopen.")
reopen_btn = gr.Button("Reopen Tab")
def reopen_tab():
return True
reopen_btn.click(fn=reopen_tab, outputs=sam_api_tab_open)
with gr.Tab("Custom IFrame Loader") as custom_iframe_tab:
@gr.render(inputs=custom_iframe_tab_open)
def render_custom_iframe_tab(is_open):
if is_open:
gr.Markdown("## Load Any IFrame URL")
custom_url = gr.Textbox(label="IFrame URL", placeholder="https://example.com")
load_custom_iframe_btn = gr.Button("Load IFrame")
custom_iframe = gr.HTML(visible=True)
def load_custom_iframe(url):
if not url:
return "<div style='color:red'>Please enter a URL.</div>"
return f'<iframe src="{url}" width="100%" height="800" style="border:none;"></iframe>'
load_custom_iframe_btn.click(fn=load_custom_iframe, inputs=custom_url, outputs=custom_iframe)
close_btn = gr.Button("Close Tab")
def close_tab():
return False
close_btn.click(fn=close_tab, outputs=custom_iframe_tab_open)
else:
gr.Markdown("Tab closed. Click below to reopen.")
reopen_btn = gr.Button("Reopen Tab")
def reopen_tab():
return True
reopen_btn.click(fn=reopen_tab, outputs=custom_iframe_tab_open)
def show_tab():
return gr.Tab(visible=True)
load_space_btn.click(fn=show_tab, outputs=[extra_space_tab])
def show_sam_tab():
return gr.Tab(visible=True)
load_sam_btn.click(fn=show_sam_tab, outputs=[sam_tab])
def show_sam_iframe_tab():
iframe_html = '<iframe src="https://lpx55-sam2-1-image-predictor-masking-tool-cpu.hf.space" width="100%" height="800" style="border:none;"></iframe>'
return gr.Tab(visible=True), iframe_html
load_sam_iframe_btn.click(fn=show_sam_iframe_tab, outputs=[sam_iframe_tab, sam_iframe])
def show_sam_api_tab():
return gr.Tab(visible=True)
load_sam_api_btn.click(fn=show_sam_api_tab, outputs=[sam_api_tab])
def open_in_new_tab():
# This function does nothing server-side, but the button will have a link
pass
open_sam_tab_btn.click(fn=open_in_new_tab, inputs=None, outputs=None, js="window.open('https://lpx55-sam2-1-image-predictor-masking-tool-cpu.hf.space', '_blank')")
gr.Markdown("""
---
## 📡 API Usage
- Every function in this demo is automatically available as a REST API!
- View the [OpenAPI schema](./openapi.json) or click "Use via API" in the footer.
- Try the [gradio_client](https://www.gradio.app/guides/getting-started-with-the-python-client) or [@gradio/client](https://www.gradio.app/guides/getting-started-with-the-js-client) to call these endpoints programmatically.
""")
demo.launch(mcp_server=True)