Reset components to original state by setting value to None (#2044)

* Fix + test

* Fix test

* Rename demo file

* Delete unused demo

* Refactor into independent demos

* change (#2059)

* Remove chatbot

Co-authored-by: aliabid94 <aabid94@gmail.com>
This commit is contained in:
Freddy Boulton 2022-08-22 16:04:59 -04:00 committed by GitHub
parent 180ca58a6e
commit e2dc87aa2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 172 additions and 23 deletions

View File

@ -11,7 +11,7 @@ demo_dir = pathlib.Path(__file__).parent / "demos"
all_demos = []
demo_module = None
for p in os.listdir("./demos"):
for p in sorted(os.listdir("./demos")):
old_path = copy.deepcopy(sys.path)
sys.path = [os.path.join(demo_dir, p)] + sys.path
if demo_module is None:

View File

@ -21,7 +21,7 @@ def random_plot():
return fig
img_dir = os.path.join(os.path.dirname(__file__), "..", "image_classifier", "images")
img_dir = os.path.join(os.path.dirname(__file__), "files")
file_dir = os.path.join(os.path.dirname(__file__), "..", "kitchen_sink", "files")
model3d_dir = os.path.join(os.path.dirname(__file__), "..", "model3D", "files")
highlighted_text_output_1 = [

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

View File

@ -0,0 +1,99 @@
import gradio as gr
from datetime import datetime
import os
import random
import string
import pandas as pd
from demos.kitchen_sink_random.constants import (
file_dir,
img_dir,
highlighted_text,
highlighted_text_output_2,
highlighted_text_output_1,
random_plot,
random_model3d,
)
components = [
gr.Textbox(value=lambda: datetime.now(), label="Current Time"),
gr.Number(value=lambda: random.random(), label="Ranom Percentage"),
gr.Slider(minimum=-1, maximum=1, randomize=True, label="Slider with randomize"),
gr.Slider(
minimum=0,
maximum=1,
value=lambda: random.random(),
label="Slider with value func",
),
gr.Checkbox(value=lambda: random.random() > 0.5, label="Random Checkbox"),
gr.CheckboxGroup(
choices=["a", "b", "c", "d"],
value=lambda: random.choice(["a", "b", "c", "d"]),
label="Random CheckboxGroup",
),
gr.Radio(
choices=list(string.ascii_lowercase),
value=lambda: random.choice(string.ascii_lowercase),
),
gr.Dropdown(
choices=["a", "b", "c", "d", "e"],
value=lambda: random.choice(["a", "b", "c"]),
),
gr.Image(
value=lambda: random.choice(
[os.path.join(img_dir, img) for img in os.listdir(img_dir)]
)
),
gr.Video(value=lambda: os.path.join(file_dir, "world.mp4")),
gr.Audio(value=lambda: os.path.join(file_dir, "cantina.wav")),
gr.File(
value=lambda: random.choice(
[os.path.join(file_dir, img) for img in os.listdir(file_dir)]
)
),
gr.Dataframe(
value=lambda: pd.DataFrame({"random_number_rows": range(random.randint(0, 10))})
),
gr.Timeseries(value=lambda: os.path.join(file_dir, "time.csv")),
gr.ColorPicker(value=lambda: random.choice(["#000000", "#ff0000", "#0000FF"])),
gr.Label(value=lambda: random.choice(["Pedestrian", "Car", "Cyclist"])),
gr.HighlightedText(
value=lambda: random.choice(
[
{"text": highlighted_text, "entities": highlighted_text_output_1},
{"text": highlighted_text, "entities": highlighted_text_output_2},
]
),
),
gr.JSON(value=lambda: random.choice([{"a": 1}, {"b": 2}])),
gr.HTML(
value=lambda: random.choice(
[
'<p style="color:red;">I am red</p>',
'<p style="color:blue;">I am blue</p>',
]
)
),
gr.Gallery(
value=lambda: [os.path.join(img_dir, img) for img in os.listdir(img_dir)]
),
gr.Model3D(value=random_model3d),
gr.Plot(value=random_plot),
gr.Markdown(value=lambda: f"### {random.choice(['Hello', 'Hi', 'Goodbye!'])}"),
]
with gr.Blocks() as demo:
for component in components:
component.render()
reset = gr.Button(value="Reset")
reset.click(
lambda: [c.update(value=None) for c in components],
inputs=[],
outputs=components,
)
if __name__ == "__main__":
demo.launch()

View File

@ -602,10 +602,8 @@ class Blocks(BlockContext):
)
prediction_value = delete_none(prediction_value)
if "value" in prediction_value:
prediction_value["value"] = (
block.postprocess(prediction_value["value"])
if prediction_value["value"] is not None
else None
prediction_value["value"] = block.postprocess(
prediction_value["value"]
)
output_value = prediction_value
else:

View File

@ -3944,7 +3944,7 @@ class Chatbot(Changeable, IOComponent):
Returns:
List of tuples representing the message and response
"""
return y
return [] if y is None else y
def style(
self,

View File

@ -61,13 +61,20 @@ XRAY_CONFIG = {
"show_label": True,
"name": "image",
"visible": True,
"value": None,
"style": {},
},
},
{
"id": 7,
"type": "json",
"props": {"show_label": True, "name": "json", "visible": True, "style": {}},
"props": {
"show_label": True,
"name": "json",
"visible": True,
"style": {},
"value": None,
},
},
{
"id": 8,
@ -105,6 +112,7 @@ XRAY_CONFIG = {
"mirror_webcam": True,
"show_label": True,
"name": "image",
"value": None,
"visible": True,
"style": {},
},
@ -112,7 +120,13 @@ XRAY_CONFIG = {
{
"id": 12,
"type": "json",
"props": {"show_label": True, "name": "json", "visible": True, "style": {}},
"props": {
"show_label": True,
"name": "json",
"visible": True,
"style": {},
"value": None,
},
},
{
"id": 13,
@ -273,6 +287,7 @@ XRAY_CONFIG_DIFF_IDS = {
"show_label": True,
"name": "image",
"visible": True,
"value": None,
"style": {},
},
},
@ -284,6 +299,7 @@ XRAY_CONFIG_DIFF_IDS = {
"name": "json",
"visible": True,
"style": {},
"value": None,
},
},
{
@ -324,6 +340,7 @@ XRAY_CONFIG_DIFF_IDS = {
"name": "image",
"visible": True,
"style": {},
"value": None,
},
},
{
@ -333,6 +350,7 @@ XRAY_CONFIG_DIFF_IDS = {
"show_label": True,
"name": "json",
"visible": True,
"value": None,
"style": {},
},
},

View File

@ -279,6 +279,8 @@ def delete_none(_dict):
"""
if isinstance(_dict, dict):
for key, value in list(_dict.items()):
if key == "value":
continue
if isinstance(value, (list, dict, tuple, set)):
_dict[key] = delete_none(value)
elif value is None or key is None:

View File

@ -20,8 +20,10 @@ def copy_all_demos(source_dir: str, dest_dir: str):
"interface_random_slider",
"interface_series_load",
"kitchen_sink",
"kitchen_sink_random",
"matrix_transpose",
"model3D",
"reset_components",
"reverse_audio",
"sst_or_tts",
"stream_audio",

View File

@ -1,7 +1,10 @@
import inspect
import pathlib
import pytest
import gradio as gr
def pytest_configure(config):
config.addinivalue_line(
@ -12,3 +15,20 @@ def pytest_configure(config):
@pytest.fixture
def test_file_dir():
return pathlib.Path(pathlib.Path(__file__).parent, "test_files")
@pytest.fixture
def io_components():
classes_to_check = gr.components.IOComponent.__subclasses__()
subclasses = []
while classes_to_check:
subclass = classes_to_check.pop()
children = subclass.__subclasses__()
if children:
classes_to_check.extend(children)
if "value" in inspect.signature(subclass).parameters:
subclasses.append(subclass)
return subclasses

View File

@ -223,29 +223,39 @@ def test_slider_random_value_config():
assert not any([dep["queue"] for dep in demo.config["dependencies"]])
def test_io_components_attach_load_events_when_value_is_fn():
classes_to_check = gr.components.IOComponent.__subclasses__()
subclasses = []
while classes_to_check:
subclass = classes_to_check.pop()
children = subclass.__subclasses__()
if children:
classes_to_check.extend(children)
if "value" in inspect.signature(subclass).parameters:
subclasses.append(subclass)
def test_io_components_attach_load_events_when_value_is_fn(io_components):
interface = gr.Interface(
lambda *args: None,
inputs=[comp(value=lambda: None) for comp in subclasses],
inputs=[comp(value=lambda: None) for comp in io_components],
outputs=None,
)
dependencies_on_load = [
dep for dep in interface.config["dependencies"] if dep["trigger"] == "load"
]
assert len(dependencies_on_load) == len(subclasses)
assert len(dependencies_on_load) == len(io_components)
def test_blocks_do_not_filter_none_values_from_updates(io_components):
io_components = [c() for c in io_components if c not in [gr.Variable, gr.Button]]
with gr.Blocks() as demo:
for component in io_components:
component.render()
btn = gr.Button(value="Reset")
btn.click(
lambda: [gr.update(value=None) for _ in io_components],
inputs=[],
outputs=io_components,
)
output = demo.postprocess_data(
0, [gr.update(value=None) for _ in io_components], state=None
)
assert all(
[o["value"] == c.postprocess(None) for o, c in zip(output, io_components)]
)
if __name__ == "__main__":