mirror of
https://github.com/gradio-app/gradio.git
synced 2024-11-21 01:01:05 +08:00
Allow Users to set random value on sliders on app load (#1935)
* Allow value=random for slider * Commit all files * Remove commented out breakpoint * Remove unused imports * Always bypass queue * Lint * Add randomize parameter * Update docstring * Add load_fn logic * Add new random logic * Add kitchen sink random * Add random kitchen sink * Fix tests + lint * Add test all components accept load_fn * Update docstring * Address final comments Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
This commit is contained in:
parent
359a62b255
commit
1fcff2d710
18
demo/blocks_random_slider/run.py
Normal file
18
demo/blocks_random_slider/run.py
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
import gradio as gr
|
||||
|
||||
|
||||
def func(slider_1, slider_2):
|
||||
return slider_1 * 5 + slider_2
|
||||
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
slider = gr.Slider(minimum=-10.2, maximum=15, label="Random Slider (Static)", randomize=True)
|
||||
slider_1 = gr.Slider(minimum=100, maximum=200, label="Random Slider (Input 1)", randomize=True)
|
||||
slider_2 = gr.Slider(minimum=10, maximum=23.2, label="Random Slider (Input 2)", randomize=True)
|
||||
slider_3 = gr.Slider(value=3, label="Non random slider")
|
||||
btn = gr.Button("Run")
|
||||
btn.click(func, inputs=[slider_1, slider_2], outputs=gr.Number())
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
23
demo/interface_random_slider/run.py
Normal file
23
demo/interface_random_slider/run.py
Normal file
@ -0,0 +1,23 @@
|
||||
import gradio as gr
|
||||
|
||||
|
||||
def func(slider_1, slider_2):
|
||||
return slider_1 + slider_2 * 5
|
||||
|
||||
|
||||
demo = gr.Interface(
|
||||
func,
|
||||
[
|
||||
gr.Slider(minimum=1.5, maximum=250000.89, randomize=True, label="Random Big Range"),
|
||||
gr.Slider(minimum=-1, maximum=1, randomize=True, step=0.05, label="Random only multiple of 0.05 allowed"),
|
||||
gr.Slider(minimum=0, maximum=1, randomize=True, step=0.25, label="Random only multiples of 0.25 allowed"),
|
||||
gr.Slider(minimum=-100, maximum=100, randomize=True, step=3, label="Random between -100 and 100 step 3"),
|
||||
gr.Slider(minimum=-100, maximum=100, randomize=True, label="Random between -100 and 100"),
|
||||
gr.Slider(value=0.25, minimum=5, maximum=30, step=-1),
|
||||
],
|
||||
"number",
|
||||
interpretation="default"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
0
demo/kitchen_sink_random/__init__.py
Normal file
0
demo/kitchen_sink_random/__init__.py
Normal file
71
demo/kitchen_sink_random/constants.py
Normal file
71
demo/kitchen_sink_random/constants.py
Normal file
@ -0,0 +1,71 @@
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
import random
|
||||
import os
|
||||
|
||||
|
||||
def random_plot():
|
||||
start_year = 2020
|
||||
x = np.arange(start_year, start_year + random.randint(0, 10))
|
||||
year_count = x.shape[0]
|
||||
plt_format = "-"
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111)
|
||||
series = np.arange(0, year_count, dtype=float)
|
||||
series = series**2
|
||||
series += np.random.rand(year_count)
|
||||
ax.plot(x, series, plt_format)
|
||||
return fig
|
||||
|
||||
|
||||
img_dir = os.path.join(os.path.dirname(__file__), "..", "image_classifier", "images")
|
||||
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 = [
|
||||
{
|
||||
"entity": "I-LOC",
|
||||
"score": 0.9988978,
|
||||
"index": 2,
|
||||
"word": "Chicago",
|
||||
"start": 5,
|
||||
"end": 12,
|
||||
},
|
||||
{
|
||||
"entity": "I-MISC",
|
||||
"score": 0.9958592,
|
||||
"index": 5,
|
||||
"word": "Pakistani",
|
||||
"start": 22,
|
||||
"end": 31,
|
||||
},
|
||||
]
|
||||
highlighted_text_output_2 = [
|
||||
{
|
||||
"entity": "I-LOC",
|
||||
"score": 0.9988978,
|
||||
"index": 2,
|
||||
"word": "Chicago",
|
||||
"start": 5,
|
||||
"end": 12,
|
||||
},
|
||||
{
|
||||
"entity": "I-LOC",
|
||||
"score": 0.9958592,
|
||||
"index": 5,
|
||||
"word": "Pakistan",
|
||||
"start": 22,
|
||||
"end": 30,
|
||||
},
|
||||
]
|
||||
|
||||
highlighted_text = "Does Chicago have any Pakistani restaurants"
|
||||
|
||||
|
||||
def random_model3d():
|
||||
model_3d = random.choice(
|
||||
[os.path.join(model3d_dir, model) for model in os.listdir(model3d_dir) if model != "source.txt"]
|
||||
)
|
||||
return model_3d
|
98
demo/kitchen_sink_random/run.py
Normal file
98
demo/kitchen_sink_random/run.py
Normal file
@ -0,0 +1,98 @@
|
||||
import gradio as gr
|
||||
from datetime import datetime
|
||||
import random
|
||||
import string
|
||||
import os
|
||||
import pandas as pd
|
||||
|
||||
from constants import (
|
||||
file_dir,
|
||||
img_dir,
|
||||
highlighted_text,
|
||||
highlighted_text_output_2,
|
||||
highlighted_text_output_1,
|
||||
random_plot,
|
||||
random_model3d,
|
||||
)
|
||||
|
||||
|
||||
demo = gr.Interface(
|
||||
lambda x: x,
|
||||
inputs=[
|
||||
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.Variable(value=lambda: random.choice(string.ascii_lowercase)),
|
||||
gr.Button(value=lambda: random.choice(["Run", "Go", "predict"])),
|
||||
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.Chatbot(
|
||||
value=lambda: random.choice([[("hello", "hi!")], [("bye", "goodbye!")]])
|
||||
),
|
||||
gr.Model3D(value=random_model3d),
|
||||
gr.Plot(value=random_plot),
|
||||
gr.Markdown(value=lambda: f"### {random.choice(['Hello', 'Hi', 'Goodbye!'])}"),
|
||||
],
|
||||
outputs=None,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
@ -14,7 +14,16 @@ from typing import TYPE_CHECKING, Any, AnyStr, Callable, Dict, List, Optional, T
|
||||
import anyio
|
||||
from anyio import CapacityLimiter
|
||||
|
||||
from gradio import encryptor, external, networking, queueing, routes, strings, utils
|
||||
from gradio import (
|
||||
components,
|
||||
encryptor,
|
||||
external,
|
||||
networking,
|
||||
queueing,
|
||||
routes,
|
||||
strings,
|
||||
utils,
|
||||
)
|
||||
from gradio.context import Context
|
||||
from gradio.deprecation import check_deprecated_parameters
|
||||
from gradio.documentation import (
|
||||
@ -129,7 +138,6 @@ class Block:
|
||||
inputs = [inputs]
|
||||
if not isinstance(outputs, list):
|
||||
outputs = [outputs]
|
||||
|
||||
Context.root_block.fns.append(BlockFunction(fn, preprocess, postprocess))
|
||||
dependency = {
|
||||
"targets": [self._id] if not no_target else [],
|
||||
@ -660,7 +668,6 @@ class Blocks(BlockContext):
|
||||
self, "enable_queue", False
|
||||
), # attribute set at launch
|
||||
}
|
||||
|
||||
for _id, block in self.blocks.items():
|
||||
config["components"].append(
|
||||
{
|
||||
@ -693,6 +700,8 @@ class Blocks(BlockContext):
|
||||
|
||||
def __exit__(self, *args):
|
||||
Context.block = self.parent
|
||||
# Configure the load events before root_block is reset
|
||||
self.attach_load_events()
|
||||
if self.parent is None:
|
||||
Context.root_block = None
|
||||
else:
|
||||
@ -1047,3 +1056,21 @@ class Blocks(BlockContext):
|
||||
self.server.close()
|
||||
if self.enable_queue:
|
||||
queueing.close()
|
||||
|
||||
def attach_load_events(self):
|
||||
"""Add a load event for every component whose initial value should be randomized."""
|
||||
|
||||
for component in Context.root_block.blocks.values():
|
||||
if (
|
||||
isinstance(component, components.IOComponent)
|
||||
and component.attach_load_event
|
||||
):
|
||||
# Use set_event_trigger to avoid ambiguity between load class/instance method
|
||||
self.set_event_trigger(
|
||||
"load",
|
||||
component.load_fn,
|
||||
None,
|
||||
component,
|
||||
no_target=True,
|
||||
queue=False,
|
||||
)
|
||||
|
@ -11,6 +11,7 @@ import numbers
|
||||
import operator
|
||||
import os
|
||||
import pathlib
|
||||
import random
|
||||
import shutil
|
||||
import tempfile
|
||||
import uuid
|
||||
@ -86,6 +87,7 @@ class IOComponent(Component):
|
||||
visible: bool = True,
|
||||
requires_permissions: bool = False,
|
||||
elem_id: Optional[str] = None,
|
||||
load_fn: Optional[Callable] = None,
|
||||
**kwargs,
|
||||
):
|
||||
self.label = label
|
||||
@ -94,6 +96,12 @@ class IOComponent(Component):
|
||||
self.interactive = interactive
|
||||
|
||||
self.set_interpret_parameters()
|
||||
if callable(load_fn):
|
||||
self.attach_load_event = True
|
||||
self.load_fn = load_fn
|
||||
else:
|
||||
self.attach_load_event = False
|
||||
self.load_fn = None
|
||||
|
||||
super().__init__(elem_id=elem_id, visible=visible, **kwargs)
|
||||
|
||||
@ -276,6 +284,16 @@ class IOComponent(Component):
|
||||
config["mode"] = "dynamic" if interactive else "static"
|
||||
return config
|
||||
|
||||
@staticmethod
|
||||
def get_load_fn_and_initial_value(value):
|
||||
if callable(value):
|
||||
initial_value = value()
|
||||
load_fn = value
|
||||
else:
|
||||
initial_value = value
|
||||
load_fn = None
|
||||
return load_fn, initial_value
|
||||
|
||||
|
||||
@document("change", "submit", "style")
|
||||
class Textbox(Changeable, Submittable, IOComponent):
|
||||
@ -291,7 +309,7 @@ class Textbox(Changeable, Submittable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: str = "",
|
||||
value: Optional[str | Callable] = "",
|
||||
*,
|
||||
lines: int = 1,
|
||||
max_lines: int = 20,
|
||||
@ -305,7 +323,7 @@ class Textbox(Changeable, Submittable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: default text to provide in textarea.
|
||||
value: default text to provide in textarea. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
lines: minimum number of line rows to provide in textarea.
|
||||
max_lines: maximum number of line rows to provide in textarea.
|
||||
placeholder: placeholder hint to provide behind textarea.
|
||||
@ -318,7 +336,8 @@ class Textbox(Changeable, Submittable, IOComponent):
|
||||
self.lines = lines
|
||||
self.max_lines = max_lines
|
||||
self.placeholder = placeholder
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.cleared_value = ""
|
||||
self.test_input = value
|
||||
self.interpret_by_tokens = True
|
||||
@ -329,6 +348,7 @@ class Textbox(Changeable, Submittable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -486,7 +506,7 @@ class Number(Changeable, Submittable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[float] = None,
|
||||
value: Optional[float | Callable] = None,
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -498,7 +518,7 @@ class Number(Changeable, Submittable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: default value.
|
||||
value: default value. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
interactive: if True, will be editable; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.
|
||||
@ -507,7 +527,8 @@ class Number(Changeable, Submittable, IOComponent):
|
||||
precision: Precision to round input/output to. If set to 0, will round to nearest integer and covert type to int. If None, no rounding happens.
|
||||
"""
|
||||
self.precision = precision
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.test_input = self.value if self.value is not None else 1
|
||||
self.interpret_by_tokens = False
|
||||
IOComponent.__init__(
|
||||
@ -517,6 +538,7 @@ class Number(Changeable, Submittable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -665,7 +687,7 @@ class Slider(Changeable, IOComponent):
|
||||
Postprocessing: expects an {int} or {float} returned from function and sets slider value to it as long as it is within range.
|
||||
Examples-format: A {float} or {int} representing the slider's value.
|
||||
|
||||
Demos: sentence_builder, generate_tone, titanic_survival
|
||||
Demos: sentence_builder, generate_tone, titanic_survival, interface_random_slider, blocks_random_slider
|
||||
Guides: create_your_own_friends_with_a_gan
|
||||
"""
|
||||
|
||||
@ -673,7 +695,7 @@ class Slider(Changeable, IOComponent):
|
||||
self,
|
||||
minimum: float = 0,
|
||||
maximum: float = 100,
|
||||
value: Optional[float] = None,
|
||||
value: Optional[float | Callable] = None,
|
||||
*,
|
||||
step: Optional[float] = None,
|
||||
label: Optional[str] = None,
|
||||
@ -681,19 +703,21 @@ class Slider(Changeable, IOComponent):
|
||||
interactive: Optional[bool] = None,
|
||||
visible: bool = True,
|
||||
elem_id: Optional[str] = None,
|
||||
randomize: bool = False,
|
||||
**kwargs,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
minimum: minimum value for slider.
|
||||
maximum: maximum value for slider.
|
||||
value: default value.
|
||||
value: default value. If callable, the function will be called whenever the app loads to set the initial value of the component. Ignored if randomized=True.
|
||||
step: increment between slider values.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
interactive: if True, slider will be adjustable; if False, adjusting will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
randomize: If True, the value of the slider when the app loads is taken uniformly at random from the range given by the minimum and maximum.
|
||||
"""
|
||||
self.minimum = minimum
|
||||
self.maximum = maximum
|
||||
@ -702,7 +726,12 @@ class Slider(Changeable, IOComponent):
|
||||
power = math.floor(math.log10(difference) - 2)
|
||||
step = 10**power
|
||||
self.step = step
|
||||
self.value = self.postprocess(value)
|
||||
|
||||
if randomize:
|
||||
value = self.get_random_value
|
||||
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.cleared_value = self.value
|
||||
self.test_input = self.value
|
||||
self.interpret_by_tokens = False
|
||||
@ -713,6 +742,7 @@ class Slider(Changeable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -725,6 +755,23 @@ class Slider(Changeable, IOComponent):
|
||||
**IOComponent.get_config(self),
|
||||
}
|
||||
|
||||
def get_random_value(self):
|
||||
# Goal is to generate a possible value of the slider
|
||||
# without generating all possible values
|
||||
# We randomly pick a step among all possible steps and add to the minimum
|
||||
n_steps = int((self.maximum - self.minimum) / self.step)
|
||||
step = random.randint(0, n_steps)
|
||||
value = self.minimum + step * self.step
|
||||
|
||||
# Round to the number of decimals in the step
|
||||
# So that UI doesn't display really long decimals due to arithmetic
|
||||
# If the step doesn't have any decimals, find will return -1
|
||||
n_decimals = max(str(self.step)[::-1].find("."), 0)
|
||||
if n_decimals:
|
||||
value = round(value, n_decimals)
|
||||
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def update(
|
||||
value: Optional[Any] = None,
|
||||
@ -836,7 +883,7 @@ class Checkbox(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: bool = False,
|
||||
value: bool | Callable = False,
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -847,7 +894,7 @@ class Checkbox(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: if True, checked by default.
|
||||
value: if True, checked by default. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
interactive: if True, this checkbox can be checked; if False, checking will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.
|
||||
@ -855,7 +902,8 @@ class Checkbox(Changeable, IOComponent):
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.test_input = True
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.interpret_by_tokens = False
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
@ -864,6 +912,7 @@ class Checkbox(Changeable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -960,7 +1009,7 @@ class CheckboxGroup(Changeable, IOComponent):
|
||||
self,
|
||||
choices: Optional[List[str]] = None,
|
||||
*,
|
||||
value: List[str] = None,
|
||||
value: List[str] | Callable = None,
|
||||
type: str = "value",
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -972,7 +1021,7 @@ class CheckboxGroup(Changeable, IOComponent):
|
||||
"""
|
||||
Parameters:
|
||||
choices: list of options to select from.
|
||||
value: default selected list of options.
|
||||
value: default selected list of options. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
type: Type of value to be returned by component. "value" returns the list of strings of the choices selected, "index" returns the list of indicies of the choices selected.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
@ -983,7 +1032,8 @@ class CheckboxGroup(Changeable, IOComponent):
|
||||
self.choices = choices or []
|
||||
self.cleared_value = []
|
||||
self.type = type
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.test_input = self.choices
|
||||
self.interpret_by_tokens = False
|
||||
IOComponent.__init__(
|
||||
@ -993,6 +1043,7 @@ class CheckboxGroup(Changeable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -1138,7 +1189,7 @@ class Radio(Changeable, IOComponent):
|
||||
self,
|
||||
choices: Optional[List[str]] = None,
|
||||
*,
|
||||
value: Optional[str] = None,
|
||||
value: Optional[str | Callable] = None,
|
||||
type: str = "value",
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -1150,7 +1201,7 @@ class Radio(Changeable, IOComponent):
|
||||
"""
|
||||
Parameters:
|
||||
choices: list of options to select from.
|
||||
value: the button selected by default. If None, no button is selected by default.
|
||||
value: the button selected by default. If None, no button is selected by default. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
type: Type of value to be returned by component. "value" returns the string of the choice selected, "index" returns the index of the choice selected.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
@ -1161,7 +1212,8 @@ class Radio(Changeable, IOComponent):
|
||||
self.choices = choices or []
|
||||
self.type = type
|
||||
self.test_input = self.choices[0] if len(self.choices) else None
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.cleared_value = self.value
|
||||
self.interpret_by_tokens = False
|
||||
IOComponent.__init__(
|
||||
@ -1171,6 +1223,7 @@ class Radio(Changeable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -1294,7 +1347,7 @@ class Dropdown(Radio):
|
||||
self,
|
||||
choices: Optional[List[str]] = None,
|
||||
*,
|
||||
value: Optional[str] = None,
|
||||
value: Optional[str | Callable] = None,
|
||||
type: str = "value",
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -1306,7 +1359,7 @@ class Dropdown(Radio):
|
||||
"""
|
||||
Parameters:
|
||||
choices: list of options to select from.
|
||||
value: default value selected in dropdown. If None, no value is selected by default.
|
||||
value: default value selected in dropdown. If None, no value is selected by default. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
type: Type of value to be returned by component. "value" returns the string of the choice selected, "index" returns the index of the choice selected.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
@ -1377,7 +1430,7 @@ class Image(Editable, Clearable, Changeable, Streamable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: A PIL Image, numpy array, path or URL for the default value that Image component is going to take.
|
||||
value: A PIL Image, numpy array, path or URL for the default value that Image component is going to take. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
shape: (width, height) shape to crop and resize image to; if None, matches input image size. Pass None for either width or height to only crop and resize the other.
|
||||
image_mode: "RGB" if color, or "L" if black and white.
|
||||
invert_colors: whether to invert the image as a preprocessing step.
|
||||
@ -1394,7 +1447,8 @@ class Image(Editable, Clearable, Changeable, Streamable, IOComponent):
|
||||
"""
|
||||
self.mirror_webcam = mirror_webcam
|
||||
self.type = type
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.shape = shape
|
||||
self.image_mode = image_mode
|
||||
self.source = source
|
||||
@ -1415,6 +1469,7 @@ class Image(Editable, Clearable, Changeable, Streamable, IOComponent):
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
requires_permissions=requires_permissions,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -1733,7 +1788,7 @@ class Video(Changeable, Clearable, Playable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[str] = None,
|
||||
value: Optional[str | Callable] = None,
|
||||
*,
|
||||
format: Optional[str] = None,
|
||||
source: str = "upload",
|
||||
@ -1747,7 +1802,7 @@ class Video(Changeable, Clearable, Playable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: A path or URL for the default value that Video component is going to take.
|
||||
value: A path or URL for the default value that Video component is going to take. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
format: Format of video format to be returned by component, such as 'avi' or 'mp4'. Use 'mp4' to ensure browser playability. If set to None, video will keep uploaded format.
|
||||
source: Source of video. "upload" creates a box where user can drop an video file, "webcam" allows user to record a video from their webcam.
|
||||
label: component name in interface.
|
||||
@ -1760,7 +1815,8 @@ class Video(Changeable, Clearable, Playable, IOComponent):
|
||||
self.format = format
|
||||
self.source = source
|
||||
self.mirror_webcam = mirror_webcam
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
label=label,
|
||||
@ -1768,6 +1824,7 @@ class Video(Changeable, Clearable, Playable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -1920,7 +1977,7 @@ class Audio(Changeable, Clearable, Playable, Streamable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[str | Tuple[int, np.array]] = None,
|
||||
value: Optional[str | Tuple[int, np.array] | Callable] = None,
|
||||
*,
|
||||
source: str = "upload",
|
||||
type: str = "numpy",
|
||||
@ -1934,7 +1991,7 @@ class Audio(Changeable, Clearable, Playable, Streamable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: A path, URL, or [sample_rate, numpy array] tuple for the default value that Audio component is going to take.
|
||||
value: A path, URL, or [sample_rate, numpy array] tuple for the default value that Audio component is going to take. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
source: Source of audio. "upload" creates a box where user can drop an audio file, "microphone" creates a microphone input.
|
||||
type: The format the audio file is converted to before being passed into the prediction function. "numpy" converts the audio to a tuple consisting of: (int sample rate, numpy.array for the data), "filepath" passes a str path to a temporary file containing the audio.
|
||||
label: component name in interface.
|
||||
@ -1944,7 +2001,8 @@ class Audio(Changeable, Clearable, Playable, Streamable, IOComponent):
|
||||
streaming: If set to True when used in a `live` interface, will automatically stream webcam feed. Only valid is source is 'microphone'.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.source = source
|
||||
requires_permissions = source == "microphone"
|
||||
self.type = type
|
||||
@ -1963,6 +2021,7 @@ class Audio(Changeable, Clearable, Playable, Streamable, IOComponent):
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
requires_permissions=requires_permissions,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -2245,7 +2304,7 @@ class File(Changeable, Clearable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[str | List[str]] = None,
|
||||
value: Optional[str | List[str] | Callable] = None,
|
||||
*,
|
||||
file_count: str = "single",
|
||||
type: str = "file",
|
||||
@ -2258,7 +2317,7 @@ class File(Changeable, Clearable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default file to display, given as str file path
|
||||
value: Default file to display, given as str file path. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
file_count: if single, allows user to upload one file. If "multiple", user uploads multiple files. If "directory", user uploads all files in selected directory. Return type will be list for each file in case of "multiple" or "directory".
|
||||
type: Type of value to be returned by component. "file" returns a temporary file object whose path can be retrieved by file_obj.name, "binary" returns an bytes object.
|
||||
label: component name in interface.
|
||||
@ -2269,7 +2328,8 @@ class File(Changeable, Clearable, IOComponent):
|
||||
"""
|
||||
self.file_count = file_count
|
||||
self.type = type
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.test_input = None
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
@ -2278,6 +2338,7 @@ class File(Changeable, Clearable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -2450,7 +2511,7 @@ class Dataframe(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[List[List[Any]]] = None,
|
||||
value: Optional[List[List[Any]] | Callable] = None,
|
||||
*,
|
||||
headers: Optional[List[str]] = None,
|
||||
row_count: int | Tuple[int, str] = (1, "dynamic"),
|
||||
@ -2470,7 +2531,7 @@ class Dataframe(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default value as a 2-dimensional list of values.
|
||||
value: Default value as a 2-dimensional list of values. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
headers: List of str header names. If None, no headers are shown.
|
||||
row_count: Limit number of rows for input and decide whether user can create new rows. The first element of the tuple is an `int`, the row count; the second should be 'fixed' or 'dynamic', the new row behaviour. If an `int` is passed the rows default to 'dynamic'
|
||||
col_count: Limit number of columns for input and decide whether user can create new columns. The first element of the tuple is an `int`, the number of columns; the second should be 'fixed' or 'dynamic', the new column behaviour. If an `int` is passed the columns default to 'dynamic'
|
||||
@ -2518,9 +2579,11 @@ class Dataframe(Changeable, IOComponent):
|
||||
[values[c] for c in column_dtypes] for _ in range(self.row_count[0])
|
||||
]
|
||||
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
|
||||
self.value = (
|
||||
self.postprocess(value)
|
||||
if value is not None
|
||||
self.postprocess(initial_value)
|
||||
if initial_value is not None
|
||||
else self.postprocess(self.test_input)
|
||||
)
|
||||
|
||||
@ -2534,6 +2597,7 @@ class Dataframe(Changeable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -2714,7 +2778,7 @@ class Timeseries(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[str] = None,
|
||||
value: Optional[str | Callable] = None,
|
||||
*,
|
||||
x: Optional[str] = None,
|
||||
y: str | List[str] = None,
|
||||
@ -2728,7 +2792,7 @@ class Timeseries(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: File path for the timeseries csv file.
|
||||
value: File path for the timeseries csv file. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
x: Column name of x (time) series. None if csv has no headers, in which case first column is x series.
|
||||
y: Column name of y series, or list of column names if multiple series. None if csv has no headers, in which case every column after first is a y series.
|
||||
label: component name in interface.
|
||||
@ -2738,7 +2802,8 @@ class Timeseries(Changeable, IOComponent):
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.x = x
|
||||
if isinstance(y, str):
|
||||
y = [y]
|
||||
@ -2751,6 +2816,7 @@ class Timeseries(Changeable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -2870,11 +2936,12 @@ class Variable(IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: the initial value of the state.
|
||||
value: the initial value of the state. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
"""
|
||||
self.value = deepcopy(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = deepcopy(initial_value)
|
||||
self.stateful = True
|
||||
IOComponent.__init__(self, **kwargs)
|
||||
IOComponent.__init__(self, load_fn=load_fn, **kwargs)
|
||||
|
||||
def style(self):
|
||||
return self
|
||||
@ -2892,7 +2959,7 @@ class Button(Clickable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: str = "Run",
|
||||
value: str | Callable = "Run",
|
||||
*,
|
||||
variant: str = "secondary",
|
||||
visible: bool = True,
|
||||
@ -2901,13 +2968,16 @@ class Button(Clickable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default text for the button to display.
|
||||
value: Default text for the button to display. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
variant: 'primary' for main call-to-action, 'secondary' for a more subdued style
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
Component.__init__(self, visible=visible, elem_id=elem_id, **kwargs)
|
||||
self.value = value
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = initial_value
|
||||
IOComponent.__init__(
|
||||
self, visible=visible, elem_id=elem_id, load_fn=load_fn, **kwargs
|
||||
)
|
||||
self.variant = variant
|
||||
|
||||
def get_config(self):
|
||||
@ -2968,7 +3038,7 @@ class ColorPicker(Changeable, Submittable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: str = None,
|
||||
value: str | Callable = None,
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -2979,14 +3049,15 @@ class ColorPicker(Changeable, Submittable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: default text to provide in color picker.
|
||||
value: default text to provide in color picker. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
interactive: if True, will be rendered as an editable color picker; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.cleared_value = "#000000"
|
||||
self.test_input = value
|
||||
IOComponent.__init__(
|
||||
@ -2996,6 +3067,7 @@ class ColorPicker(Changeable, Submittable, IOComponent):
|
||||
interactive=interactive,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -3087,7 +3159,7 @@ class Label(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[str] = None,
|
||||
value: Optional[str | Callable] = None,
|
||||
*,
|
||||
num_top_classes: Optional[int] = None,
|
||||
label: Optional[str] = None,
|
||||
@ -3098,7 +3170,7 @@ class Label(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default value to show in the component.
|
||||
value: Default value to show in the component. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
num_top_classes: number of most confident classes to show.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
@ -3106,13 +3178,15 @@ class Label(Changeable, IOComponent):
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.num_top_classes = num_top_classes
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
label=label,
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -3229,7 +3303,7 @@ class HighlightedText(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[List[Tuple[str, str | float | None]] | Dict] = None,
|
||||
value: Optional[List[Tuple[str, str | float | None]] | Dict | Callable] = None,
|
||||
*,
|
||||
color_map: Dict[str, str] = None, # Parameter moved to HighlightedText.style()
|
||||
show_legend: bool = False,
|
||||
@ -3243,7 +3317,7 @@ class HighlightedText(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default value to show.
|
||||
value: Default value to show. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
show_legend: whether to show span categories in a separate legend or inline.
|
||||
combine_adjacent: If True, will merge the labels of adjacent tokens belonging to the same category.
|
||||
adjacent_separator: Specifies the separator to be used between tokens if combine_adjacent is True.
|
||||
@ -3260,13 +3334,15 @@ class HighlightedText(Changeable, IOComponent):
|
||||
self.show_legend = show_legend
|
||||
self.combine_adjacent = combine_adjacent
|
||||
self.adjacent_separator = adjacent_separator
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
label=label,
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -3381,7 +3457,7 @@ class JSON(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[str] = None,
|
||||
value: Optional[str | Callable] = None,
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -3391,19 +3467,21 @@ class JSON(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default value
|
||||
value: Default value. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
label=label,
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -3470,7 +3548,7 @@ class HTML(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: str = "",
|
||||
value: str | Callable = "",
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -3480,19 +3558,21 @@ class HTML(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default value
|
||||
value: Default value. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.value = value
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
label=label,
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -3534,7 +3614,7 @@ class Gallery(IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[List[np.ndarray | PIL.Image | str]] = None,
|
||||
value: Optional[List[np.ndarray | PIL.Image | str] | Callable] = None,
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -3544,18 +3624,20 @@ class Gallery(IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: List of images to display in the gallery by default
|
||||
value: List of images to display in the gallery by default. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
super().__init__(
|
||||
label=label,
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -3779,7 +3861,7 @@ class Chatbot(Changeable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[List[Tuple[str, str]]] = None,
|
||||
value: Optional[List[Tuple[str, str]] | Callable] = None,
|
||||
color_map: Dict[str, str] = None, # Parameter moved to Chatbot.style()
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
@ -3790,7 +3872,7 @@ class Chatbot(Changeable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Default value to show in chatbot
|
||||
value: Default value to show in chatbot. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
visible: If False, component will be hidden.
|
||||
@ -3800,8 +3882,8 @@ class Chatbot(Changeable, IOComponent):
|
||||
warnings.warn(
|
||||
"The 'color_map' parameter has been moved from the constructor to `Chatbot.style()` ",
|
||||
)
|
||||
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
self.color_map = color_map
|
||||
|
||||
IOComponent.__init__(
|
||||
@ -3810,6 +3892,7 @@ class Chatbot(Changeable, IOComponent):
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -3882,7 +3965,7 @@ class Model3D(Changeable, Editable, Clearable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: Optional[str] = None,
|
||||
value: Optional[str | Callable] = None,
|
||||
*,
|
||||
clear_color: List[float] = None,
|
||||
label: Optional[str] = None,
|
||||
@ -3893,7 +3976,7 @@ class Model3D(Changeable, Editable, Clearable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: path to (.obj, glb, or .gltf) file to show in model3D viewer
|
||||
value: path to (.obj, glb, or .gltf) file to show in model3D viewer. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
clear_color: background color of scene
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
@ -3901,13 +3984,15 @@ class Model3D(Changeable, Editable, Clearable, IOComponent):
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.clear_color = clear_color or [0.2, 0.2, 0.2, 1.0]
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
label=label,
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -4025,7 +4110,7 @@ class Plot(Changeable, Clearable, IOComponent):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value=None,
|
||||
value: Optional[Callable] = None,
|
||||
*,
|
||||
label: Optional[str] = None,
|
||||
show_label: bool = True,
|
||||
@ -4035,19 +4120,21 @@ class Plot(Changeable, Clearable, IOComponent):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Optionally, supply a default plot object to display, must be a matplotlib, plotly, or bokeh figure.
|
||||
value: Optionally, supply a default plot object to display, must be a matplotlib, plotly, or bokeh figure. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
label: component name in interface.
|
||||
show_label: if True, will display label.
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self,
|
||||
label=label,
|
||||
show_label=show_label,
|
||||
visible=visible,
|
||||
elem_id=elem_id,
|
||||
load_fn=load_fn,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@ -4116,7 +4203,7 @@ class Markdown(IOComponent, Changeable):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
value: str = "",
|
||||
value: str | Callable = "",
|
||||
*,
|
||||
visible: bool = True,
|
||||
elem_id: Optional[str] = None,
|
||||
@ -4124,13 +4211,16 @@ class Markdown(IOComponent, Changeable):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
value: Value to show in Markdown component
|
||||
value: Value to show in Markdown component. If callable, the function will be called whenever the app loads to set the initial value of the component.
|
||||
visible: If False, component will be hidden.
|
||||
elem_id: An optional string that is assigned as the id of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
"""
|
||||
IOComponent.__init__(self, visible=visible, elem_id=elem_id, **kwargs)
|
||||
self.md = MarkdownIt()
|
||||
self.value = self.postprocess(value)
|
||||
load_fn, initial_value = self.get_load_fn_and_initial_value(value)
|
||||
self.value = self.postprocess(initial_value)
|
||||
IOComponent.__init__(
|
||||
self, visible=visible, elem_id=elem_id, load_fn=load_fn, **kwargs
|
||||
)
|
||||
|
||||
def postprocess(self, y: str | None) -> str | None:
|
||||
"""
|
||||
|
@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
import inspect
|
||||
import io
|
||||
import random
|
||||
import sys
|
||||
@ -197,5 +198,55 @@ class TestBlocks(unittest.TestCase):
|
||||
demo.close()
|
||||
|
||||
|
||||
def test_slider_random_value_config():
|
||||
with gr.Blocks() as demo:
|
||||
gr.Slider(
|
||||
value=11.2, minimum=-10.2, maximum=15, label="Non-random Slider (Static)"
|
||||
)
|
||||
gr.Slider(
|
||||
randomize=True, minimum=100, maximum=200, label="Random Slider (Input 1)"
|
||||
)
|
||||
gr.Slider(
|
||||
randomize=True, minimum=10, maximum=23.2, label="Random Slider (Input 2)"
|
||||
)
|
||||
for component in demo.blocks.values():
|
||||
if isinstance(component, gr.components.IOComponent):
|
||||
if "Non-random" in component.label:
|
||||
assert not component.attach_load_event
|
||||
else:
|
||||
assert component.attach_load_event
|
||||
dependencies_on_load = [
|
||||
dep["trigger"] == "load" for dep in demo.config["dependencies"]
|
||||
]
|
||||
assert all(dependencies_on_load)
|
||||
assert len(dependencies_on_load) == 2
|
||||
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)
|
||||
|
||||
interface = gr.Interface(
|
||||
lambda *args: None,
|
||||
inputs=[comp(value=lambda: None) for comp in subclasses],
|
||||
outputs=None,
|
||||
)
|
||||
|
||||
dependencies_on_load = [
|
||||
dep for dep in interface.config["dependencies"] if dep["trigger"] == "load"
|
||||
]
|
||||
assert len(dependencies_on_load) == len(subclasses)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
@ -1829,5 +1829,22 @@ def test_gallery_save_and_restore_flagged(my_uuid, tmp_path):
|
||||
assert data == data_restored
|
||||
|
||||
|
||||
@patch("gradio.Slider.get_random_value", return_value=7)
|
||||
def test_slider_get_random_value_on_load(mock_get_random_value):
|
||||
slider = gr.Slider(minimum=-5, maximum=10, randomize=True)
|
||||
assert slider.attach_load_event
|
||||
assert slider.value == 7
|
||||
assert slider.load_fn() == 7
|
||||
|
||||
|
||||
@patch("random.randint", return_value=3)
|
||||
def test_slider_rounds_when_using_default_randomizer(mock_randint):
|
||||
slider = gr.Slider(minimum=0, maximum=1, randomize=True, step=0.1)
|
||||
# If get_random_value didn't round, this test would fail
|
||||
# because 0.30000000000000004 != 0.3
|
||||
assert slider.get_random_value() == 0.3
|
||||
mock_randint.assert_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user