gradio_rerun / app.py
radames's picture
Upload folder using huggingface_hub
d80bf49 verified
raw
history blame contribute delete
No virus
5.78 kB
import cv2
import os
import tempfile
import time
import gradio as gr
from gradio_rerun import Rerun
import rerun as rr
import rerun.blueprint as rrb
from color_grid import build_color_grid
# NOTE: Functions that work with Rerun should be decorated with `@rr.thread_local_stream`.
# This decorator creates a generator-aware thread-local context so that rerun log calls
# across multiple workers stay isolated.
# A task can directly log to a binary stream, which is routed to the embedded viewer.
# Incremental chunks are yielded to the viewer using `yield stream.read()`.
#
# This is the preferred way to work with Rerun in Gradio since your data can be immediately and
# incrementally seen by the viewer. Also, there are no ephemeral RRDs to cleanup or manage.
@rr.thread_local_stream("rerun_example_streaming_blur")
def streaming_repeated_blur(img):
stream = rr.binary_stream()
if img is None:
raise gr.Error("Must provide an image to blur.")
blueprint = rrb.Blueprint(
rrb.Horizontal(
rrb.Spatial2DView(origin="image/original"),
rrb.Spatial2DView(origin="image/blurred"),
),
collapse_panels=True,
)
rr.send_blueprint(blueprint)
rr.set_time_sequence("iteration", 0)
rr.log("image/original", rr.Image(img))
yield stream.read()
blur = img
for i in range(100):
rr.set_time_sequence("iteration", i)
# Pretend blurring takes a while so we can see streaming in action.
time.sleep(0.1)
blur = cv2.GaussianBlur(blur, (5, 5), 0)
rr.log("image/blurred", rr.Image(blur))
# Each time we yield bytes from the stream back to Gradio, they
# are incrementally sent to the viewer. Make sure to yield any time
# you want the user to be able to see progress.
yield stream.read()
# However, if you have a workflow that creates an RRD file instead, you can still send it
# directly to the viewer by simply returning the path to the RRD file.
#
# This may be helpful if you need to execute a helper tool written in C++ or Rust that can't
# be easily modified to stream data directly via Gradio.
#
# In this case you may want to clean up the RRD file after it's sent to the viewer so that you
# don't accumulate too many temporary files.
@rr.thread_local_stream("rerun_example_cube_rrd")
def create_cube_rrd(x, y, z, pending_cleanup):
cube = build_color_grid(int(x), int(y), int(z), twist=0)
rr.log("cube", rr.Points3D(cube.positions, colors=cube.colors, radii=0.5))
# We eventually want to clean up the RRD file after it's sent to the viewer, so tracking
# any pending files to be cleaned up when the state is deleted.
temp = tempfile.NamedTemporaryFile(prefix="cube_", suffix=".rrd", delete=False)
pending_cleanup.append(temp.name)
blueprint = rrb.Spatial3DView(origin="cube")
rr.save(temp.name, default_blueprint=blueprint)
# Just return the name of the file -- Gradio will convert it to a FileData object
# and send it to the viewer.
return temp.name
def cleanup_cube_rrds(pending_cleanup):
for f in pending_cleanup:
os.unlink(f)
with gr.Blocks() as demo:
with gr.Tab("Streaming"):
with gr.Row():
img = gr.Image(interactive=True, label="Image")
with gr.Column():
stream_blur = gr.Button("Stream Repeated Blur")
with gr.Row():
viewer = Rerun(
streaming=True,
panel_states={
"time": "collapsed",
"blueprint": "hidden",
"selection": "hidden",
},
)
stream_blur.click(streaming_repeated_blur, inputs=[img], outputs=[viewer])
with gr.Tab("Dynamic RRD"):
pending_cleanup = gr.State(
[], time_to_live=10, delete_callback=cleanup_cube_rrds
)
with gr.Row():
x_count = gr.Number(
minimum=1, maximum=10, value=5, precision=0, label="X Count"
)
y_count = gr.Number(
minimum=1, maximum=10, value=5, precision=0, label="Y Count"
)
z_count = gr.Number(
minimum=1, maximum=10, value=5, precision=0, label="Z Count"
)
with gr.Row():
create_rrd = gr.Button("Create RRD")
with gr.Row():
viewer = Rerun(
streaming=True,
panel_states={
"time": "collapsed",
"blueprint": "hidden",
"selection": "hidden",
},
)
create_rrd.click(
create_cube_rrd,
inputs=[x_count, y_count, z_count, pending_cleanup],
outputs=[viewer],
)
with gr.Tab("Hosted RRD"):
with gr.Row():
# It may be helpful to point the viewer to a hosted RRD file on another server.
# If an RRD file is hosted via http, you can just return a URL to the file.
choose_rrd = gr.Dropdown(
label="RRD",
choices=[
f"{rr.bindings.get_app_url()}/examples/arkit_scenes.rrd",
f"{rr.bindings.get_app_url()}/examples/dna.rrd",
f"{rr.bindings.get_app_url()}/examples/plots.rrd",
],
)
with gr.Row():
viewer = Rerun(
streaming=True,
panel_states={
"time": "collapsed",
"blueprint": "hidden",
"selection": "hidden",
},
)
choose_rrd.change(lambda x: x, inputs=[choose_rrd], outputs=[viewer])
if __name__ == "__main__":
demo.launch()