mirror of
https://github.com/gradio-app/gradio.git
synced 2025-02-17 11:29:58 +08:00
Render decorator 2 (#8110)
* changes * add changeset * changes * changes * changes * changes * changes * changes * changeas * changes * add changeset * changes * add changeset * changes * changes * changes * changes * changes * changes * changes * changes * add changeset * changes * cganges * changes * changes * changes * changes * add changeset * changes * chagnes * changes * changes * changes * changes * remove console log * changes * changes * changes * changes * changes --------- Co-authored-by: Ali Abid <aliabid94@gmail.com> Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com> Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
This commit is contained in:
parent
be2b1e1261
commit
5436031f92
7
.changeset/rich-signs-bow.md
Normal file
7
.changeset/rich-signs-bow.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@gradio/app": minor
|
||||
"@gradio/client": minor
|
||||
"gradio": minor
|
||||
---
|
||||
|
||||
feat:Render decorator 2
|
@ -220,12 +220,13 @@ export interface FileData {
|
||||
|
||||
// Event and Listener Types
|
||||
|
||||
export type EventType = "data" | "status" | "log";
|
||||
export type EventType = "data" | "status" | "log" | "render";
|
||||
|
||||
export interface EventMap {
|
||||
data: Payload;
|
||||
status: Status;
|
||||
log: LogMessage;
|
||||
render: RenderMessage;
|
||||
}
|
||||
|
||||
export type Event<K extends EventType> = {
|
||||
@ -239,6 +240,13 @@ export interface LogMessage {
|
||||
log: string;
|
||||
level: "warning" | "info";
|
||||
}
|
||||
export interface RenderMessage {
|
||||
fn_index: number;
|
||||
data: {
|
||||
components: any[];
|
||||
layout: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Status {
|
||||
queue: boolean;
|
||||
|
@ -594,6 +594,14 @@ export function submit(
|
||||
endpoint: _endpoint,
|
||||
fn_index
|
||||
});
|
||||
if (data.render_config) {
|
||||
fire_event({
|
||||
type: "render",
|
||||
data: data.render_config,
|
||||
endpoint: _endpoint,
|
||||
fn_index
|
||||
});
|
||||
}
|
||||
|
||||
if (complete) {
|
||||
fire_event({
|
||||
|
1
demo/render_merge/run.ipynb
Normal file
1
demo/render_merge/run.ipynb
Normal file
@ -0,0 +1 @@
|
||||
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: render_merge"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " text_count = gr.Slider(1, 10, step=1, label=\"Textbox Count\")\n", "\n", " @gr.render(inputs=[text_count], triggers=[text_count.change])\n", " def render_count(count):\n", " for i in range(count):\n", " gr.Textbox(key=i)\n", "\n", " gr.Button(\"Merge\")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
|
14
demo/render_merge/run.py
Normal file
14
demo/render_merge/run.py
Normal file
@ -0,0 +1,14 @@
|
||||
import gradio as gr
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
text_count = gr.Slider(1, 10, step=1, label="Textbox Count")
|
||||
|
||||
@gr.render(inputs=[text_count], triggers=[text_count.change])
|
||||
def render_count(count):
|
||||
for i in range(count):
|
||||
gr.Textbox(key=i)
|
||||
|
||||
gr.Button("Merge")
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
1
demo/render_split/run.ipynb
Normal file
1
demo/render_split/run.ipynb
Normal file
@ -0,0 +1 @@
|
||||
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: render_split"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " input_text = gr.Textbox(label=\"input\")\n", " mode = gr.Radio([\"textbox\", \"button\"], value=\"textbox\")\n", "\n", " @gr.render(inputs=[input_text, mode], triggers=[input_text.submit])\n", " def show_split(text, mode):\n", " if len(text) == 0:\n", " gr.Markdown(\"## No Input Provided\")\n", " else:\n", " for letter in text:\n", " if mode == \"textbox\":\n", " gr.Textbox(letter)\n", " else:\n", " gr.Button(letter)\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
|
19
demo/render_split/run.py
Normal file
19
demo/render_split/run.py
Normal file
@ -0,0 +1,19 @@
|
||||
import gradio as gr
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
input_text = gr.Textbox(label="input")
|
||||
mode = gr.Radio(["textbox", "button"], value="textbox")
|
||||
|
||||
@gr.render(inputs=[input_text, mode], triggers=[input_text.submit])
|
||||
def show_split(text, mode):
|
||||
if len(text) == 0:
|
||||
gr.Markdown("## No Input Provided")
|
||||
else:
|
||||
for letter in text:
|
||||
if mode == "textbox":
|
||||
gr.Textbox(letter)
|
||||
else:
|
||||
gr.Button(letter)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
@ -81,6 +81,7 @@ from gradio.helpers import create_examples as Examples # noqa: N812
|
||||
from gradio.interface import Interface, TabbedInterface, close_all
|
||||
from gradio.layouts import Accordion, Column, Group, Row, Tab, TabItem, Tabs
|
||||
from gradio.oauth import OAuthProfile, OAuthToken
|
||||
from gradio.renderable import render
|
||||
from gradio.routes import Request, mount_gradio_app
|
||||
from gradio.templates import (
|
||||
Files,
|
||||
|
@ -30,6 +30,7 @@ class SimpleDropdown(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -46,6 +47,7 @@ class SimpleDropdown(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.choices = (
|
||||
[tuple(c) if isinstance(c, (tuple, list)) else (str(c), c) for c in choices]
|
||||
@ -65,6 +67,7 @@ class SimpleDropdown(FormComponent):
|
||||
elem_classes=elem_classes,
|
||||
value=value,
|
||||
render=render,
|
||||
key=key,
|
||||
)
|
||||
|
||||
def api_info(self) -> dict[str, Any]:
|
||||
|
@ -43,6 +43,7 @@ class SimpleImage(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -59,6 +60,7 @@ class SimpleImage(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.show_download_button = show_download_button
|
||||
super().__init__(
|
||||
@ -73,6 +75,7 @@ class SimpleImage(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -33,6 +33,7 @@ class SimpleTextbox(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -49,6 +50,7 @@ class SimpleTextbox(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.placeholder = placeholder
|
||||
self.rtl = rtl
|
||||
@ -64,6 +66,7 @@ class SimpleTextbox(FormComponent):
|
||||
elem_classes=elem_classes,
|
||||
value=value,
|
||||
render=render,
|
||||
key=key,
|
||||
)
|
||||
|
||||
def preprocess(self, payload: str | None) -> str | None:
|
||||
|
127
gradio/blocks.py
127
gradio/blocks.py
@ -39,7 +39,12 @@ from gradio import (
|
||||
wasm_utils,
|
||||
)
|
||||
from gradio.blocks_events import BlocksEvents, BlocksMeta
|
||||
from gradio.context import Context
|
||||
from gradio.context import (
|
||||
Context,
|
||||
get_blocks_context,
|
||||
get_render_context,
|
||||
set_render_context,
|
||||
)
|
||||
from gradio.data_classes import FileData, GradioModel, GradioRootModel
|
||||
from gradio.events import (
|
||||
EventData,
|
||||
@ -82,6 +87,7 @@ if TYPE_CHECKING: # Only import for type checking (is False at runtime).
|
||||
from fastapi.applications import FastAPI
|
||||
|
||||
from gradio.components.base import Component
|
||||
from gradio.renderable import Renderable
|
||||
|
||||
BUILT_IN_THEMES: dict[str, Theme] = {
|
||||
t.name: t
|
||||
@ -102,6 +108,7 @@ class Block:
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
visible: bool = True,
|
||||
proxy_url: str | None = None,
|
||||
):
|
||||
@ -120,7 +127,7 @@ class Block:
|
||||
self.state_session_capacity = 10000
|
||||
self.temp_files: set[str] = set()
|
||||
self.GRADIO_CACHE = get_upload_folder()
|
||||
self.key: int | str | None = None
|
||||
self.key = key
|
||||
# Keep tracks of files that should not be deleted when the delete_cache parmaeter is set
|
||||
# These files are the default value of the component and files that are used in examples
|
||||
self.keep_in_cache = set()
|
||||
@ -156,17 +163,19 @@ class Block:
|
||||
"""
|
||||
Adds self into appropriate BlockContext
|
||||
"""
|
||||
if Context.root_block is not None and self._id in Context.root_block.blocks:
|
||||
root_context = get_blocks_context()
|
||||
render_context = get_render_context()
|
||||
if root_context is not None and self._id in root_context.blocks:
|
||||
raise DuplicateBlockError(
|
||||
f"A block with id: {self._id} has already been rendered in the current Blocks."
|
||||
)
|
||||
if Context.block is not None:
|
||||
Context.block.add(self)
|
||||
if Context.root_block is not None:
|
||||
Context.root_block.blocks[self._id] = self
|
||||
if render_context is not None:
|
||||
render_context.add(self)
|
||||
if root_context is not None:
|
||||
root_context.blocks[self._id] = self
|
||||
self.is_rendered = True
|
||||
if isinstance(self, components.Component):
|
||||
Context.root_block.temp_file_sets.append(self.temp_files)
|
||||
root_context.root_block.temp_file_sets.append(self.temp_files)
|
||||
return self
|
||||
|
||||
def unrender(self):
|
||||
@ -174,14 +183,16 @@ class Block:
|
||||
Removes self from BlockContext if it has been rendered (otherwise does nothing).
|
||||
Removes self from the layout and collection of blocks, but does not delete any event triggers.
|
||||
"""
|
||||
if Context.block is not None:
|
||||
root_context = get_blocks_context()
|
||||
render_context = get_render_context()
|
||||
if render_context is not None:
|
||||
try:
|
||||
Context.block.children.remove(self)
|
||||
render_context.children.remove(self)
|
||||
except ValueError:
|
||||
pass
|
||||
if Context.root_block is not None:
|
||||
if root_context is not None:
|
||||
try:
|
||||
del Context.root_block.blocks[self._id]
|
||||
del root_context.blocks[self._id]
|
||||
self.is_rendered = False
|
||||
except KeyError:
|
||||
pass
|
||||
@ -404,8 +415,9 @@ class BlockContext(Block):
|
||||
self.children.append(child)
|
||||
|
||||
def __enter__(self):
|
||||
self.parent = Context.block
|
||||
Context.block = self
|
||||
render_context = get_render_context()
|
||||
self.parent = render_context
|
||||
set_render_context(self)
|
||||
return self
|
||||
|
||||
def add(self, child: Block):
|
||||
@ -413,6 +425,7 @@ class BlockContext(Block):
|
||||
self.children.append(child)
|
||||
|
||||
def fill_expected_parents(self):
|
||||
root_context = get_blocks_context()
|
||||
children = []
|
||||
pseudo_parent = None
|
||||
for child in self.children:
|
||||
@ -430,13 +443,13 @@ class BlockContext(Block):
|
||||
pseudo_parent.parent = self
|
||||
children.append(pseudo_parent)
|
||||
pseudo_parent.add_child(child)
|
||||
if Context.root_block:
|
||||
Context.root_block.blocks[pseudo_parent._id] = pseudo_parent
|
||||
if root_context:
|
||||
root_context.blocks[pseudo_parent._id] = pseudo_parent
|
||||
child.parent = pseudo_parent
|
||||
self.children = children
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None = None, *args):
|
||||
Context.block = self.parent
|
||||
set_render_context(self.parent)
|
||||
if exc_type is not None:
|
||||
return
|
||||
if getattr(self, "allow_expected_parents", True):
|
||||
@ -476,6 +489,7 @@ class BlockFunction:
|
||||
queue: bool | None = None,
|
||||
scroll_to_output: bool = False,
|
||||
show_api: bool = True,
|
||||
renderable: Renderable | None = None,
|
||||
):
|
||||
self.fn = fn
|
||||
self.inputs = inputs
|
||||
@ -511,6 +525,8 @@ class BlockFunction:
|
||||
or inspect.isasyncgenfunction(self.fn)
|
||||
or bool(self.every)
|
||||
)
|
||||
self.renderable = renderable
|
||||
|
||||
self.spaces_auto_wrap()
|
||||
|
||||
def spaces_auto_wrap(self):
|
||||
@ -619,10 +635,13 @@ class BlocksConfig:
|
||||
self.blocks: dict[int, Component | Block] = {}
|
||||
self.fns: list[BlockFunction] = []
|
||||
|
||||
def get_config(self):
|
||||
def get_config(self, renderable: Renderable | None = None):
|
||||
config = {}
|
||||
|
||||
def get_layout(block):
|
||||
rendered_ids = []
|
||||
|
||||
def get_layout(block: Block):
|
||||
rendered_ids.append(block._id)
|
||||
if not isinstance(block, BlockContext):
|
||||
return {"id": block._id}
|
||||
children_layout = []
|
||||
@ -630,10 +649,19 @@ class BlocksConfig:
|
||||
children_layout.append(get_layout(child))
|
||||
return {"id": block._id, "children": children_layout}
|
||||
|
||||
config["layout"] = get_layout(self.root_block)
|
||||
if renderable:
|
||||
root_block = self.blocks[renderable.column_id]
|
||||
else:
|
||||
root_block = self.root_block
|
||||
config["layout"] = get_layout(root_block)
|
||||
|
||||
config["components"] = []
|
||||
for _id, block in self.blocks.items():
|
||||
if renderable:
|
||||
if _id not in rendered_ids:
|
||||
continue
|
||||
if block.key:
|
||||
block.key = f"{renderable._id}-{block.key}"
|
||||
props = block.get_config() if hasattr(block, "get_config") else {}
|
||||
block_config = {
|
||||
"id": _id,
|
||||
@ -643,6 +671,8 @@ class BlocksConfig:
|
||||
"component_class_id": getattr(block, "component_class_id", None),
|
||||
"key": block.key,
|
||||
}
|
||||
if renderable:
|
||||
block_config["renderable"] = renderable._id
|
||||
if not block.skip_api:
|
||||
block_config["api_info"] = block.api_info() # type: ignore
|
||||
# .example_inputs() has been renamed .example_payload() but
|
||||
@ -761,6 +791,7 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
self.js = js_file.read()
|
||||
else:
|
||||
self.js = js
|
||||
self.renderables: list[Renderable] = []
|
||||
|
||||
# For analytics_enabled and allow_flagging: (1) first check for
|
||||
# parameter, (2) check for env variable, (3) default to True/"manual"
|
||||
@ -1009,7 +1040,7 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
first_dependency = dependency
|
||||
|
||||
# Allows some use of Interface-specific methods with loaded Spaces
|
||||
if first_dependency and Context.root_block:
|
||||
if first_dependency and get_blocks_context():
|
||||
blocks.predict = [fns[0]]
|
||||
blocks.input_components = first_dependency.inputs
|
||||
blocks.output_components = first_dependency.outputs
|
||||
@ -1108,6 +1139,7 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
concurrency_limit: int | None | Literal["default"] = "default",
|
||||
concurrency_id: str | None = None,
|
||||
show_api: bool = True,
|
||||
renderable: Renderable | None = None,
|
||||
) -> tuple[BlockFunction, int]:
|
||||
"""
|
||||
Adds an event to the component's dependencies.
|
||||
@ -1256,18 +1288,20 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
queue=queue,
|
||||
scroll_to_output=scroll_to_output,
|
||||
show_api=show_api,
|
||||
renderable=renderable,
|
||||
)
|
||||
|
||||
self.fns.append(block_fn)
|
||||
return block_fn, len(self.fns) - 1
|
||||
|
||||
def render(self):
|
||||
if Context.root_block is not None:
|
||||
if self._id in Context.root_block.blocks:
|
||||
root_context = get_blocks_context()
|
||||
if root_context is not None and Context.root_block is not None:
|
||||
if self._id in root_context.blocks:
|
||||
raise DuplicateBlockError(
|
||||
f"A block with id: {self._id} has already been rendered in the current Blocks."
|
||||
)
|
||||
overlapping_ids = set(Context.root_block.blocks).intersection(self.blocks)
|
||||
overlapping_ids = set(root_context.blocks).intersection(self.blocks)
|
||||
for id in overlapping_ids:
|
||||
# State components are allowed to be reused between Blocks
|
||||
if not isinstance(self.blocks[id], components.State):
|
||||
@ -1275,11 +1309,11 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
"At least one block in this Blocks has already been rendered."
|
||||
)
|
||||
|
||||
Context.root_block.blocks.update(self.blocks)
|
||||
dependency_offset = len(Context.root_block.fns)
|
||||
root_context.blocks.update(self.blocks)
|
||||
dependency_offset = len(root_context.fns)
|
||||
existing_api_names = [
|
||||
dep.api_name
|
||||
for dep in Context.root_block.fns
|
||||
for dep in root_context.fns
|
||||
if isinstance(dep.api_name, str)
|
||||
]
|
||||
for dependency in self.fns:
|
||||
@ -1299,16 +1333,16 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
# events in the backend
|
||||
if dependency.cancels:
|
||||
updated_cancels = [
|
||||
Context.root_block.fns[i].get_config()
|
||||
for i in dependency.cancels
|
||||
root_context.fns[i].get_config() for i in dependency.cancels
|
||||
]
|
||||
dependency.fn = get_cancel_function(updated_cancels)[0]
|
||||
Context.root_block.fns.append(dependency)
|
||||
root_context.fns.append(dependency)
|
||||
Context.root_block.temp_file_sets.extend(self.temp_file_sets)
|
||||
Context.root_block.proxy_urls.update(self.proxy_urls)
|
||||
|
||||
if Context.block is not None:
|
||||
Context.block.children.extend(self.children)
|
||||
render_context = get_render_context()
|
||||
if render_context is not None:
|
||||
render_context.children.extend(self.children)
|
||||
return self
|
||||
|
||||
def is_callable(self, fn_index: int = 0) -> bool:
|
||||
@ -1386,6 +1420,7 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
event_id: str | None = None,
|
||||
event_data: EventData | None = None,
|
||||
in_event_listener: bool = False,
|
||||
state: SessionState | None = None,
|
||||
):
|
||||
"""
|
||||
Calls function with given index and preprocessed input, and measures process time.
|
||||
@ -1410,6 +1445,7 @@ class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
event_id=event_id,
|
||||
in_event_listener=in_event_listener,
|
||||
request=request,
|
||||
state=state,
|
||||
)
|
||||
|
||||
if iterator is None: # If not a generator function that has already run
|
||||
@ -1825,6 +1861,7 @@ Received outputs:
|
||||
event_id,
|
||||
event_data,
|
||||
in_event_listener,
|
||||
state,
|
||||
)
|
||||
preds = result["prediction"]
|
||||
data = [
|
||||
@ -1852,6 +1889,7 @@ Received outputs:
|
||||
event_id,
|
||||
event_data,
|
||||
in_event_listener,
|
||||
state,
|
||||
)
|
||||
data = await self.postprocess_data(fn_index, result["prediction"], state)
|
||||
if root_path is not None:
|
||||
@ -1877,13 +1915,20 @@ Received outputs:
|
||||
|
||||
block_fn.total_runtime += result["duration"]
|
||||
block_fn.total_runs += 1
|
||||
return {
|
||||
output = {
|
||||
"data": data,
|
||||
"is_generating": is_generating,
|
||||
"iterator": iterator,
|
||||
"duration": result["duration"],
|
||||
"average_duration": block_fn.total_runtime / block_fn.total_runs,
|
||||
"render_config": None,
|
||||
}
|
||||
if block_fn.renderable and state:
|
||||
output["render_config"] = state.blocks_config.get_config(
|
||||
block_fn.renderable
|
||||
)
|
||||
|
||||
return output
|
||||
|
||||
def create_limiter(self):
|
||||
self.limiter = (
|
||||
@ -1947,20 +1992,21 @@ Received outputs:
|
||||
return config
|
||||
|
||||
def __enter__(self):
|
||||
if Context.block is None:
|
||||
render_context = get_render_context()
|
||||
if render_context is None:
|
||||
Context.root_block = self
|
||||
self.parent = Context.block
|
||||
Context.block = self
|
||||
self.parent = render_context
|
||||
set_render_context(self)
|
||||
self.exited = False
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type: type[BaseException] | None = None, *args):
|
||||
if exc_type is not None:
|
||||
Context.block = None
|
||||
set_render_context(None)
|
||||
Context.root_block = None
|
||||
return
|
||||
super().fill_expected_parents()
|
||||
Context.block = self.parent
|
||||
set_render_context(self.parent)
|
||||
# Configure the load events before root_block is reset
|
||||
self.attach_load_events()
|
||||
if self.parent is None:
|
||||
@ -2560,8 +2606,9 @@ Received outputs:
|
||||
|
||||
def attach_load_events(self):
|
||||
"""Add a load event for every component whose initial value should be randomized."""
|
||||
if Context.root_block:
|
||||
for component in Context.root_block.blocks.values():
|
||||
root_context = Context.root_block
|
||||
if root_context:
|
||||
for component in root_context.blocks.values():
|
||||
if (
|
||||
isinstance(component, components.Component)
|
||||
and component.load_event_to_attach
|
||||
|
@ -128,10 +128,10 @@ def create_or_modify_pyi(
|
||||
pyi_file.write_text(contents)
|
||||
|
||||
|
||||
def in_event_listener():
|
||||
def get_local_contexts():
|
||||
from gradio.context import LocalContext
|
||||
|
||||
return LocalContext.in_event_listener.get()
|
||||
return LocalContext.in_event_listener.get(), LocalContext.is_render.get()
|
||||
|
||||
|
||||
def updateable(fn):
|
||||
@ -153,7 +153,8 @@ def updateable(fn):
|
||||
arg_name = fn_args[i]
|
||||
kwargs[arg_name] = arg
|
||||
self._constructor_args.append(kwargs)
|
||||
if in_event_listener() and initialized_before:
|
||||
in_event_listener, is_render = get_local_contexts()
|
||||
if in_event_listener and initialized_before and not is_render:
|
||||
return None
|
||||
else:
|
||||
return fn(self, **kwargs)
|
||||
|
@ -66,6 +66,7 @@ class AnnotatedImage(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -85,6 +86,7 @@ class AnnotatedImage(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.format = format
|
||||
self.show_legend = show_legend
|
||||
@ -102,6 +104,7 @@ class AnnotatedImage(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -88,6 +88,7 @@ class Audio(
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
format: Literal["wav", "mp3"] = "wav",
|
||||
autoplay: bool = False,
|
||||
show_download_button: bool | None = None,
|
||||
@ -114,6 +115,7 @@ class Audio(
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
format: The file format to save audio files. Either 'wav' or 'mp3'. wav files are lossless but will tend to be larger files. mp3 files tend to be smaller. Default is wav. Applies both when this component is used as an input (when `type` is "format") and when this component is used as an output.
|
||||
autoplay: Whether to automatically play the audio when the component is used as an output. Note: browsers will not autoplay audio files if the user has not interacted with the page yet.
|
||||
show_download_button: If True, will show a download button in the corner of the component for saving audio. If False, icon does not appear. By default, it will be True for output components and False for input components.
|
||||
@ -179,6 +181,7 @@ class Audio(
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -67,6 +67,7 @@ class BarPlot(Plot):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
sort: Literal["x", "y", "-x", "-y"] | None = None,
|
||||
show_actions_button: bool = False,
|
||||
):
|
||||
@ -99,6 +100,7 @@ class BarPlot(Plot):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
sort: Specifies the sorting axis as either "x", "y", "-x" or "-y". If None, no sorting is applied.
|
||||
show_actions_button: Whether to show the actions button on the top right corner of the plot.
|
||||
"""
|
||||
@ -135,6 +137,7 @@ class BarPlot(Plot):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
every=every,
|
||||
)
|
||||
|
||||
|
@ -143,6 +143,7 @@ class Component(ComponentBase, Block):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
load_fn: Callable | None = None,
|
||||
every: float | None = None,
|
||||
):
|
||||
@ -170,6 +171,7 @@ class Component(ComponentBase, Block):
|
||||
elem_classes=elem_classes,
|
||||
visible=visible,
|
||||
render=render,
|
||||
key=key,
|
||||
)
|
||||
if isinstance(self, StreamingInput):
|
||||
self.check_streamable()
|
||||
|
@ -32,6 +32,7 @@ class Button(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
scale: int | None = None,
|
||||
min_width: int | None = None,
|
||||
):
|
||||
@ -48,6 +49,7 @@ class Button(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
scale: relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.
|
||||
min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.
|
||||
"""
|
||||
@ -57,6 +59,7 @@ class Button(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
interactive=interactive,
|
||||
scale=scale,
|
||||
|
@ -54,6 +54,7 @@ class Chatbot(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
height: int | str | None = None,
|
||||
latex_delimiters: list[dict[str, str | bool]] | None = None,
|
||||
rtl: bool = False,
|
||||
@ -81,6 +82,7 @@ class Chatbot(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
height: The height of the component, specified in pixels if a number is passed, or in CSS units if a string is passed.
|
||||
latex_delimiters: A list of dicts of the form {"left": open delimiter (str), "right": close delimiter (str), "display": whether to display in newline (bool)} that will be used to render LaTeX expressions. If not provided, `latex_delimiters` is set to `[{ "left": "$$", "right": "$$", "display": True }]`, so only expressions enclosed in $$ delimiters will be rendered as LaTeX, and in a new line. Pass in an empty list to disable LaTeX rendering. For more information, see the [KaTeX documentation](https://katex.org/docs/autorender.html).
|
||||
rtl: If True, sets the direction of the rendered text to right-to-left. Default is False, which renders text left-to-right.
|
||||
@ -123,6 +125,7 @@ class Chatbot(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
self.avatar_images: list[dict | None] = [None, None]
|
||||
|
@ -37,6 +37,7 @@ class Checkbox(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -53,6 +54,7 @@ class Checkbox(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
super().__init__(
|
||||
label=label,
|
||||
@ -67,6 +69,7 @@ class Checkbox(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -37,6 +37,7 @@ class CheckboxGroup(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -55,6 +56,7 @@ class CheckboxGroup(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.choices = (
|
||||
# Although we expect choices to be a list of tuples, it can be a list of tuples if the Gradio app
|
||||
@ -82,6 +84,7 @@ class CheckboxGroup(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -39,6 +39,7 @@ class ClearButton(Button):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
scale: int | None = None,
|
||||
min_width: int | None = None,
|
||||
api_name: str | None | Literal["False"] = None,
|
||||
@ -56,6 +57,7 @@ class ClearButton(Button):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
scale=scale,
|
||||
min_width=min_width,
|
||||
)
|
||||
|
@ -95,6 +95,7 @@ class Code(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -111,6 +112,7 @@ class Code(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
if language not in Code.languages:
|
||||
raise ValueError(f"Language {language} not supported.")
|
||||
@ -129,6 +131,7 @@ class Code(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -35,6 +35,7 @@ class ColorPicker(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -51,6 +52,7 @@ class ColorPicker(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
super().__init__(
|
||||
label=label,
|
||||
@ -65,6 +67,7 @@ class ColorPicker(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -89,6 +89,7 @@ class Dataframe(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
wrap: bool = False,
|
||||
line_breaks: bool = True,
|
||||
column_widths: list[str | int] | None = None,
|
||||
@ -114,6 +115,7 @@ class Dataframe(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
wrap: If True, the text in table cells will wrap when appropriate. If False and the `column_width` parameter is not set, the column widths will expand based on the cell contents and the table may need to be horizontally scrolled. If `column_width` is set, then any overflow text will be hidden.
|
||||
line_breaks: If True (default), will enable Github-flavored Markdown line breaks in chatbot messages. If False, single new lines will be ignored. Only applies for columns of type "markdown."
|
||||
column_widths: An optional list representing the width of each column. The elements of the list should be in the format "100px" (ints are also accepted and converted to pixel values) or "10%". If not provided, the column widths will be automatically determined based on the content of the cells. Setting this parameter will cause the browser to try to fit the table within the page width.
|
||||
@ -179,6 +181,7 @@ class Dataframe(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -36,6 +36,7 @@ class Dataset(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
container: bool = True,
|
||||
scale: int | None = None,
|
||||
min_width: int = 160,
|
||||
@ -53,6 +54,7 @@ class Dataset(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
container: If True, will place the component in a container - providing some extra padding around the border.
|
||||
scale: relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.
|
||||
min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.
|
||||
@ -63,6 +65,7 @@ class Dataset(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
)
|
||||
self.container = container
|
||||
self.scale = scale
|
||||
|
@ -40,6 +40,7 @@ class DownloadButton(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -56,6 +57,7 @@ class DownloadButton(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.data_model = FileData
|
||||
self.size = size
|
||||
@ -68,6 +70,7 @@ class DownloadButton(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
scale=scale,
|
||||
min_width=min_width,
|
||||
|
@ -50,6 +50,7 @@ class Dropdown(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -114,6 +115,7 @@ class Dropdown(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -33,6 +33,7 @@ class DuplicateButton(Button):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
scale: int | None = 0,
|
||||
min_width: int | None = None,
|
||||
_activate: bool = True,
|
||||
@ -50,6 +51,7 @@ class DuplicateButton(Button):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
scale: relative size compared to adjacent Components. For example if Components A and B are in a Row, and A has scale=2, and B has scale=1, A will be twice as wide as B. Should be an integer. scale applies in Rows, and to top-level Components in Blocks where fill_height=True.
|
||||
min_width: minimum pixel width, will wrap if not sufficient screen space to satisfy this value. If a certain scale value results in this Component being narrower than min_width, the min_width parameter will be respected first.
|
||||
"""
|
||||
@ -65,6 +67,7 @@ class DuplicateButton(Button):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
scale=scale,
|
||||
min_width=min_width,
|
||||
)
|
||||
|
@ -47,6 +47,7 @@ class File(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -66,6 +67,7 @@ class File(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.file_count = file_count
|
||||
if self.file_count in ["multiple", "directory"]:
|
||||
@ -101,6 +103,7 @@ class File(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
self.type = type
|
||||
|
@ -50,6 +50,7 @@ class FileExplorer(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
root: None = None,
|
||||
):
|
||||
"""
|
||||
@ -71,6 +72,7 @@ class FileExplorer(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
if root is not None:
|
||||
warnings.warn(
|
||||
@ -101,6 +103,7 @@ class FileExplorer(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -61,6 +61,7 @@ class Gallery(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
columns: int | tuple | None = 2,
|
||||
rows: int | tuple | None = None,
|
||||
height: int | float | None = None,
|
||||
@ -89,6 +90,7 @@ class Gallery(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
columns: Represents the number of images that should be shown in one row, for each of the six standard screen sizes (<576px, <768px, <992px, <1200px, <1400px, >1400px). If fewer than 6 are given then the last will be used for all subsequent breakpoints
|
||||
rows: Represents the number of rows in the image grid, for each of the six standard screen sizes (<576px, <768px, <992px, <1200px, <1400px, >1400px). If fewer than 6 are given then the last will be used for all subsequent breakpoints
|
||||
height: The height of the gallery component, specified in pixels if a number is passed, or in CSS units if a string is passed. If more images are displayed than can fit in the height, a scrollbar will appear.
|
||||
@ -132,6 +134,7 @@ class Gallery(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
interactive=interactive,
|
||||
)
|
||||
|
@ -51,6 +51,7 @@ class HighlightedText(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
interactive: bool | None = None,
|
||||
):
|
||||
"""
|
||||
@ -70,6 +71,7 @@ class HighlightedText(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
interactive: If True, the component will be editable, and allow user to select spans of text and label them.
|
||||
"""
|
||||
self.color_map = color_map
|
||||
@ -87,6 +89,7 @@ class HighlightedText(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
interactive=interactive,
|
||||
)
|
||||
|
@ -32,6 +32,7 @@ class HTML(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -43,6 +44,7 @@ class HTML(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
super().__init__(
|
||||
label=label,
|
||||
@ -52,6 +54,7 @@ class HTML(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -64,6 +64,7 @@ class Image(StreamingInput, Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
mirror_webcam: bool = True,
|
||||
show_share_button: bool | None = None,
|
||||
):
|
||||
@ -89,6 +90,7 @@ class Image(StreamingInput, Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
mirror_webcam: If True webcam will be mirrored. Default is True.
|
||||
show_share_button: If True, will show a share icon in the corner of the component that allows user to share outputs to Hugging Face Spaces Discussions. If False, icon does not appear. If set to None (default behavior), then the icon appears if this Gradio app is launched on Spaces, but not otherwise.
|
||||
"""
|
||||
@ -140,6 +142,7 @@ class Image(StreamingInput, Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -151,6 +151,7 @@ class ImageEditor(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
mirror_webcam: bool = True,
|
||||
show_share_button: bool | None = None,
|
||||
_selectable: bool = False,
|
||||
@ -182,6 +183,7 @@ class ImageEditor(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
mirror_webcam: If True webcam will be mirrored. Default is True.
|
||||
show_share_button: If True, will show a share icon in the corner of the component that allows user to share outputs to Hugging Face Spaces Discussions. If False, icon does not appear. If set to None (default behavior), then the icon appears if this Gradio app is launched on Spaces, but not otherwise.
|
||||
crop_size: The size of the crop box in pixels. If a tuple, the first value is the width and the second value is the height. If a string, the value must be a ratio in the form `width:height` (e.g. "16:9").
|
||||
@ -245,6 +247,7 @@ class ImageEditor(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -36,6 +36,7 @@ class JSON(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -50,6 +51,7 @@ class JSON(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
super().__init__(
|
||||
label=label,
|
||||
@ -62,6 +64,7 @@ class JSON(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -52,6 +52,7 @@ class Label(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
color: str | None = None,
|
||||
):
|
||||
"""
|
||||
@ -68,6 +69,7 @@ class Label(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
color: The background color of the label (either a valid css color name or hexadecimal string).
|
||||
"""
|
||||
self.num_top_classes = num_top_classes
|
||||
@ -83,6 +85,7 @@ class Label(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -80,6 +80,7 @@ class LinePlot(Plot):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
show_actions_button: bool = False,
|
||||
):
|
||||
"""
|
||||
@ -113,6 +114,7 @@ class LinePlot(Plot):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
show_actions_button: Whether to show the actions button on the top right corner of the plot.
|
||||
"""
|
||||
self.x = x
|
||||
@ -148,6 +150,7 @@ class LinePlot(Plot):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
every=every,
|
||||
)
|
||||
|
||||
|
@ -38,6 +38,7 @@ class LoginButton(Button):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
scale: int | None = 0,
|
||||
min_width: int | None = None,
|
||||
signed_in_value: str = "Signed in as {}",
|
||||
@ -63,6 +64,7 @@ class LoginButton(Button):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
scale=scale,
|
||||
min_width=min_width,
|
||||
)
|
||||
|
@ -37,6 +37,7 @@ class LogoutButton(Button):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
scale: int | None = 0,
|
||||
min_width: int | None = None,
|
||||
):
|
||||
@ -55,6 +56,7 @@ class LogoutButton(Button):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
scale=scale,
|
||||
min_width=min_width,
|
||||
)
|
||||
|
@ -36,6 +36,7 @@ class Markdown(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
sanitize_html: bool = True,
|
||||
line_breaks: bool = False,
|
||||
header_links: bool = False,
|
||||
@ -52,6 +53,7 @@ class Markdown(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
sanitize_html: If False, will disable HTML sanitization when converted from markdown. This is not recommended, as it can lead to security vulnerabilities.
|
||||
line_breaks: If True, will enable Github-flavored Markdown line breaks in chatbot messages. If False (default), single new lines will be ignored.
|
||||
header_links: If True, will automatically create anchors for headings, displaying a link icon on hover.
|
||||
@ -72,6 +74,7 @@ class Markdown(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -51,6 +51,7 @@ class Model3D(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -71,6 +72,7 @@ class Model3D(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.clear_color = clear_color or [0, 0, 0, 0]
|
||||
self.camera_position = camera_position
|
||||
@ -89,6 +91,7 @@ class Model3D(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -72,6 +72,7 @@ class MultimodalTextbox(FormComponent):
|
||||
autoscroll: bool = True,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
text_align: Literal["left", "right"] | None = None,
|
||||
rtl: bool = False,
|
||||
submit_btn: str | Literal[False] | None = None,
|
||||
@ -96,6 +97,7 @@ class MultimodalTextbox(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
text_align: How to align the text in the textbox, can be: "left", "right", or None (default). If None, the alignment is left if `rtl` is False, or right if `rtl` is True. Can only be changed if `type` is "text".
|
||||
rtl: If True and `type` is "text", sets the direction of the text to right-to-left (cursor appears on the left of the text). Default is False, which renders cursor on the right.
|
||||
autoscroll: If True, will automatically scroll to the bottom of the textbox when the value changes, unless the user scrolls up. If False, will not scroll to the bottom of the textbox when the value changes.
|
||||
@ -128,6 +130,7 @@ class MultimodalTextbox(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
self.rtl = rtl
|
||||
|
@ -37,6 +37,7 @@ class Number(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
precision: int | None = None,
|
||||
minimum: float | None = None,
|
||||
maximum: float | None = None,
|
||||
@ -57,6 +58,7 @@ class Number(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
precision: Precision to round input/output to. If set to 0, will round to nearest integer and convert type to int. If None, no rounding happens.
|
||||
minimum: Minimum value. Only applied when component is used as an input. If a user provides a smaller value, a gr.Error exception is raised by the backend.
|
||||
maximum: Maximum value. Only applied when component is used as an input. If a user provides a larger value, a gr.Error exception is raised by the backend.
|
||||
@ -80,6 +82,7 @@ class Number(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -35,6 +35,7 @@ class ParamViewer(Component):
|
||||
linkify: list[str] | None = None,
|
||||
every: float | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -43,6 +44,7 @@ class ParamViewer(Component):
|
||||
linkify: A list of strings to linkify. If any of these strings is found in the description, it will be rendered as a link.
|
||||
every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.value = value or {}
|
||||
self.language = language
|
||||
@ -51,6 +53,7 @@ class ParamViewer(Component):
|
||||
every=every,
|
||||
value=value,
|
||||
render=render,
|
||||
key=key,
|
||||
)
|
||||
|
||||
def preprocess(self, payload: dict[str, Parameter]) -> dict[str, Parameter]:
|
||||
|
@ -52,6 +52,7 @@ class Plot(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -67,6 +68,7 @@ class Plot(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.format = format
|
||||
super().__init__(
|
||||
@ -80,6 +82,7 @@ class Plot(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -38,6 +38,7 @@ class Radio(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
@ -56,6 +57,7 @@ class Radio(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
"""
|
||||
self.choices = (
|
||||
# Although we expect choices to be a list of tuples, it can be a list of tuples if the Gradio app
|
||||
@ -83,6 +85,7 @@ class Radio(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -93,6 +93,7 @@ class ScatterPlot(Plot):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
show_actions_button: bool = False,
|
||||
):
|
||||
"""
|
||||
@ -128,6 +129,7 @@ class ScatterPlot(Plot):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
show_actions_button: Whether to show the actions button on the top right corner of the plot.
|
||||
"""
|
||||
self.x = x
|
||||
@ -166,6 +168,7 @@ class ScatterPlot(Plot):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
)
|
||||
|
||||
def get_block_name(self) -> str:
|
||||
|
@ -42,6 +42,7 @@ class Slider(FormComponent):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
randomize: bool = False,
|
||||
):
|
||||
"""
|
||||
@ -62,6 +63,7 @@ class Slider(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
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
|
||||
@ -87,6 +89,7 @@ class Slider(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -49,6 +49,7 @@ class Textbox(FormComponent):
|
||||
autoscroll: bool = True,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
type: Literal["text", "password", "email"] = "text",
|
||||
text_align: Literal["left", "right"] | None = None,
|
||||
rtl: bool = False,
|
||||
@ -73,6 +74,7 @@ class Textbox(FormComponent):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
type: The type of textbox. One of: 'text', 'password', 'email', Default is 'text'.
|
||||
text_align: How to align the text in the textbox, can be: "left", "right", or None (default). If None, the alignment is left if `rtl` is False, or right if `rtl` is True. Can only be changed if `type` is "text".
|
||||
rtl: If True and `type` is "text", sets the direction of the text to right-to-left (cursor appears on the left of the text). Default is False, which renders cursor on the right.
|
||||
@ -104,6 +106,7 @@ class Textbox(FormComponent):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
self.type = type
|
||||
|
@ -44,6 +44,7 @@ class UploadButton(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
type: Literal["filepath", "bytes"] = "filepath",
|
||||
file_count: Literal["single", "multiple", "directory"] = "single",
|
||||
file_types: list[str] | None = None,
|
||||
@ -63,6 +64,7 @@ class UploadButton(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
type: Type of value to be returned by component. "file" returns a temporary file object with the same base name as the uploaded file, whose full path can be retrieved by file_obj.name, "binary" returns an bytes object.
|
||||
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".
|
||||
file_types: List of type of files to be uploaded. "file" allows any file to be uploaded, "image" allows only image files to be uploaded, "audio" allows only audio files to be uploaded, "video" allows only video files to be uploaded, "text" allows only text files to be uploaded.
|
||||
@ -100,6 +102,7 @@ class UploadButton(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
scale=scale,
|
||||
min_width=min_width,
|
||||
|
@ -76,6 +76,7 @@ class Video(Component):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
mirror_webcam: bool = True,
|
||||
include_audio: bool | None = None,
|
||||
autoplay: bool = False,
|
||||
@ -102,6 +103,7 @@ class Video(Component):
|
||||
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.
|
||||
elem_classes: An optional list of strings that are assigned as the classes of this component in the HTML DOM. Can be used for targeting CSS styles.
|
||||
render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later.
|
||||
key: if assigned, will be used to assume identity across a re-render. Components that have the same key across a re-render will have their value preserved.
|
||||
mirror_webcam: If True webcam will be mirrored. Default is True.
|
||||
include_audio: Whether the component should record/retain the audio track for a video. By default, audio is excluded for webcam videos and included for uploaded videos.
|
||||
autoplay: Whether to automatically play the video when the component is used as an output. Note: browsers will not autoplay video files if the user has not interacted with the page yet.
|
||||
@ -154,6 +156,7 @@ class Video(Component):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
value=value,
|
||||
)
|
||||
|
||||
|
@ -6,7 +6,7 @@ from contextvars import ContextVar
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING: # Only import for type checking (is False at runtime).
|
||||
from gradio.blocks import BlockContext, Blocks
|
||||
from gradio.blocks import BlockContext, Blocks, BlocksConfig
|
||||
from gradio.helpers import Progress
|
||||
from gradio.routes import Request
|
||||
|
||||
@ -21,7 +21,35 @@ class Context:
|
||||
|
||||
class LocalContext:
|
||||
blocks: ContextVar[Blocks | None] = ContextVar("blocks", default=None)
|
||||
blocks_config: ContextVar[BlocksConfig | None] = ContextVar(
|
||||
"blocks_config", default=None
|
||||
)
|
||||
is_render: ContextVar[bool] = ContextVar("is_render", default=False)
|
||||
render_block: ContextVar[BlockContext | None] = ContextVar(
|
||||
"render_block", default=None
|
||||
)
|
||||
in_event_listener: ContextVar[bool] = ContextVar("in_event_listener", default=False)
|
||||
event_id: ContextVar[str | None] = ContextVar("event_id", default=None)
|
||||
request: ContextVar[Request | None] = ContextVar("request", default=None)
|
||||
progress: ContextVar[Progress | None] = ContextVar("progress", default=None)
|
||||
|
||||
|
||||
def get_render_context() -> BlockContext | None:
|
||||
if LocalContext.is_render.get():
|
||||
return LocalContext.render_block.get()
|
||||
else:
|
||||
return Context.block
|
||||
|
||||
|
||||
def set_render_context(block: BlockContext | None):
|
||||
if LocalContext.is_render.get():
|
||||
LocalContext.render_block.set(block)
|
||||
else:
|
||||
Context.block = block
|
||||
|
||||
|
||||
def get_blocks_context() -> BlocksConfig | None:
|
||||
if LocalContext.is_render.get():
|
||||
return LocalContext.blocks_config.get()
|
||||
elif Context.root_block:
|
||||
return Context.root_block.default_config
|
||||
|
79
gradio/renderable.py
Normal file
79
gradio/renderable.py
Normal file
@ -0,0 +1,79 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable, Literal, Sequence
|
||||
|
||||
from gradio.components import Component
|
||||
from gradio.context import Context, LocalContext
|
||||
from gradio.events import EventListener, EventListenerMethod
|
||||
from gradio.layouts import Column
|
||||
|
||||
|
||||
class Renderable:
|
||||
def __init__(
|
||||
self,
|
||||
fn: Callable,
|
||||
inputs: list[Component] | Component | None = None,
|
||||
triggers: EventListener | Sequence[EventListener] | None = None,
|
||||
concurrency_limit: int | None | Literal["default"] = "default",
|
||||
concurrency_id: str | None = None,
|
||||
):
|
||||
if Context.root_block is None:
|
||||
raise ValueError("Reactive render must be inside a Blocks context.")
|
||||
|
||||
self._id = len(Context.root_block.renderables)
|
||||
Context.root_block.renderables.append(self)
|
||||
self.column = Column()
|
||||
self.column_id = Column()._id
|
||||
|
||||
self.fn = fn
|
||||
self.inputs = [inputs] if isinstance(inputs, Component) else inputs
|
||||
self.triggers: list[EventListenerMethod] = []
|
||||
if isinstance(triggers, EventListener):
|
||||
triggers = [triggers]
|
||||
|
||||
if triggers:
|
||||
self.triggers = [
|
||||
EventListenerMethod(
|
||||
getattr(t, "__self__", None) if t.has_trigger else None,
|
||||
t.event_name,
|
||||
)
|
||||
for t in triggers
|
||||
]
|
||||
Context.root_block.set_event_trigger(
|
||||
self.triggers,
|
||||
self.apply,
|
||||
self.inputs,
|
||||
None,
|
||||
show_api=False,
|
||||
concurrency_limit=concurrency_limit,
|
||||
concurrency_id=concurrency_id,
|
||||
renderable=self,
|
||||
)
|
||||
|
||||
def apply(self, *args, **kwargs):
|
||||
column_copy = Column(render=False)
|
||||
column_copy._id = self.column_id
|
||||
LocalContext.is_render.set(True)
|
||||
LocalContext.render_block.set(column_copy)
|
||||
try:
|
||||
self.fn(*args, **kwargs)
|
||||
blocks_config = LocalContext.blocks_config.get()
|
||||
if blocks_config is None:
|
||||
raise ValueError("Reactive render must be inside a LocalContext.")
|
||||
blocks_config.blocks[self.column_id] = column_copy
|
||||
finally:
|
||||
LocalContext.is_render.set(False)
|
||||
LocalContext.render_block.set(None)
|
||||
|
||||
|
||||
def render(
|
||||
inputs: list[Component] | None = None,
|
||||
triggers: list[EventListener] | None = None,
|
||||
concurrency_limit: int | None | Literal["default"] = None,
|
||||
concurrency_id: str | None = None,
|
||||
):
|
||||
def wrapper_function(fn):
|
||||
Renderable(fn, inputs, triggers, concurrency_limit, concurrency_id)
|
||||
return fn
|
||||
|
||||
return wrapper_function
|
@ -39,6 +39,7 @@ class TextArea(components.Textbox):
|
||||
autoscroll: bool = True,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
type: Literal["text", "password", "email"] = "text",
|
||||
text_align: Literal["left", "right"] | None = None,
|
||||
rtl: bool = False,
|
||||
@ -63,6 +64,7 @@ class TextArea(components.Textbox):
|
||||
autoscroll=autoscroll,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
type=type,
|
||||
text_align=text_align,
|
||||
rtl=rtl,
|
||||
@ -100,6 +102,7 @@ class Sketchpad(components.ImageEditor):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
mirror_webcam: bool = True,
|
||||
show_share_button: bool | None = None,
|
||||
_selectable: bool = False,
|
||||
@ -132,6 +135,7 @@ class Sketchpad(components.ImageEditor):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
mirror_webcam=mirror_webcam,
|
||||
show_share_button=show_share_button,
|
||||
_selectable=_selectable,
|
||||
@ -175,6 +179,7 @@ class Paint(components.ImageEditor):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
mirror_webcam: bool = True,
|
||||
show_share_button: bool | None = None,
|
||||
_selectable: bool = False,
|
||||
@ -205,6 +210,7 @@ class Paint(components.ImageEditor):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
mirror_webcam=mirror_webcam,
|
||||
show_share_button=show_share_button,
|
||||
_selectable=_selectable,
|
||||
@ -252,6 +258,7 @@ class ImageMask(components.ImageEditor):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
mirror_webcam: bool = True,
|
||||
show_share_button: bool | None = None,
|
||||
_selectable: bool = False,
|
||||
@ -284,6 +291,7 @@ class ImageMask(components.ImageEditor):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
mirror_webcam=mirror_webcam,
|
||||
show_share_button=show_share_button,
|
||||
_selectable=_selectable,
|
||||
@ -325,6 +333,7 @@ class PlayableVideo(components.Video):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
mirror_webcam: bool = True,
|
||||
include_audio: bool | None = None,
|
||||
autoplay: bool = False,
|
||||
@ -351,6 +360,7 @@ class PlayableVideo(components.Video):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
mirror_webcam=mirror_webcam,
|
||||
include_audio=include_audio,
|
||||
autoplay=autoplay,
|
||||
@ -386,6 +396,7 @@ class Microphone(components.Audio):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
format: Literal["wav", "mp3"] = "wav",
|
||||
autoplay: bool = False,
|
||||
show_download_button: bool | None = None,
|
||||
@ -412,6 +423,7 @@ class Microphone(components.Audio):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
format=format,
|
||||
autoplay=autoplay,
|
||||
show_download_button=show_download_button,
|
||||
@ -449,6 +461,7 @@ class Files(components.File):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
):
|
||||
super().__init__(
|
||||
value,
|
||||
@ -467,6 +480,7 @@ class Files(components.File):
|
||||
elem_id=elem_id,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
)
|
||||
|
||||
|
||||
@ -498,6 +512,7 @@ class Numpy(components.Dataframe):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
wrap: bool = False,
|
||||
line_breaks: bool = True,
|
||||
column_widths: list[str | int] | None = None,
|
||||
@ -517,6 +532,7 @@ class Numpy(components.Dataframe):
|
||||
wrap=wrap,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
line_breaks=line_breaks,
|
||||
column_widths=column_widths,
|
||||
every=every,
|
||||
@ -555,6 +571,7 @@ class Matrix(components.Dataframe):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
wrap: bool = False,
|
||||
line_breaks: bool = True,
|
||||
column_widths: list[str | int] | None = None,
|
||||
@ -574,6 +591,7 @@ class Matrix(components.Dataframe):
|
||||
wrap=wrap,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
line_breaks=line_breaks,
|
||||
column_widths=column_widths,
|
||||
every=every,
|
||||
@ -612,6 +630,7 @@ class List(components.Dataframe):
|
||||
elem_id: str | None = None,
|
||||
elem_classes: list[str] | str | None = None,
|
||||
render: bool = True,
|
||||
key: int | str | None = None,
|
||||
wrap: bool = False,
|
||||
line_breaks: bool = True,
|
||||
column_widths: list[str | int] | None = None,
|
||||
@ -631,6 +650,7 @@ class List(components.Dataframe):
|
||||
wrap=wrap,
|
||||
elem_classes=elem_classes,
|
||||
render=render,
|
||||
key=key,
|
||||
line_breaks=line_breaks,
|
||||
column_widths=column_widths,
|
||||
every=every,
|
||||
|
@ -58,6 +58,7 @@ if TYPE_CHECKING: # Only import for type checking (is False at runtime).
|
||||
from gradio.blocks import BlockContext, Blocks
|
||||
from gradio.components import Component
|
||||
from gradio.routes import App, Request
|
||||
from gradio.state_holder import SessionState
|
||||
|
||||
JSON_PATH = os.path.join(os.path.dirname(gradio.__file__), "launches.json")
|
||||
|
||||
@ -816,6 +817,7 @@ def get_function_with_locals(
|
||||
event_id: str | None,
|
||||
in_event_listener: bool,
|
||||
request: Request | None,
|
||||
state: SessionState | None,
|
||||
):
|
||||
def before_fn(blocks, event_id):
|
||||
from gradio.context import LocalContext
|
||||
@ -824,12 +826,15 @@ def get_function_with_locals(
|
||||
LocalContext.in_event_listener.set(in_event_listener)
|
||||
LocalContext.event_id.set(event_id)
|
||||
LocalContext.request.set(request)
|
||||
if state:
|
||||
LocalContext.blocks_config.set(state.blocks_config)
|
||||
|
||||
def after_fn():
|
||||
from gradio.context import LocalContext
|
||||
|
||||
LocalContext.in_event_listener.set(False)
|
||||
LocalContext.request.set(None)
|
||||
LocalContext.blocks_config.set(None)
|
||||
|
||||
return function_wrapper(
|
||||
fn,
|
||||
|
@ -17,11 +17,7 @@
|
||||
|
||||
import logo from "./images/logo.svg";
|
||||
import api_logo from "./api_docs/img/api-logo.svg";
|
||||
import {
|
||||
create_components,
|
||||
AsyncFunction,
|
||||
restore_keyed_values
|
||||
} from "./init";
|
||||
import { create_components, AsyncFunction } from "./init";
|
||||
|
||||
setupi18n();
|
||||
|
||||
@ -53,7 +49,8 @@
|
||||
get_data,
|
||||
loading_status,
|
||||
scheduled_updates,
|
||||
create_layout
|
||||
create_layout,
|
||||
rerender_layout
|
||||
} = create_components();
|
||||
|
||||
$: create_layout({
|
||||
@ -64,8 +61,7 @@
|
||||
app,
|
||||
options: {
|
||||
fill_height
|
||||
},
|
||||
callback: () => restore_keyed_values(old_components, components)
|
||||
}
|
||||
});
|
||||
|
||||
$: {
|
||||
@ -303,6 +299,16 @@
|
||||
handle_update(data, fn_index);
|
||||
set_status($loading_status);
|
||||
})
|
||||
.on("render", ({ data, fn_index }) => {
|
||||
let _components: ComponentMeta[] = data.components;
|
||||
let render_layout: LayoutNode = data.layout;
|
||||
|
||||
rerender_layout({
|
||||
components: _components,
|
||||
layout: render_layout,
|
||||
root: root
|
||||
});
|
||||
})
|
||||
.on("status", ({ fn_index, ...status }) => {
|
||||
//@ts-ignore
|
||||
loading_status.update({
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { writable, type Writable } from "svelte/store";
|
||||
import { writable, type Writable, get } from "svelte/store";
|
||||
import type {
|
||||
ComponentMeta,
|
||||
Dependency,
|
||||
@ -9,6 +9,7 @@ import type {
|
||||
import { load_component } from "virtual:component-loader";
|
||||
import type { client_return } from "@gradio/client";
|
||||
import { create_loading_status_store } from "./stores";
|
||||
import { _ } from "svelte-i18n";
|
||||
|
||||
export interface UpdateTransaction {
|
||||
id: number;
|
||||
@ -40,6 +41,11 @@ export function create_components(): {
|
||||
};
|
||||
callback?: () => void;
|
||||
}) => void;
|
||||
rerender_layout: (args: {
|
||||
components: ComponentMeta[];
|
||||
layout: LayoutNode;
|
||||
root: string;
|
||||
}) => void;
|
||||
} {
|
||||
let _component_map: Map<number, ComponentMeta>;
|
||||
|
||||
@ -53,8 +59,9 @@ export function create_components(): {
|
||||
create_loading_status_store();
|
||||
const layout_store: Writable<ComponentMeta> = writable();
|
||||
let root: string;
|
||||
let _components: ComponentMeta[];
|
||||
let _components: ComponentMeta[] = [];
|
||||
let app: client_return;
|
||||
let keyed_component_values: Record<string | number, any> = {};
|
||||
|
||||
function create_layout({
|
||||
app: _app,
|
||||
@ -76,6 +83,8 @@ export function create_components(): {
|
||||
callback?: () => void;
|
||||
}): void {
|
||||
app = _app;
|
||||
store_keyed_values(_components);
|
||||
|
||||
_components = components;
|
||||
inputs = new Set();
|
||||
outputs = new Set();
|
||||
@ -130,15 +139,62 @@ export function create_components(): {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Rerender the layout when the config has been modified to attach new components
|
||||
*/
|
||||
function rerender_layout({
|
||||
components,
|
||||
layout,
|
||||
root
|
||||
}: {
|
||||
components: ComponentMeta[];
|
||||
layout: LayoutNode;
|
||||
root: string;
|
||||
}): void {
|
||||
target_map.set(_target_map);
|
||||
|
||||
let _constructor_map = preload_all_components(components, root);
|
||||
_constructor_map.forEach((v, k) => {
|
||||
constructor_map.set(k, v);
|
||||
});
|
||||
|
||||
let current_element = instance_map[layout.id];
|
||||
let all_current_children: ComponentMeta[] = [];
|
||||
const add_to_current_children = (component: ComponentMeta): void => {
|
||||
all_current_children.push(component);
|
||||
if (component.children) {
|
||||
component.children.forEach((child) => {
|
||||
add_to_current_children(child);
|
||||
});
|
||||
}
|
||||
};
|
||||
add_to_current_children(current_element);
|
||||
store_keyed_values(all_current_children);
|
||||
|
||||
components.forEach((c) => {
|
||||
instance_map[c.id] = c;
|
||||
_component_map.set(c.id, c);
|
||||
});
|
||||
if (current_element.parent) {
|
||||
current_element.parent.children![
|
||||
current_element.parent.children!.indexOf(current_element)
|
||||
] = instance_map[layout.id];
|
||||
}
|
||||
|
||||
walk_layout(layout, root, current_element.parent);
|
||||
}
|
||||
|
||||
async function walk_layout(
|
||||
node: LayoutNode,
|
||||
root: string
|
||||
root: string,
|
||||
parent?: ComponentMeta
|
||||
): Promise<ComponentMeta> {
|
||||
const instance = instance_map[node.id];
|
||||
|
||||
instance.component = (await constructor_map.get(
|
||||
instance.component_class_id
|
||||
))!?.default;
|
||||
instance.parent = parent;
|
||||
|
||||
if (instance.type === "dataset") {
|
||||
instance.props.component_map = get_component(
|
||||
@ -168,11 +224,18 @@ export function create_components(): {
|
||||
app
|
||||
);
|
||||
|
||||
if (
|
||||
instance.key != null &&
|
||||
keyed_component_values[instance.key] !== undefined
|
||||
) {
|
||||
instance.props.value = keyed_component_values[instance.key];
|
||||
}
|
||||
|
||||
_component_map.set(instance.id, instance);
|
||||
|
||||
if (node.children) {
|
||||
instance.children = await Promise.all(
|
||||
node.children.map((v) => walk_layout(v, root))
|
||||
node.children.map((v) => walk_layout(v, root, instance))
|
||||
);
|
||||
}
|
||||
|
||||
@ -182,6 +245,14 @@ export function create_components(): {
|
||||
let update_scheduled = false;
|
||||
let update_scheduled_store = writable(false);
|
||||
|
||||
function store_keyed_values(components: ComponentMeta[]): void {
|
||||
components.forEach((c) => {
|
||||
if (c.key != null) {
|
||||
keyed_component_values[c.key] = c.props.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function flush(): void {
|
||||
layout_store.update((layout) => {
|
||||
for (let i = 0; i < pending_updates.length; i++) {
|
||||
@ -239,7 +310,8 @@ export function create_components(): {
|
||||
loading_status,
|
||||
scheduled_updates: update_scheduled_store,
|
||||
create_layout: (...args) =>
|
||||
requestAnimationFrame(() => create_layout(...args))
|
||||
requestAnimationFrame(() => create_layout(...args)),
|
||||
rerender_layout
|
||||
};
|
||||
}
|
||||
|
||||
@ -488,23 +560,3 @@ export function preload_all_components(
|
||||
|
||||
return constructor_map;
|
||||
}
|
||||
|
||||
export const restore_keyed_values = (
|
||||
old_components: ComponentMeta[],
|
||||
new_components: ComponentMeta[]
|
||||
): void => {
|
||||
let component_values_by_key: Record<string | number, ComponentMeta> = {};
|
||||
old_components.forEach((component) => {
|
||||
if (component.key) {
|
||||
component_values_by_key[component.key] = component;
|
||||
}
|
||||
});
|
||||
new_components.forEach((component) => {
|
||||
if (component.key) {
|
||||
const old_component = component_values_by_key[component.key];
|
||||
if (old_component) {
|
||||
component.props.value = old_component.props.value;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -24,6 +24,7 @@ export interface ComponentMeta {
|
||||
component: ComponentType<SvelteComponent>;
|
||||
documentation?: Documentation;
|
||||
children?: ComponentMeta[];
|
||||
parent?: ComponentMeta;
|
||||
value?: any;
|
||||
component_class_id: string;
|
||||
key: string | number | null;
|
||||
|
@ -102,6 +102,7 @@ class TestTextbox:
|
||||
"text_align": None,
|
||||
"autofocus": False,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"info": None,
|
||||
"autoscroll": True,
|
||||
}
|
||||
@ -187,6 +188,7 @@ class TestNumber:
|
||||
"info": None,
|
||||
"precision": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_component_functions_integer(self):
|
||||
@ -220,6 +222,7 @@ class TestNumber:
|
||||
"info": None,
|
||||
"precision": 0,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_component_functions_precision(self):
|
||||
@ -316,6 +319,7 @@ class TestSlider:
|
||||
"proxy_url": None,
|
||||
"info": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_in_interface(self):
|
||||
@ -374,6 +378,7 @@ class TestCheckbox:
|
||||
"interactive": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"info": None,
|
||||
}
|
||||
|
||||
@ -424,6 +429,7 @@ class TestCheckboxGroup:
|
||||
"interactive": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"type": "value",
|
||||
"info": None,
|
||||
}
|
||||
@ -473,6 +479,7 @@ class TestRadio:
|
||||
"interactive": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"type": "value",
|
||||
"info": None,
|
||||
}
|
||||
@ -557,6 +564,7 @@ class TestDropdown:
|
||||
"filterable": True,
|
||||
"max_choices": 2,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"type": "value",
|
||||
"info": None,
|
||||
}
|
||||
@ -621,6 +629,7 @@ class TestImageEditor:
|
||||
"mirror_webcam": True,
|
||||
"show_share_button": False,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"crop_size": None,
|
||||
"transforms": ("crop",),
|
||||
"eraser": {"default_size": "auto"},
|
||||
@ -692,6 +701,7 @@ class TestImage:
|
||||
"proxy_url": None,
|
||||
"mirror_webcam": True,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"streamable": False,
|
||||
"type": "pil",
|
||||
}
|
||||
@ -887,6 +897,7 @@ class TestAudio:
|
||||
"trim_region_color": None,
|
||||
},
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
assert audio_input.preprocess(None) is None
|
||||
|
||||
@ -941,6 +952,7 @@ class TestAudio:
|
||||
"trim_region_color": None,
|
||||
},
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
output1 = audio_output.postprocess(y_audio.name).model_dump()
|
||||
@ -1037,6 +1049,7 @@ class TestFile:
|
||||
"interactive": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"height": None,
|
||||
"type": "filepath",
|
||||
}
|
||||
@ -1152,6 +1165,7 @@ class TestDataframe:
|
||||
"metadata": None,
|
||||
},
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"headers": ["Name", "Age", "Member"],
|
||||
"row_count": (1, "dynamic"),
|
||||
"col_count": (3, "dynamic"),
|
||||
@ -1195,6 +1209,7 @@ class TestDataframe:
|
||||
"metadata": None,
|
||||
},
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"headers": ["1", "2", "3"],
|
||||
"row_count": (1, "dynamic"),
|
||||
"col_count": (3, "dynamic"),
|
||||
@ -1546,6 +1561,7 @@ class TestVideo:
|
||||
"min_length": None,
|
||||
"max_length": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
assert video_input.preprocess(None) is None
|
||||
video_input = gr.Video(format="avi")
|
||||
@ -1765,6 +1781,7 @@ class TestLabel:
|
||||
"proxy_url": None,
|
||||
"color": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_color_argument(self):
|
||||
@ -1920,6 +1937,7 @@ class TestHighlightedText:
|
||||
"value": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"combine_adjacent": False,
|
||||
"adjacent_separator": "",
|
||||
"interactive": None,
|
||||
@ -2008,6 +2026,7 @@ class TestAnnotatedImage:
|
||||
"value": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_in_interface(self):
|
||||
@ -2069,6 +2088,7 @@ class TestChatbot:
|
||||
"height": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
"latex_delimiters": [{"display": True, "left": "$$", "right": "$$"}],
|
||||
"likeable": False,
|
||||
"rtl": False,
|
||||
@ -2110,6 +2130,7 @@ class TestJSON:
|
||||
"name": "json",
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_chatbot_selectable_in_config(self):
|
||||
@ -2181,6 +2202,7 @@ class TestHTML:
|
||||
"proxy_url": None,
|
||||
"name": "html",
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_in_interface(self):
|
||||
@ -2235,6 +2257,7 @@ class TestModel3D:
|
||||
"zoom_speed": 1,
|
||||
"pan_speed": 1,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
file = "test/test_files/Box.gltf"
|
||||
@ -2280,6 +2303,7 @@ class TestColorPicker:
|
||||
"name": "colorpicker",
|
||||
"info": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_in_interface_as_input(self):
|
||||
@ -2562,6 +2586,7 @@ class TestScatterPlot:
|
||||
"x_label_angle": None,
|
||||
"y_label_angle": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_no_color(self):
|
||||
@ -2720,6 +2745,7 @@ class TestLinePlot:
|
||||
"x_label_angle": None,
|
||||
"y_label_angle": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_no_color(self):
|
||||
@ -2824,6 +2850,7 @@ class TestBarPlot:
|
||||
"y_label_angle": None,
|
||||
"sort": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_no_color(self):
|
||||
@ -2937,6 +2964,7 @@ class TestCode:
|
||||
"interactive": None,
|
||||
"proxy_url": None,
|
||||
"_selectable": False,
|
||||
"key": None,
|
||||
}
|
||||
|
||||
def test_process_example(self):
|
||||
|
Loading…
Reference in New Issue
Block a user