Update component config (#1089)

* first commit

* changes

* restore defualt_value name

* changes

* rm value=

* rm value=

* rm value=

* changes

* changes

* changes

* rename default_val to value

* changes

* changes

* changes

* changes

* format

* changes

* changes

* format

* test fix

Co-authored-by: Ali Abid <aliabid94@gmail.com>
This commit is contained in:
aliabid94 2022-05-10 17:11:43 -07:00 committed by GitHub
parent 11740dd329
commit ce47c48ebc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 1476 additions and 792 deletions

View File

@ -32,7 +32,7 @@ with demo:
"Incorrect", css={"background-color": "pink", "color": "red"}
)
with gr.TabItem("Results"):
results = gr.Variable(default_value={})
results = gr.Variable(value={})
correct_field = gr.Markdown("# Correct: 0")
incorrect_field = gr.Markdown("# Incorrect: 0")
gr.Markdown("Card Statistics: ")

View File

@ -35,7 +35,7 @@ with gr.Blocks() as demo:
headers=["One", "Two", "Three", "Four"],
col_count=(4, "fixed"),
row_count=(7, "fixed"),
default_value=[[1, 2, 3, 4]],
value=[[1, 2, 3, 4]],
)
gr.Dataframe(
interactive=True, headers=["One", "Two", "Three", "Four"], col_count=4

View File

@ -3,8 +3,8 @@ import gradio as gr
test = gr.Blocks()
with test:
num = gr.Variable(default_value=0)
squared = gr.Number(default_value=0)
num = gr.Variable(value=0)
squared = gr.Number(value=0)
btn = gr.Button("Next Square")
def increase(var):

View File

@ -1,17 +1,44 @@
from gradio import Dropdown, Blocks, Slider
import gradio as gr
with gr.Blocks() as block:
gr.Markdown(
"""
# Animal Generator
Once you select a species, the detail panel should be visible.
"""
)
def update_dropdown_choices(val):
if val < 50:
opts = ["fail", "repeat"]
else:
opts = ["succeed", "repeat"]
return Dropdown.update(choices=opts)
species = gr.Radio(label="Animal Class", choices=["Mammal", "Fish", "Bird"])
animal = gr.Dropdown(label="Animal", choices=[])
with gr.Column(visible=False) as details_col:
weight = gr.Slider(0, minimum=0, maximum=20)
details = gr.Textbox(label="Extra Details")
generate_btn = gr.Button("Generate")
output = gr.Textbox(label="Output")
with Blocks() as block:
s = Slider(default_value=0, minimum=0, maximum=100)
d = Dropdown(choices=["fake", "choices", "exist"])
species_map = {
"Mammal": ["Elephant", "Giraffe", "Hamster"],
"Fish": ["Shark", "Salmon", "Tuna"],
"Bird": ["Chicken", "Eagle", "Hawk"],
}
s.change(fn=update_dropdown_choices, inputs=[s], outputs=[d])
block.launch()
def filter_species(species):
return gr.Dropdown.update(
choices=species_map[species], value=species_map[species][1]
), gr.update(visible=True)
species.change(filter_species, species, [animal, details_col])
def filter_weight(animal):
if animal in ("Elephant", "Shark", "Giraffe"):
return gr.update(maximum=100)
else:
return gr.update(maximum=20)
animal.change(filter_weight, animal, weight)
weight.change(lambda w: gr.update(lines=int(w / 10) + 1), weight, details)
generate_btn.click(lambda x: x, details, output)
block.launch()

View File

@ -5,7 +5,7 @@
"id": 1,
"type": "markdown",
"props": {
"default_value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"label": null,
"css": {},
@ -17,7 +17,7 @@
"type": "checkboxgroup",
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"default_value": [],
"value": [],
"name": "checkboxgroup",
"label": "Disease to Scan For",
"css": {},
@ -29,7 +29,7 @@
"type": "tabs",
"props": {
"css": {},
"default_value": true
"value": true
}
},
{
@ -38,7 +38,7 @@
"props": {
"label": "X-ray",
"css": {},
"default_value": true
"value": true
}
},
{
@ -47,7 +47,7 @@
"props": {
"type": "row",
"css": {},
"default_value": true
"value": true
}
},
{
@ -58,7 +58,7 @@
"shape": null,
"source": "upload",
"tool": "editor",
"default_value": null,
"value": null,
"name": "image",
"label": null,
"css": {},
@ -69,7 +69,7 @@
"id": 7,
"type": "json",
"props": {
"default_value": "\"\"",
"value": "\"\"",
"name": "json",
"label": null,
"css": {},
@ -80,7 +80,7 @@
"id": 8,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"name": "button",
"label": null,
"css": {},
@ -93,7 +93,7 @@
"props": {
"label": "CT Scan",
"css": {},
"default_value": true
"value": true
}
},
{
@ -102,7 +102,7 @@
"props": {
"type": "row",
"css": {},
"default_value": true
"value": true
}
},
{
@ -113,7 +113,7 @@
"shape": null,
"source": "upload",
"tool": "editor",
"default_value": null,
"value": null,
"name": "image",
"label": null,
"css": {},
@ -124,7 +124,7 @@
"id": 12,
"type": "json",
"props": {
"default_value": "\"\"",
"value": "\"\"",
"name": "json",
"label": null,
"css": {},
@ -135,7 +135,7 @@
"id": 13,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"name": "button",
"label": null,
"css": {},
@ -148,7 +148,7 @@
"props": {
"lines": 1,
"placeholder": null,
"default_value": "",
"value": "",
"name": "textbox",
"label": null,
"css": {},

View File

@ -14,7 +14,7 @@ def calculator(num1, operation, num2):
demo = gr.Interface(
calculator,
["number", gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
[gr.Number(4), gr.Radio(["add", "subtract", "multiply", "divide"]), "number"],
"number",
examples=[
[5, "add", 3],

View File

@ -17,12 +17,12 @@ demo = gr.Interface(
gr.Textbox(
label="Initial text",
lines=3,
default_value="The quick brown fox jumped over the lazy dogs.",
value="The quick brown fox jumped over the lazy dogs.",
),
gr.Textbox(
label="Text to compare",
lines=3,
default_value="The fast brown fox jumps over lazy dogs.",
value="The fast brown fox jumps over lazy dogs.",
),
],
gr.HighlightedText(label="Diff"),

View File

@ -22,7 +22,7 @@ demo = gr.Interface(
[
gr.Timeseries(x="time", y=["retail", "food", "other"]),
gr.CheckboxGroup(
["retail", "food", "other"], default_selected=["retail", "food", "other"]
["retail", "food", "other"], value=["retail", "food", "other"]
),
gr.Slider(minimum=1, maximum=3),
],

View File

@ -33,7 +33,7 @@ def interpret_gender(sentence):
demo = gr.Interface(
fn=gender_of_sentence,
inputs=gr.Textbox(default_value="She went to his house to get her keys."),
inputs=gr.Textbox(value="She went to his house to get her keys."),
outputs="label",
interpretation=interpret_gender,
)

View File

@ -14,7 +14,7 @@ def gender_of_sentence(sentence):
demo = gr.Interface(
fn=gender_of_sentence,
inputs=gr.Textbox(default_value="She went to his house to get her keys."),
inputs=gr.Textbox(value="She went to his house to get her keys."),
outputs="label",
interpretation="default",
)

View File

@ -7,7 +7,7 @@
"props": {
"lines": 1,
"placeholder": null,
"default_value": "",
"value": "",
"name": "textbox",
"label": "Input-Output",
"css": {},
@ -18,7 +18,7 @@
"id": 2,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"name": "button",
"label": null,
"css": {},

View File

@ -98,16 +98,16 @@ def fn(
demo = gr.Interface(
fn,
inputs=[
gr.Textbox(default_value="Lorem ipsum", label="Textbox"),
gr.Textbox(value="Lorem ipsum", label="Textbox"),
gr.Textbox(lines=3, placeholder="Type here..", label="Textbox 2"),
gr.Number(label="Number", default=42),
gr.Slider(minimum=10, maximum=20, default_value=15, label="Slider: 10 - 20"),
gr.Number(label="Number", value=42),
gr.Slider(minimum=10, maximum=20, value=15, label="Slider: 10 - 20"),
gr.Slider(maximum=20, step=0.04, label="Slider: step @ 0.04"),
gr.Checkbox(label="Checkbox"),
gr.CheckboxGroup(
label="CheckboxGroup", choices=CHOICES, default_selected=CHOICES[0:2]
label="CheckboxGroup", choices=CHOICES, value=CHOICES[0:2]
),
gr.Radio(label="Radio", choices=CHOICES, default_selected=CHOICES[2]),
gr.Radio(label="Radio", choices=CHOICES, value=CHOICES[2]),
gr.Dropdown(label="Dropdown", choices=CHOICES),
gr.Image(label="Image"),
gr.Image(label="Image w/ Cropper", tool="select"),

View File

@ -51,10 +51,10 @@ def outbreak(plot_type, r, month, countries, social_distancing):
inputs = [
gr.Dropdown(["Matplotlib", "Plotly", "Bokeh"], label="Plot Type"),
gr.Slider(minimum=1, maximum=4, default_value=3.2, label="R"),
gr.Slider(minimum=1, maximum=4, value=3.2, label="R"),
gr.Dropdown(["January", "February", "March", "April", "May"], label="Month"),
gr.CheckboxGroup(["USA", "Canada", "Mexico", "UK"], label="Countries",
default_selected=["USA", "Canada"]),
value=["USA", "Canada"]),
gr.Checkbox(label="Social Distancing?"),
]
outputs = gr.Plot(type="auto")

View File

@ -23,8 +23,6 @@ from gradio.components import (
Highlightedtext,
HighlightedText,
Image,
Keyvalues,
KeyValues,
Label,
Markdown,
Model3D,
@ -39,6 +37,7 @@ from gradio.components import (
Variable,
Video,
component,
update,
)
from gradio.flagging import (
CSVLogger,

View File

@ -11,6 +11,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple
from gradio import encryptor, networking, queueing, strings, utils
from gradio.context import Context
from gradio.deprecation import check_deprecated_parameters
from gradio.utils import delete_none
if TYPE_CHECKING: # Only import for type checking (is False at runtime).
from fastapi.applications import FastAPI
@ -20,10 +21,11 @@ if TYPE_CHECKING: # Only import for type checking (is False at runtime).
class Block:
def __init__(self, css=None, render=True, **kwargs):
def __init__(self, *, render=True, css=None, visible=True, **kwargs):
self._id = Context.id
Context.id += 1
self.css = css if css is not None else {}
self.visible = visible
if render:
self.render()
check_deprecated_parameters(self.__class__.__name__, **kwargs)
@ -122,6 +124,9 @@ class Block:
}
)
def get_config(self):
return {"css": self.css, "visible": self.visible}
class BlockContext(Block):
def __init__(
@ -135,8 +140,7 @@ class BlockContext(Block):
css: Css rules to apply to block.
"""
self.children = []
self.visible = visible
super().__init__(css=css, render=render, **kwargs)
super().__init__(css=css, visible=visible, render=render, **kwargs)
def __enter__(self):
self.parent = Context.block
@ -146,25 +150,24 @@ class BlockContext(Block):
def __exit__(self, *args):
Context.block = self.parent
def get_template_context(self):
return {
"css": self.css,
"default_value": self.visible,
}
def postprocess(self, y):
return y
class Row(BlockContext):
def __init__(self, visible: bool = True, css: Optional[Dict[str, str]] = None):
"""
css: Css rules to apply to block.
"""
super().__init__(visible, css)
def get_config(self):
return {"type": "row", **super().get_config()}
def get_template_context(self):
return {"type": "row", **super().get_template_context()}
@staticmethod
def update(
css: Optional[Dict] = None,
visible: Optional[bool] = None,
):
return {
"css": css,
"visible": visible,
"__type__": "update",
}
class Column(BlockContext):
@ -179,23 +182,30 @@ class Column(BlockContext):
variant: column type, 'default' (no background) or 'panel' (gray background color and rounded corners)
"""
self.variant = variant
super().__init__(visible, css)
super().__init__(visible=visible, css=css)
def get_template_context(self):
def get_config(self):
return {
"type": "column",
"variant": self.variant,
**super().get_template_context(),
**super().get_config(),
}
@staticmethod
def update(
variant: Optional[str] = None,
css: Optional[Dict] = None,
visible: Optional[bool] = None,
):
return {
"variant": variant,
"css": css,
"visible": visible,
"__type__": "update",
}
class Tabs(BlockContext):
def __init__(self, visible: bool = True, css: Optional[Dict[str, str]] = None):
"""
css: css rules to apply to block.
"""
super().__init__(visible, css)
def change(self, fn: Callable, inputs: List[Component], outputs: List[Component]):
"""
Parameters:
@ -208,17 +218,12 @@ class Tabs(BlockContext):
class TabItem(BlockContext):
def __init__(
self, label, visible: bool = True, css: Optional[Dict[str, str]] = None
):
"""
css: Css rules to apply to block.
"""
super().__init__(visible, css)
def __init__(self, label, **kwargs):
super().__init__(**kwargs)
self.label = label
def get_template_context(self):
return {"label": self.label, **super().get_template_context()}
def get_config(self):
return {"label": self.label, **super().get_config()}
def select(self, fn: Callable, inputs: List[Component], outputs: List[Component]):
"""
@ -330,11 +335,31 @@ class Blocks(BlockContext):
state[output_id] = predictions[i]
output.append(None)
else:
output.append(
block.postprocess(predictions[i])
if predictions[i] is not None
else None
)
prediction_value = predictions[i]
if type(
prediction_value
) is dict and "update" in prediction_value.get("__type__"):
if prediction_value["__type__"] == "generic_update":
del prediction_value["__type__"]
prediction_value = block.__class__.update(
**prediction_value
)
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
)
output_value = prediction_value
else:
output_value = (
block.postprocess(prediction_value)
if prediction_value is not None
else None
)
output.append(output_value)
else:
output = predictions
return {
@ -343,7 +368,7 @@ class Blocks(BlockContext):
"average_duration": block_fn.total_runtime / block_fn.total_runs,
}
def get_template_context(self):
def get_config(self):
return {"type": "column"}
def get_config_file(self):
@ -355,14 +380,15 @@ class Blocks(BlockContext):
self, "enable_queue", False
), # attribute set at launch
}
for _id, block in self.blocks.items():
config["components"].append(
{
"id": _id,
"type": (block.get_block_name()),
"props": utils.delete_none(block.get_template_context())
if hasattr(block, "get_template_context")
else None,
"props": utils.delete_none(block.get_config())
if hasattr(block, "get_config")
else {},
}
)

File diff suppressed because it is too large Load Diff

View File

@ -173,7 +173,7 @@ def get_huggingface_interface(model_name, api_key, alias):
# example model: hf.co/sentence-transformers/distilbert-base-nli-stsb-mean-tokens
"inputs": [
components.Textbox(
default_value="That is a happy person", label="Source Sentence"
value="That is a happy person", label="Source Sentence"
),
components.Textbox(
lines=7,

View File

@ -42,7 +42,7 @@ class Textbox(C_Textbox):
DeprecationWarning,
)
super().__init__(
default_value=default,
value=default,
lines=lines,
placeholder=placeholder,
label=label,
@ -75,7 +75,7 @@ class Number(C_Number):
"Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components",
DeprecationWarning,
)
super().__init__(default_value=default, label=label, optional=optional)
super().__init__(value=default, label=label, optional=optional)
class Slider(C_Slider):
@ -109,7 +109,7 @@ class Slider(C_Slider):
)
super().__init__(
default_value=default,
value=default,
minimum=minimum,
maximum=maximum,
step=step,
@ -141,7 +141,7 @@ class Checkbox(C_Checkbox):
"Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components",
DeprecationWarning,
)
super().__init__(default_value=default, label=label, optional=optional)
super().__init__(value=default, label=label, optional=optional)
class CheckboxGroup(C_CheckboxGroup):
@ -172,7 +172,7 @@ class CheckboxGroup(C_CheckboxGroup):
DeprecationWarning,
)
super().__init__(
default_selected=default,
value=default,
choices=choices,
type=type,
label=label,
@ -210,7 +210,7 @@ class Radio(C_Radio):
super().__init__(
choices=choices,
type=type,
default_selected=default,
value=default,
label=label,
optional=optional,
)
@ -246,7 +246,7 @@ class Dropdown(C_Dropdown):
super().__init__(
choices=choices,
type=type,
default_selected=default,
value=default,
label=label,
optional=optional,
)
@ -426,7 +426,7 @@ class Dataframe(C_Dataframe):
DeprecationWarning,
)
super().__init__(
default_value=default,
value=default,
headers=headers,
row_count=row_count,
col_count=col_count,
@ -488,7 +488,7 @@ class State(C_Variable):
"Usage of gradio.inputs is deprecated, and will not be supported in the future, please import this component as gr.Variable from gradio.components",
DeprecationWarning,
)
super().__init__(default_value=default, label=label)
super().__init__(value=default, label=label)
class Image3D(C_Model3D):

View File

@ -195,7 +195,7 @@ class Interface(Blocks):
"If using 'state', there must be exactly one state input and one state output."
)
default = utils.get_default_args(fn[0])[inputs.index("state")]
state_variable = Variable(default_value=default)
state_variable = Variable(value=default)
inputs[inputs.index("state")] = state_variable
outputs[outputs.index("state")] = state_variable
@ -561,7 +561,7 @@ class Interface(Blocks):
_js=f"""() => {json.dumps(
[component.cleared_value if hasattr(component, "cleared_value") else None
for component in self.input_components + self.output_components] + (
[True]
[Column.update(visible=True)]
if self.interface_type
in [
self.InterfaceTypes.STANDARD,
@ -570,7 +570,7 @@ class Interface(Blocks):
]
else []
)
+ ([False] if self.interpretation else [])
+ ([Column.update(visible=False)] if self.interpretation else [])
)}
""",
)
@ -631,7 +631,8 @@ class Interface(Blocks):
if self.interpretation:
interpretation_btn.click(
lambda *data: self.interpret(data) + [False, True],
lambda *data: self.interpret(data)
+ [Column.update(visible=False), Column.update(visible=True)],
inputs=self.input_components + self.output_components,
outputs=interpretation_set
+ [input_component_column, interpret_component_column],

File diff suppressed because one or more lines are too long

View File

@ -238,12 +238,10 @@ class KeyValues:
Demos: text_analysis
"""
def __init__(
self, default_value: str = " ", *, label: Optional[str] = None, **kwargs
):
def __init__(self, value: str = " ", *, label: Optional[str] = None, **kwargs):
"""
Parameters:
default_value (str): IGNORED
value (str): IGNORED
label (str): component name in interface.
"""
raise DeprecationWarning(

View File

@ -238,7 +238,7 @@ def create_app() -> FastAPI:
if hasattr(body, "session_hash"):
if body.session_hash not in app.state_holder:
app.state_holder[body.session_hash] = {
_id: getattr(block, "default_value", None)
_id: getattr(block, "value", None)
for _id, block in app.blocks.blocks.items()
if getattr(block, "stateful", False)
}

View File

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html
lang="en"
style="
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
flex-grow: 1;
height: 100%;
"
>
<head>
<base target="_blank" />
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta property="og:url" content="https://gradio.app/" />
<meta property="og:type" content="website" />
<meta property="og:image" content="{{ config['thumbnail'] or '' }}" />
<meta property="og:title" content="{{ config['title'] or '' }}" />
<meta
property="og:description"
content="{{ config['simple_description'] or '' }}"
/>
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content="@teamGradio" />
<meta name="twitter:title" content="{{ config['title'] or '' }}" />
<meta
name="twitter:description"
content="{{ config['simple_description'] or '' }}"
/>
<meta name="twitter:image" content="{{ config['thumbnail'] or '' }}" />
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "UA-156449732-1");
window.gradio_mode = "app";
</script>
<script>window.gradio_config = {{ config | tojson }};</script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossorigin="anonymous"
/>
<link
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600&family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=IBM+Plex+Serif:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
rel="stylesheet"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script>
<script type="module" crossorigin src="./assets/index.0064653a.js"></script>
<link rel="stylesheet" href="./assets/index.bac7eb5e.css">
</head>
<body
style="
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
flex-grow: 1;
"
>
<div
id="root"
style="display: flex; flex-direction: column; flex-grow: 1"
></div>
</body>
</html>

View File

@ -5,9 +5,10 @@ XRAY_CONFIG = {
"id": 1,
"type": "markdown",
"props": {
"default_value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"css": {},
"visible": True,
},
},
{
@ -15,24 +16,21 @@ XRAY_CONFIG = {
"type": "checkboxgroup",
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"default_value": [],
"value": [],
"label": "Disease to Scan For",
"show_label": True,
"name": "checkboxgroup",
"css": {},
"visible": True,
},
},
{"id": 3, "type": "tabs", "props": {"css": {}, "default_value": True}},
{"id": 3, "type": "tabs", "props": {"css": {}, "visible": True}},
{
"id": 4,
"type": "tabitem",
"props": {"label": "X-ray", "css": {}, "default_value": True},
},
{
"id": 5,
"type": "row",
"props": {"type": "row", "css": {}, "default_value": True},
"props": {"label": "X-ray", "css": {}, "visible": True},
},
{"id": 5, "type": "row", "props": {"type": "row", "css": {}, "visible": True}},
{
"id": 6,
"type": "image",
@ -43,38 +41,37 @@ XRAY_CONFIG = {
"show_label": True,
"name": "image",
"css": {},
"visible": True,
},
},
{
"id": 7,
"type": "json",
"props": {
"default_value": '""',
"value": '""',
"show_label": True,
"name": "json",
"css": {},
"visible": True,
},
},
{
"id": 8,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"variant": "primary",
"name": "button",
"css": {"background-color": "red", "--hover-color": "orange"},
"variant": "primary",
"visible": True,
},
},
{
"id": 9,
"type": "tabitem",
"props": {"label": "CT Scan", "css": {}, "default_value": True},
},
{
"id": 10,
"type": "row",
"props": {"type": "row", "css": {}, "default_value": True},
"props": {"label": "CT Scan", "css": {}, "visible": True},
},
{"id": 10, "type": "row", "props": {"type": "row", "css": {}, "visible": True}},
{
"id": 11,
"type": "image",
@ -85,26 +82,29 @@ XRAY_CONFIG = {
"show_label": True,
"name": "image",
"css": {},
"visible": True,
},
},
{
"id": 12,
"type": "json",
"props": {
"default_value": '""',
"value": '""',
"show_label": True,
"name": "json",
"css": {},
"visible": True,
},
},
{
"id": 13,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"variant": "primary",
"name": "button",
"css": {},
"variant": "primary",
"visible": True,
},
},
{
@ -113,10 +113,11 @@ XRAY_CONFIG = {
"props": {
"lines": 1,
"max_lines": 20,
"default_value": "",
"value": "",
"show_label": True,
"name": "textbox",
"css": {},
"visible": True,
},
},
],
@ -190,9 +191,10 @@ XRAY_CONFIG_DIFF_IDS = {
"id": 1,
"type": "markdown",
"props": {
"default_value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"css": {},
"visible": True,
},
},
{
@ -200,74 +202,62 @@ XRAY_CONFIG_DIFF_IDS = {
"type": "checkboxgroup",
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"default_value": [],
"name": "checkboxgroup",
"show_label": True,
"value": [],
"label": "Disease to Scan For",
"show_label": True,
"name": "checkboxgroup",
"css": {},
"visible": True,
},
},
{"id": 3, "type": "tabs", "props": {"css": {}, "default_value": True}},
{"id": 3, "type": "tabs", "props": {"css": {}, "visible": True}},
{
"id": 444,
"type": "tabitem",
"props": {
"label": "X-ray",
"css": {},
"default_value": True,
},
},
{
"id": 5,
"type": "row",
"props": {"type": "row", "css": {}, "default_value": True},
"props": {"label": "X-ray", "css": {}, "visible": True},
},
{"id": 5, "type": "row", "props": {"type": "row", "css": {}, "visible": True}},
{
"id": 6,
"type": "image",
"props": {
"image_mode": "RGB",
"source": "upload",
"show_label": True,
"tool": "editor",
"show_label": True,
"name": "image",
"css": {},
"visible": True,
},
},
{
"id": 7,
"type": "json",
"props": {
"default_value": '""',
"name": "json",
"value": '""',
"show_label": True,
"name": "json",
"css": {},
"visible": True,
},
},
{
"id": 8888,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"variant": "primary",
"name": "button",
"css": {"background-color": "red", "--hover-color": "orange"},
"variant": "primary",
"visible": True,
},
},
{
"id": 9,
"type": "tabitem",
"props": {
"label": "CT Scan",
"css": {},
"default_value": True,
},
},
{
"id": 10,
"type": "row",
"props": {"type": "row", "css": {}, "default_value": True},
"props": {"label": "CT Scan", "css": {}, "visible": True},
},
{"id": 10, "type": "row", "props": {"type": "row", "css": {}, "visible": True}},
{
"id": 11,
"type": "image",
@ -275,29 +265,32 @@ XRAY_CONFIG_DIFF_IDS = {
"image_mode": "RGB",
"source": "upload",
"tool": "editor",
"name": "image",
"show_label": True,
"name": "image",
"css": {},
"visible": True,
},
},
{
"id": 12,
"type": "json",
"props": {
"default_value": '""',
"name": "json",
"value": '""',
"show_label": True,
"name": "json",
"css": {},
"visible": True,
},
},
{
"id": 13,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"variant": "primary",
"name": "button",
"css": {},
"variant": "primary",
"visible": True,
},
},
{
@ -305,15 +298,17 @@ XRAY_CONFIG_DIFF_IDS = {
"type": "textbox",
"props": {
"lines": 1,
"default_value": "",
"name": "textbox",
"max_lines": 20,
"value": "",
"show_label": True,
"name": "textbox",
"css": {},
"visible": True,
},
},
],
"theme": "default",
"enable_queue": False,
"layout": {
"id": 0,
"children": [
@ -347,14 +342,30 @@ XRAY_CONFIG_DIFF_IDS = {
"trigger": "click",
"inputs": [22, 6],
"outputs": [7],
"backend_fn": True,
"js": None,
"status_tracker": None,
"queue": None,
},
{
"targets": [13],
"trigger": "click",
"inputs": [22, 11],
"outputs": [12],
"backend_fn": True,
"js": None,
"status_tracker": None,
"queue": None,
},
{
"targets": [],
"trigger": "load",
"inputs": [],
"outputs": [141],
"backend_fn": True,
"js": False,
"status_tracker": None,
"queue": None,
},
],
}
@ -366,7 +377,7 @@ XRAY_CONFIG_WITH_MISTAKE = {
"id": 1,
"type": "markdown",
"props": {
"default_value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"value": "<h1>Detect Disease From Scan</h1>\n<p>With this model you can lorem ipsum</p>\n<ul>\n<li>ipsum 1</li>\n<li>ipsum 2</li>\n</ul>\n",
"name": "markdown",
"css": {},
},
@ -376,27 +387,27 @@ XRAY_CONFIG_WITH_MISTAKE = {
"type": "checkboxgroup",
"props": {
"choices": ["Covid", "Malaria", "Lung Cancer"],
"default_value": [],
"value": [],
"name": "checkboxgroup",
"show_label": True,
"label": "Disease to Scan For",
"css": {},
},
},
{"id": 3, "type": "tabs", "props": {"css": {}, "default_value": True}},
{"id": 3, "type": "tabs", "props": {"css": {}, "value": True}},
{
"id": 4,
"type": "tabitem",
"props": {
"label": "X-ray",
"css": {},
"default_value": True,
"value": True,
},
},
{
"id": 5,
"type": "row",
"props": {"type": "row", "css": {}, "default_value": True},
"props": {"type": "row", "css": {}, "value": True},
},
{
"id": 6,
@ -413,7 +424,7 @@ XRAY_CONFIG_WITH_MISTAKE = {
"id": 7,
"type": "json",
"props": {
"default_value": '""',
"value": '""',
"name": "json",
"css": {},
},
@ -422,7 +433,7 @@ XRAY_CONFIG_WITH_MISTAKE = {
"id": 8,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"name": "button",
"css": {"background-color": "red", "--hover-color": "orange"},
"variant": "primary",
@ -435,13 +446,13 @@ XRAY_CONFIG_WITH_MISTAKE = {
"show_label": True,
"label": "CT Scan",
"css": {},
"default_value": True,
"value": True,
},
},
{
"id": 10,
"type": "row",
"props": {"type": "row", "css": {}, "default_value": True},
"props": {"type": "row", "css": {}, "value": True},
},
{
"id": 11,
@ -458,7 +469,7 @@ XRAY_CONFIG_WITH_MISTAKE = {
"id": 12,
"type": "json",
"props": {
"default_value": '""',
"value": '""',
"name": "json",
"css": {},
},
@ -467,7 +478,7 @@ XRAY_CONFIG_WITH_MISTAKE = {
"id": 13,
"type": "button",
"props": {
"default_value": "Run",
"value": "Run",
"name": "button",
"css": {},
"variant": "primary",
@ -478,7 +489,7 @@ XRAY_CONFIG_WITH_MISTAKE = {
"type": "textbox",
"props": {
"lines": 1,
"default_value": "",
"value": "",
"name": "textbox",
"css": {},
},

View File

@ -181,112 +181,6 @@ def launch_counter() -> None:
pass
def get_config_file(interface: Interface) -> Dict[str, Any]:
config = {
"input_components": [
iface.get_template_context() for iface in interface.input_components
],
"output_components": [
iface.get_template_context() for iface in interface.output_components
],
"function_count": len(interface.predict),
"live": interface.live,
"examples_per_page": interface.examples_per_page,
"layout": interface.layout,
"show_input": interface.show_input,
"show_output": interface.show_output,
"title": interface.title,
"analytics_enabled": interface.analytics_enabled,
"description": interface.description,
"simple_description": interface.simple_description,
"article": interface.article,
"theme": interface.theme,
"css": interface.css,
"thumbnail": interface.thumbnail,
"allow_screenshot": interface.allow_screenshot,
"allow_flagging": interface.allow_flagging,
"flagging_options": interface.flagging_options,
"allow_interpretation": interface.interpretation is not None,
"enable_queue": interface.enable_queue,
"cached_examples": interface.cache_examples
if hasattr(interface, "cache_examples")
else False,
"version": pkg_resources.require("gradio")[0].version,
"favicon_path": interface.favicon_path,
}
try:
param_names = inspect.getfullargspec(interface.predict[0])[0]
for index, component in enumerate(config["input_components"]):
if not component["label"]:
if index < len(param_names):
component["label"] = param_names[index].replace("_", " ")
else:
component["label"] = (
f"input {index + 1}"
if len(config["input_components"]) > 1
else "input"
)
for index, component in enumerate(config["output_components"]):
outputs_per_function = int(
len(interface.output_components) / len(interface.predict)
)
function_index = index // outputs_per_function
component_index = index - function_index * outputs_per_function
if component["label"] is None:
component["label"] = (
f"output {component_index + 1}"
if outputs_per_function > 1
else "output"
)
if len(interface.predict) > 1:
component["label"] = (
interface.function_names[function_index].replace("_", " ")
+ ": "
+ component["label"]
)
except ValueError:
pass
if interface.examples is not None:
if isinstance(interface.examples, str):
if not os.path.exists(interface.examples):
raise FileNotFoundError(
"Could not find examples directory: " + interface.examples
)
log_file = os.path.join(interface.examples, "log.csv")
if not os.path.exists(log_file):
if len(interface.input_components) == 1:
examples = [
[os.path.join(interface.examples, item)]
for item in os.listdir(interface.examples)
]
else:
raise FileNotFoundError(
"Could not find log file (required for multiple inputs): "
+ log_file
)
else:
with open(log_file) as logs:
examples = list(csv.reader(logs))
examples = examples[1:] # remove header
for i, example in enumerate(examples):
for j, (component, cell) in enumerate(
zip(
interface.input_components + interface.output_components,
example,
)
):
examples[i][j] = component.restore_flagged(
interface.flagging_dir,
cell,
interface.encryption_key if interface.encrypt else None,
)
config["examples"] = examples
config["examples_dir"] = interface.examples
else:
config["examples"] = interface.examples
return config
def get_default_args(func: Callable) -> Dict[str, Any]:
signature = inspect.signature(func)
return [

View File

@ -51,7 +51,6 @@ class TestBlocks(unittest.TestCase):
)
textbox = gr.components.Textbox()
demo.load(fake_func, [], [textbox])
self.assertEqual(XRAY_CONFIG, demo.get_config_file())

View File

@ -33,7 +33,7 @@ class TestComponent(unittest.TestCase):
class TestTextbox(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, postprocess, serialize, save_flagged, restore_flagged, tokenize, generate_sample, get_template_context
Preprocess, postprocess, serialize, save_flagged, restore_flagged, tokenize, generate_sample, get_config
"""
text_input = gr.Textbox()
self.assertEqual(text_input.preprocess("Hello World!"), "Hello World!")
@ -82,16 +82,17 @@ class TestTextbox(unittest.TestCase):
),
)
self.assertEqual(
text_input.get_template_context(),
text_input.get_config(),
{
"lines": 1,
"max_lines": 20,
"placeholder": None,
"default_value": "",
"value": "",
"name": "textbox",
"show_label": True,
"label": None,
"css": {},
"visible": True,
"interactive": None,
},
)
@ -152,7 +153,7 @@ class TestTextbox(unittest.TestCase):
class TestNumber(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, postprocess, serialize, save_flagged, restore_flagged, generate_sample, set_interpret_parameters, get_interpretation_neighbors, get_template_context
Preprocess, postprocess, serialize, save_flagged, restore_flagged, generate_sample, set_interpret_parameters, get_interpretation_neighbors, get_config
"""
numeric_input = gr.Number()
@ -180,13 +181,14 @@ class TestNumber(unittest.TestCase):
([0.97, 0.98, 0.99, 1.01, 1.02, 1.03], {}),
)
self.assertEqual(
numeric_input.get_template_context(),
numeric_input.get_config(),
{
"default_value": None,
"value": None,
"name": "number",
"show_label": True,
"label": None,
"css": {},
"visible": True,
"interactive": None,
},
)
@ -241,7 +243,7 @@ class TestNumber(unittest.TestCase):
class TestSlider(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, postprocess, serialize, save_flagged, restore_flagged, generate_sample, get_template_context
Preprocess, postprocess, serialize, save_flagged, restore_flagged, generate_sample, get_config
"""
slider_input = gr.Slider()
self.assertEqual(slider_input.preprocess(3.0), 3.0)
@ -257,19 +259,20 @@ class TestSlider(unittest.TestCase):
self.assertIsInstance(slider_input.generate_sample(), int)
slider_input = gr.Slider(
default_value=15, minimum=10, maximum=20, step=1, label="Slide Your Input"
value=15, minimum=10, maximum=20, step=1, label="Slide Your Input"
)
self.assertEqual(
slider_input.get_template_context(),
slider_input.get_config(),
{
"minimum": 10,
"maximum": 20,
"step": 1,
"default_value": 15,
"value": 15,
"name": "slider",
"show_label": True,
"label": "Slide Your Input",
"css": {},
"visible": True,
"interactive": None,
},
)
@ -302,7 +305,7 @@ class TestSlider(unittest.TestCase):
class TestCheckbox(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, postprocess, serialize, generate_sample, get_template_context
Preprocess, postprocess, serialize, generate_sample, get_config
"""
bool_input = gr.Checkbox()
self.assertEqual(bool_input.preprocess(True), True)
@ -315,15 +318,16 @@ class TestCheckbox(unittest.TestCase):
restored = bool_input.restore_flagged(tmpdirname, to_save, None)
self.assertEqual(restored, True)
self.assertIsInstance(bool_input.generate_sample(), bool)
bool_input = gr.Checkbox(default_value=True, label="Check Your Input")
bool_input = gr.Checkbox(value=True, label="Check Your Input")
self.assertEqual(
bool_input.get_template_context(),
bool_input.get_config(),
{
"default_value": True,
"value": True,
"name": "checkbox",
"show_label": True,
"label": "Check Your Input",
"css": {},
"visible": True,
"interactive": None,
},
)
@ -346,7 +350,7 @@ class TestCheckbox(unittest.TestCase):
class TestCheckboxGroup(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, preprocess_example, serialize, save_flagged, restore_flagged, generate_sample, get_template_context
Preprocess, preprocess_example, serialize, save_flagged, restore_flagged, generate_sample, get_config
"""
checkboxes_input = gr.CheckboxGroup(["a", "b", "c"])
self.assertEqual(checkboxes_input.preprocess(["a", "c"]), ["a", "c"])
@ -361,19 +365,20 @@ class TestCheckboxGroup(unittest.TestCase):
self.assertEqual(restored, ["a", "c"])
self.assertIsInstance(checkboxes_input.generate_sample(), list)
checkboxes_input = gr.CheckboxGroup(
default_selected=["a", "c"],
value=["a", "c"],
choices=["a", "b", "c"],
label="Check Your Inputs",
)
self.assertEqual(
checkboxes_input.get_template_context(),
checkboxes_input.get_config(),
{
"choices": ["a", "b", "c"],
"default_value": ["a", "c"],
"value": ["a", "c"],
"name": "checkboxgroup",
"show_label": True,
"label": "Check Your Inputs",
"css": {},
"visible": True,
"interactive": None,
},
)
@ -395,7 +400,7 @@ class TestCheckboxGroup(unittest.TestCase):
class TestRadio(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, preprocess_example, serialize, save_flagged, generate_sample, get_template_context
Preprocess, preprocess_example, serialize, save_flagged, generate_sample, get_config
"""
radio_input = gr.Radio(["a", "b", "c"])
@ -412,14 +417,15 @@ class TestRadio(unittest.TestCase):
choices=["a", "b", "c"], default="a", label="Pick Your One Input"
)
self.assertEqual(
radio_input.get_template_context(),
radio_input.get_config(),
{
"choices": ["a", "b", "c"],
"default_value": "a",
"value": "a",
"name": "radio",
"show_label": True,
"label": "Pick Your One Input",
"css": {},
"visible": True,
"interactive": None,
},
)
@ -446,7 +452,7 @@ class TestRadio(unittest.TestCase):
class TestImage(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, postprocess, serialize, save_flagged, restore_flagged, generate_sample, get_template_context, _segment_by_slic
Preprocess, postprocess, serialize, save_flagged, restore_flagged, generate_sample, get_config, _segment_by_slic
type: pil, file, filepath, numpy
"""
img = deepcopy(media_data.BASE64_IMAGE)
@ -471,7 +477,7 @@ class TestImage(unittest.TestCase):
source="upload", tool="editor", type="pil", label="Upload Your Image"
)
self.assertEqual(
image_input.get_template_context(),
image_input.get_config(),
{
"image_mode": "RGB",
"shape": None,
@ -481,7 +487,8 @@ class TestImage(unittest.TestCase):
"show_label": True,
"label": "Upload Your Image",
"css": {},
"default_value": None,
"visible": True,
"value": None,
"interactive": None,
},
)
@ -605,7 +612,7 @@ class TestImage(unittest.TestCase):
class TestAudio(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, postprocess serialize, save_flagged, restore_flagged, generate_sample, get_template_context, deserialize
Preprocess, postprocess serialize, save_flagged, restore_flagged, generate_sample, get_config, deserialize
type: filepath, numpy, file
"""
x_wav = deepcopy(media_data.BASE64_AUDIO)
@ -629,14 +636,15 @@ class TestAudio(unittest.TestCase):
self.assertIsInstance(audio_input.generate_sample(), dict)
audio_input = gr.Audio(label="Upload Your Audio")
self.assertEqual(
audio_input.get_template_context(),
audio_input.get_config(),
{
"source": "upload",
"name": "audio",
"show_label": True,
"label": "Upload Your Audio",
"css": {},
"default_value": None,
"visible": True,
"value": None,
"interactive": None,
},
)
@ -670,14 +678,15 @@ class TestAudio(unittest.TestCase):
)
)
self.assertEqual(
audio_output.get_template_context(),
audio_output.get_config(),
{
"name": "audio",
"show_label": True,
"label": None,
"source": "upload",
"css": {},
"default_value": None,
"visible": True,
"value": None,
"interactive": None,
},
)
@ -744,7 +753,7 @@ class TestAudio(unittest.TestCase):
class TestFile(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, serialize, save_flagged, restore_flagged, generate_sample, get_template_context, default_value
Preprocess, serialize, save_flagged, restore_flagged, generate_sample, get_config, value
"""
x_file = deepcopy(media_data.BASE64_FILE)
file_input = gr.File()
@ -766,14 +775,15 @@ class TestFile(unittest.TestCase):
self.assertIsInstance(file_input.generate_sample(), dict)
file_input = gr.File(label="Upload Your File")
self.assertEqual(
file_input.get_template_context(),
file_input.get_config(),
{
"file_count": "single",
"name": "file",
"show_label": True,
"label": "Upload Your File",
"css": {},
"default_value": None,
"visible": True,
"value": None,
"interactive": None,
},
)
@ -783,7 +793,7 @@ class TestFile(unittest.TestCase):
file_input = gr.File("test/test_files/sample_file.pdf")
self.assertEqual(
file_input.get_template_context(),
file_input.get_config(),
deepcopy(media_data.FILE_TEMPLATE_CONTEXT),
)
@ -833,7 +843,7 @@ class TestFile(unittest.TestCase):
class TestDataframe(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, serialize, save_flagged, restore_flagged, generate_sample, get_template_context
Preprocess, serialize, save_flagged, restore_flagged, generate_sample, get_config
"""
x_data = [["Tim", 12, False], ["Jan", 24, True]]
dataframe_input = gr.Dataframe(headers=["Name", "Age", "Member"])
@ -856,13 +866,13 @@ class TestDataframe(unittest.TestCase):
headers=["Name", "Age", "Member"], label="Dataframe Input"
)
self.assertEqual(
dataframe_input.get_template_context(),
dataframe_input.get_config(),
{
"headers": ["Name", "Age", "Member"],
"datatype": "str",
"row_count": (3, "dynamic"),
"col_count": (3, "dynamic"),
"default_value": [
"value": [
["", "", ""],
["", "", ""],
["", "", ""],
@ -874,6 +884,7 @@ class TestDataframe(unittest.TestCase):
"max_cols": None,
"overflow_row_behaviour": "paginate",
"css": {},
"visible": True,
"interactive": None,
},
)
@ -901,7 +912,7 @@ class TestDataframe(unittest.TestCase):
},
)
self.assertEqual(
dataframe_output.get_template_context(),
dataframe_output.get_config(),
{
"headers": None,
"max_rows": 20,
@ -911,10 +922,11 @@ class TestDataframe(unittest.TestCase):
"show_label": True,
"label": None,
"css": {},
"visible": True,
"datatype": "str",
"row_count": (3, "dynamic"),
"col_count": (3, "dynamic"),
"default_value": [
"value": [
["", "", ""],
["", "", ""],
["", "", ""],
@ -976,7 +988,7 @@ class TestDataframe(unittest.TestCase):
class TestVideo(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, serialize, deserialize, save_flagged, restore_flagged, generate_sample, get_template_context
Preprocess, serialize, deserialize, save_flagged, restore_flagged, generate_sample, get_config
"""
x_video = deepcopy(media_data.BASE64_VIDEO)
video_input = gr.Video()
@ -994,14 +1006,15 @@ class TestVideo(unittest.TestCase):
self.assertIsInstance(video_input.generate_sample(), dict)
video_input = gr.Video(label="Upload Your Video")
self.assertEqual(
video_input.get_template_context(),
video_input.get_config(),
{
"source": "upload",
"name": "video",
"show_label": True,
"label": "Upload Your Video",
"css": {},
"default_value": None,
"visible": True,
"value": None,
"interactive": None,
},
)
@ -1048,7 +1061,7 @@ class TestVideo(unittest.TestCase):
class TestTimeseries(unittest.TestCase):
def test_component_functions(self):
"""
Preprocess, postprocess, save_flagged, restore_flagged, generate_sample, get_template_context,
Preprocess, postprocess, save_flagged, restore_flagged, generate_sample, get_config,
"""
timeseries_input = gr.Timeseries(x="time", y=["retail", "food", "other"])
x_timeseries = {
@ -1071,7 +1084,7 @@ class TestTimeseries(unittest.TestCase):
x="time", y="retail", label="Upload Your Timeseries"
)
self.assertEqual(
timeseries_input.get_template_context(),
timeseries_input.get_config(),
{
"x": "time",
"y": ["retail"],
@ -1080,7 +1093,8 @@ class TestTimeseries(unittest.TestCase):
"label": "Upload Your Timeseries",
"colors": None,
"css": {},
"default_value": None,
"visible": True,
"value": None,
"interactive": None,
},
)
@ -1093,7 +1107,7 @@ class TestTimeseries(unittest.TestCase):
timeseries_output = gr.Timeseries(label="Disease")
self.assertEqual(
timeseries_output.get_template_context(),
timeseries_output.get_config(),
{
"x": None,
"y": None,
@ -1102,7 +1116,8 @@ class TestTimeseries(unittest.TestCase):
"label": "Disease",
"colors": None,
"css": {},
"default_value": None,
"visible": True,
"value": None,
"interactive": None,
},
)
@ -1269,12 +1284,13 @@ class TestLabel(unittest.TestCase):
)
self.assertEqual(
label_output.get_template_context(),
label_output.get_config(),
{
"name": "label",
"show_label": True,
"label": None,
"css": {},
"visible": True,
"interactive": None,
},
)
@ -1313,11 +1329,11 @@ class TestLabel(unittest.TestCase):
class TestHighlightedText(unittest.TestCase):
def test_component_functions(self):
"""
get_template_context, save_flagged, restore_flagged
get_config, save_flagged, restore_flagged
"""
ht_output = gr.HighlightedText(color_map={"pos": "green", "neg": "red"})
self.assertEqual(
ht_output.get_template_context(),
ht_output.get_config(),
{
"color_map": {"pos": "green", "neg": "red"},
"name": "highlightedtext",
@ -1325,7 +1341,8 @@ class TestHighlightedText(unittest.TestCase):
"label": None,
"show_legend": False,
"css": {},
"default_value": "",
"visible": True,
"value": "",
"interactive": None,
},
)
@ -1383,10 +1400,11 @@ class TestJSON(unittest.TestCase):
{"pos": "Hello ", "neg": "World"},
)
self.assertEqual(
js_output.get_template_context(),
js_output.get_config(),
{
"css": {},
"default_value": '""',
"visible": True,
"value": '""',
"show_label": True,
"label": None,
"name": "json",
@ -1424,19 +1442,20 @@ class TestJSON(unittest.TestCase):
class TestHTML(unittest.TestCase):
def test_component_functions(self):
"""
Get_template_context
get_config
"""
html_component = gr.components.HTML("#Welcome onboard", label="HTML Input")
self.assertEqual(
{
"css": {},
"default_value": "#Welcome onboard",
"visible": True,
"value": "#Welcome onboard",
"show_label": True,
"label": "HTML Input",
"name": "html",
"interactive": None,
},
html_component.get_template_context(),
html_component.get_config(),
)
def test_in_interface(self):
@ -1454,7 +1473,7 @@ class TestHTML(unittest.TestCase):
class TestCarousel(unittest.TestCase):
def test_component_functions(self):
"""
Postprocess, get_template_context, save_flagged, restore_flagged
Postprocess, get_config, save_flagged, restore_flagged
"""
carousel_output = gr.Carousel(
components=[gr.Textbox(), gr.Image()], label="Disease"
@ -1478,17 +1497,18 @@ class TestCarousel(unittest.TestCase):
output = carousel_output.postprocess([["Hello World"], ["Bye World"]])
self.assertEqual(output, [["Hello World"], ["Bye World"]])
self.assertEqual(
carousel_output.get_template_context(),
carousel_output.get_config(),
{
"components": [
{
"name": "textbox",
"show_label": True,
"label": None,
"default_value": "",
"value": "",
"lines": 1,
"max_lines": 20,
"css": {},
"visible": True,
"placeholder": None,
"interactive": None,
}
@ -1497,6 +1517,7 @@ class TestCarousel(unittest.TestCase):
"show_label": True,
"label": "Disease",
"css": {},
"visible": True,
"interactive": None,
},
)

View File

@ -3,7 +3,6 @@
import { component_map } from "./components/directory";
import { loading_status } from "./stores";
import type { LoadingStatus } from "./stores";
import { Component as Column } from "./components/Column";
import { _ } from "svelte-i18n";
import { setupi18n } from "./i18n";
@ -12,19 +11,24 @@
setupi18n();
interface Component {
id: string;
id: number;
type: string;
has_modes?: boolean;
props: {
name: keyof typeof component_map;
css: Record<string, string>;
name?: keyof typeof component_map;
css?: Record<string, string>;
visible?: boolean;
[key: string]: unknown;
};
instance?: SvelteComponentTyped;
value?: unknown;
component?: any;
children?: Array<Component>;
}
interface Layout {
name: string;
type: string;
children: Layout | number;
interface LayoutNode {
id: number;
children: Array<LayoutNode>;
}
interface Dependency {
@ -43,7 +47,7 @@
export let root: string;
export let fn: (...args: any) => Promise<unknown>;
export let components: Array<Component>;
export let layout: Layout;
export let layout: LayoutNode;
export let dependencies: Array<Dependency>;
export let theme: string;
export let style: string | null;
@ -52,6 +56,9 @@
export let title: string = "Gradio";
export let analytics_enabled: boolean = false;
let rootNode: Component = { id: layout.id, type: "column", props: {} };
components.push(rootNode);
dependencies.forEach((d) => {
if (d.js) {
try {
@ -71,22 +78,10 @@
return acc;
}, new Set());
interface Instance {
props?: Record<string, unknown>;
id: number;
type: string;
instance?: SvelteComponentTyped;
value?: unknown;
}
let instance_map = components.reduce((acc, next) => {
return {
...acc,
[next.id]: {
...next
}
};
}, {} as { [id: number]: Instance });
acc[next.id] = next;
return acc;
}, {} as { [id: number]: Component });
function load_component<T extends keyof typeof component_map>(
name: T
@ -102,22 +97,19 @@
});
}
async function walk_layout(node) {
const _n = { id: node.id };
const meta = instance_map[_n.id];
_n.props = meta.props || {};
const _module = (await _component_map.get(meta.type)).component;
_n.component = _module.Component;
if (_module.modes.length > 1) {
_n.has_modes = true;
async function walk_layout(node: LayoutNode) {
let instance = instance_map[node.id];
console.log(node.id, instance_map);
const _component = (await _component_map.get(instance.type)).component;
instance.component = _component.Component;
if (_component.modes.length > 1) {
instance.has_modes = true;
}
if (node.children) {
_n.children = await Promise.all(node.children.map((v) => walk_layout(v)));
instance.children = node.children.map((v) => instance_map[v.id]);
await Promise.all(node.children.map((v) => walk_layout(v)));
}
return _n;
}
const component_set = new Set();
@ -128,21 +120,19 @@
_component_map.set(c.type, _c);
});
let tree;
Promise.all(Array.from(component_set)).then((v) => {
Promise.all(layout.children.map((c) => walk_layout(c))).then((v) => {
console.log(v);
tree = v;
let ready = false;
Promise.all(Array.from(component_set)).then(() => {
walk_layout(layout).then(() => {
ready = true;
});
});
function set_prop(obj: Instance, prop: string, val: any) {
function set_prop(obj: Component, prop: string, val: any) {
if (!obj?.props) {
obj.props = {};
}
obj.props[prop] = val;
tree = tree;
rootNode = rootNode;
}
let handled_dependencies: Array<number[]> = [];
@ -155,7 +145,7 @@
{ targets, trigger, inputs, outputs, queue, backend_fn, frontend_fn },
i
) => {
const target_instances: [number, Instance][] = targets.map((t) => [
const target_instances: [number, Component][] = targets.map((t) => [
t,
instance_map[t]
]);
@ -175,13 +165,30 @@
frontend_fn,
payload: {
fn_index: i,
data: inputs.map((id) => instance_map[id].value)
data: inputs.map((id) => instance_map[id].props.value)
},
queue: queue === null ? enable_queue : queue
})
.then((output) => {
output.data.forEach((value, i) => {
instance_map[outputs[i]].value = value;
if (
typeof value === "object" &&
value !== null &&
value.__type__ == "update"
) {
for (const [update_key, update_value] of Object.entries(
value
)) {
if (update_key === "__type__") {
continue;
} else {
instance_map[outputs[i]].props[update_key] = update_value;
}
}
rootNode = rootNode;
} else {
instance_map[outputs[i]].props.value = value;
}
});
})
.catch((error) => {
@ -191,7 +198,7 @@
handled_dependencies[i] = [-1];
}
target_instances.forEach(([id, { instance }]: [number, Instance]) => {
target_instances.forEach(([id, { instance }]: [number, Component]) => {
if (handled_dependencies[i]?.includes(id) || !instance) return;
instance?.$on(trigger, () => {
if (loading_status.get_status_for_fn(i) === "pending") {
@ -205,14 +212,32 @@
frontend_fn,
payload: {
fn_index: i,
data: inputs.map((id) => instance_map[id].value)
data: inputs.map((id) => instance_map[id].props.value)
},
output_data: outputs.map((id) => instance_map[id].value),
output_data: outputs.map((id) => instance_map[id].props.value),
queue: queue === null ? enable_queue : queue
})
.then((output) => {
output.data.forEach((value, i) => {
instance_map[outputs[i]].value = value;
if (
typeof value === "object" &&
value !== null &&
value.__type__ == "update"
) {
for (const [update_key, update_value] of Object.entries(
value
)) {
if (update_key === "__type__") {
continue;
} else {
instance_map[outputs[i]].props[update_key] =
update_value;
}
}
rootNode = rootNode;
} else {
instance_map[outputs[i]].props.value = value;
}
});
})
.catch((error) => {
@ -259,26 +284,21 @@
</svelte:head>
<div class="mx-auto container px-4 py-6 dark:bg-gray-950">
<Column default_value={true}>
{#if tree}
{#each tree as { component, id, props, children, has_modes }}
<Render
{has_modes}
{dynamic_ids}
{component}
{id}
{props}
{children}
{instance_map}
{theme}
{root}
{status_tracker_values}
on:mount={handle_mount}
on:destroy={({ detail }) => handle_destroy(detail)}
/>
{/each}
{/if}
</Column>
{#if ready}
<Render
component={rootNode.component}
id={rootNode.id}
props={rootNode.props}
children={rootNode.children}
{dynamic_ids}
{instance_map}
{theme}
{root}
{status_tracker_values}
on:mount={handle_mount}
on:destroy={({ detail }) => handle_destroy(detail)}
/>
{/if}
</div>
<div
class="gradio-page container mx-auto flex flex-col box-border flex-grow text-gray-700 dark:text-gray-50"

View File

@ -6,11 +6,19 @@
export let component;
export let instance_map;
export let id: number;
export let props;
export let children;
export let props: {
css: Record<string, string>;
visible: boolean;
[key: string]: unknown;
};
interface LayoutNode {
id: number;
children: Array<LayoutNode>;
}
export let children: Array<LayoutNode>;
export let theme;
export let dynamic_ids: Set<number>;
export let has_modes: boolean;
export let has_modes: boolean | undefined;
export let status_tracker_values: Record<number, string>;
export let parent: string | null = null;
@ -34,11 +42,17 @@
return () => dispatch("destroy", id);
});
let style = props.css
? Object.entries(props.css)
.map((rule) => rule[0] + ": " + rule[1])
.join("; ")
: null;
let style: string = "";
$: {
style = props.css
? Object.entries(props.css)
.map((rule) => rule[0] + ": " + rule[1])
.join("; ")
: "";
if (props.visible === false) {
style += " display: none !important;";
}
}
const forms = [
"textbox",
@ -95,7 +109,7 @@
<svelte:component
this={component}
bind:this={instance_map[id].instance}
bind:value={instance_map[id].value}
bind:value={instance_map[id].props.value}
{style}
{...props}
{root}

View File

@ -11,7 +11,6 @@
export let mode: "static" | "dynamic";
export let value: null | FileData | string = null;
export let default_value: null | FileData | string = null;
export let style: string = "";
export let name: string;
export let source: "microphone" | "upload";
@ -22,8 +21,6 @@
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
let _value: null | FileData;
$: _value = normalise_file(value, root);

View File

@ -3,11 +3,8 @@
import { _ } from "svelte-i18n";
export let value: string;
export let default_value: string | undefined = undefined;
export let style: string = "";
export let variant: "primary" | "secondary" = "primary";
if (default_value) value = default_value;
</script>
<Button {variant} {style} on:click>

View File

@ -5,13 +5,10 @@
import type { LoadingStatus } from "../StatusTracker/types";
export let value: Array<[string, string]> = [];
export let default_value: Array<[string, string]>;
export let style: string = "";
export let color_map: Array<[string, string]>;
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
</script>
<Block padding={false}>

View File

@ -5,7 +5,6 @@
import type { LoadingStatus } from "../StatusTracker/types";
export let value: boolean = false;
export let default_value: boolean = false;
export let style: string = "";
export let label: string = "Checkbox";
export let mode: "static" | "dynamic";
@ -13,8 +12,6 @@
export let show_label: boolean;
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
</script>
<Block {form_position}>

View File

@ -5,7 +5,6 @@
import type { LoadingStatus } from "../StatusTracker/types";
export let value: Array<string> = [];
export let default_value: Array<string> = [];
export let choices: Array<string>;
export let mode: "static" | "dynamic";
@ -15,8 +14,6 @@
export let show_label: boolean;
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
</script>
<Block {form_position} type="fieldset">

View File

@ -1,17 +1,11 @@
<script lang="ts">
export let value: boolean = true;
export let default_value: boolean;
export let style: string = "";
export let variant: "default" | "panel" = "default";
export let parent: string | null = null;
if (default_value) value = default_value;
console.log(parent);
</script>
<div
{style}
class:hidden={!value}
class:bg-gray-50={variant === "panel"}
class:p-2={variant === "panel"}
class:rounded-lg={variant === "panel"}

View File

@ -9,15 +9,12 @@
export let headers: Headers = [];
export let value: Data | { data: Data; headers: Headers } = [["", "", ""]];
export let default_value: Array<Array<string | number>> = [["", "", ""]];
export let style: string = "";
export let mode: "static" | "dynamic";
export let col_count: [number, "fixed" | "dynamic"];
export let row_count: [number, "fixed" | "dynamic"];
export let parent: string | null = null;
if (default_value) value = default_value;
$: {
if (!Array.isArray(value)) {
if (Array.isArray(value.headers)) headers = value.headers;

View File

@ -6,7 +6,6 @@
export let label: string = "Dropdown";
export let value: string = "";
export let default_value: string = "";
export let style: string = "";
export let choices: Array<string>;
export let form_position: "first" | "last" | "mid" | "single" = "single";
@ -15,20 +14,10 @@
export let loading_status: LoadingStatus;
export let mode: "static" | "dynamic";
if (default_value) value = default_value;
</script>
<Block {form_position}>
<StatusTracker {...loading_status} />
<Dropdown
bind:value
{style}
{choices}
{label}
{show_label}
on:change
disabled={mode === "static"}
/>
<Dropdown bind:value {style} {choices} {label} {show_label} on:change />
</Block>

View File

@ -9,7 +9,6 @@
import { _ } from "svelte-i18n";
export let value: null | FileData = null;
export let default_value: null | FileData = null;
export let style: string = "";
export let mode: "static" | "dynamic";
export let root: string;
@ -18,8 +17,6 @@
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
let _value: null | FileData;
$: _value = normalise_file(value, root);

View File

@ -4,14 +4,11 @@
export let label: string;
export let value: string = "";
export let default_value: string;
export let style: string = "";
const dispatch = createEventDispatcher<{ change: undefined }>();
$: label, dispatch("change");
if (default_value) value = default_value;
</script>
<HTML {value} {style} on:change />

View File

@ -6,7 +6,6 @@
import type { LoadingStatus } from "../StatusTracker/types";
export let value: Array<[string, string | number]>;
export let default_value: Array<[string, string | number]>;
export let style: string = "";
export let show_legend: boolean;
export let color_map: Record<string, string> = {};
@ -16,8 +15,6 @@
const dispatch = createEventDispatcher<{ change: undefined }>();
if (default_value) value = default_value;
$: value, dispatch("change");
</script>

View File

@ -6,7 +6,6 @@
import { Component as StatusTracker } from "../StatusTracker/";
export let value: null | string = null;
export let default_value: null | string = null;
export let style: string = "";
export let source: "canvas" | "webcam" | "upload" = "upload";
export let tool: "editor" | "select" = "editor";
@ -19,8 +18,6 @@
const dispatch = createEventDispatcher<{ change: undefined }>();
if (default_value) value = default_value;
$: value, dispatch("change");
let dragging: boolean;

View File

@ -7,15 +7,12 @@
import type { LoadingStatus } from "../StatusTracker/types";
export let value: any = {};
export let default_value: any;
export let style: string = "";
export let loading_status: LoadingStatus;
const dispatch = createEventDispatcher<{ change: undefined }>();
$: value, dispatch("change");
if (default_value) value = default_value;
</script>
<Block test_id="json">

View File

@ -10,19 +10,12 @@
confidences?: Array<{ label: string; confidence: number }>;
};
export let default_value: {
label: string;
confidences?: Array<{ label: string; confidence: number }>;
};
export let style: string = "";
export let loading_status: LoadingStatus;
export let show_label: boolean;
const dispatch = createEventDispatcher<{ change: undefined }>();
if (default_value) value = default_value;
$: value, dispatch("change");
</script>

View File

@ -4,14 +4,11 @@
export let label: string;
export let value: string = "";
export let default_value: string;
export let style: string = "";
const dispatch = createEventDispatcher<{ change: undefined }>();
$: label, dispatch("change");
if (default_value) value = default_value;
</script>
<Markdown {value} {style} on:change />

View File

@ -9,7 +9,6 @@
import { _ } from "svelte-i18n";
export let value: null | FileData = null;
export let default_value: null | FileData = null;
export let style: string = "";
export let mode: "static" | "dynamic";
export let root: string;
@ -19,8 +18,6 @@
export let label: string;
export let show_label: boolean;
if (default_value) value = default_value;
let _value: null | FileData;
$: _value = normalise_file(value, root);

View File

@ -6,7 +6,6 @@
export let label: string = "Number";
export let value: number = 0;
export let default_value: number;
export let form_position: "first" | "last" | "mid" | "single" = "single";
export let show_label: boolean;
@ -15,8 +14,6 @@
export let style: string = "";
export let mode: "static" | "dynamic";
if (default_value) value = default_value;
</script>
<Block {form_position}>

View File

@ -2,12 +2,9 @@
import { Plot } from "@gradio/plot";
export let value: null | string = null;
export let default_value: null | string = null;
export let style: string = "";
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
</script>
<Plot {value} {style} on:change />

View File

@ -6,7 +6,6 @@
export let label: string = "Radio";
export let value: string = "";
export let default_value: string;
export let style: string = "";
export let choices: Array<string> = [];
export let mode: "static" | "dynamic";
@ -14,8 +13,6 @@
export let show_label: boolean;
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
</script>
<Block {form_position} type="fieldset">

View File

@ -1,15 +1,10 @@
<script lang="ts">
export let value: boolean;
export let default_value: boolean;
export let style: string = "";
export let parent: string | null = null;
if (default_value) value = default_value;
</script>
<div
{style}
class:hidden={!value}
class="flex flex-col md:flex-row gr-gap gr-form-gap row w-full flex-none"
class:flex-1={parent === "row"}
>

View File

@ -7,7 +7,6 @@
export let value: number = 0;
export let label: string = "Slider";
export let default_value: number;
export let style: string = "";
export let minimum: number;
@ -18,8 +17,6 @@
export let show_label: boolean;
export let loading_status: LoadingStatus;
if (default_value) value = default_value;
</script>
<Block {form_position}>

View File

@ -8,7 +8,6 @@
export let label: string = "Textbox";
export let value: string = "";
export let default_value: string | false = false;
export let style: string = "";
export let lines: number;
export let placeholder: string = "";
@ -19,8 +18,6 @@
export let loading_status: LoadingStatus;
export let mode: "static" | "dynamic";
if (default_value) value = default_value;
</script>
<Block {form_position}>

View File

@ -29,7 +29,6 @@
}
export let value: null | Data;
export let default_value: null | Data;
export let style: string = "";
export let y: Array<string>;
export let x: string;
@ -112,8 +111,6 @@
mode === "static" && value && format_value(value as StaticData);
$: value, dispatch("change");
if (default_value) value = default_value;
</script>
<Block

View File

@ -10,7 +10,6 @@
export let value: FileData | null | string = null;
export let label: string;
export let default_value: FileData | null;
export let style: string = "";
export let source: string;
export let root: string;
@ -19,8 +18,6 @@
export let mode: "static" | "dynamic";
if (default_value) value = default_value;
let _value: null | FileData;
$: _value = normalise_file(value, root);