mirror of
https://github.com/gradio-app/gradio.git
synced 2025-04-06 12:30:29 +08:00
fix every=
support in render (#10113)
* changes * add changeset * changes --------- Co-authored-by: Ali Abid <aliabid94@gmail.com> Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
f1718c4713
commit
de42c85661
5
.changeset/slimy-clocks-laugh.md
Normal file
5
.changeset/slimy-clocks-laugh.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"gradio": patch
|
||||
---
|
||||
|
||||
fix:fix `every=` support in render
|
1
demo/render_tests/run.ipynb
Normal file
1
demo/render_tests/run.ipynb
Normal file
@ -0,0 +1 @@
|
||||
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: render_tests"]}, {"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": ["from datetime import datetime\n", "\n", "import gradio as gr\n", "\n", "def update_log():\n", " return datetime.now().timestamp()\n", "\n", "with gr.Blocks() as demo:\n", " gr.Textbox(value=update_log, every=0.2, label=\"Time\")\n", " \n", " slider = gr.Slider(1, 10, step=1)\n", " @gr.render(inputs=[slider])\n", " def show_log(s):\n", " for i in range(s):\n", " gr.Textbox(value=update_log, every=0.2, label=f\"Render {i + 1}\")\n", "\n", "if __name__ == '__main__':\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
|
18
demo/render_tests/run.py
Normal file
18
demo/render_tests/run.py
Normal file
@ -0,0 +1,18 @@
|
||||
from datetime import datetime
|
||||
|
||||
import gradio as gr
|
||||
|
||||
def update_log():
|
||||
return datetime.now().timestamp()
|
||||
|
||||
with gr.Blocks() as demo:
|
||||
gr.Textbox(value=update_log, every=0.2, label="Time")
|
||||
|
||||
slider = gr.Slider(1, 10, step=1)
|
||||
@gr.render(inputs=[slider])
|
||||
def show_log(s):
|
||||
for i in range(s):
|
||||
gr.Textbox(value=update_log, every=0.2, label=f"Render {i + 1}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
demo.launch()
|
@ -943,6 +943,30 @@ class BlocksConfig:
|
||||
new.fn_id = self.fn_id
|
||||
return new
|
||||
|
||||
def attach_load_events(self, rendered_in: Renderable | None = None):
|
||||
"""Add a load event for every component whose initial value requires a function call to set."""
|
||||
for component in self.blocks.values():
|
||||
if rendered_in is not None and component.rendered_in != rendered_in:
|
||||
continue
|
||||
if (
|
||||
isinstance(component, components.Component)
|
||||
and component.load_event_to_attach
|
||||
):
|
||||
load_fn, triggers, inputs = component.load_event_to_attach
|
||||
has_target = len(triggers) > 0
|
||||
triggers += [(self.root_block, "load")]
|
||||
# Use set_event_trigger to avoid ambiguity between load class/instance method
|
||||
|
||||
dep = self.set_event_trigger(
|
||||
[EventListenerMethod(*trigger) for trigger in triggers],
|
||||
load_fn,
|
||||
inputs,
|
||||
component,
|
||||
no_target=not has_target,
|
||||
show_progress="hidden" if has_target else "full",
|
||||
)[0]
|
||||
component.load_event = dep.get_config()
|
||||
|
||||
|
||||
@document("launch", "queue", "integrate", "load", "unload")
|
||||
class Blocks(BlockContext, BlocksEvents, metaclass=BlocksMeta):
|
||||
@ -2169,7 +2193,7 @@ Received inputs:
|
||||
super().fill_expected_parents()
|
||||
set_render_context(self.parent)
|
||||
# Configure the load events before root_block is reset
|
||||
self.attach_load_events()
|
||||
self.default_config.attach_load_events()
|
||||
if self.parent is None:
|
||||
Context.root_block = None
|
||||
else:
|
||||
@ -2845,30 +2869,6 @@ Received inputs:
|
||||
for tunnel in CURRENT_TUNNELS:
|
||||
tunnel.kill()
|
||||
|
||||
def attach_load_events(self):
|
||||
"""Add a load event for every component whose initial value should be randomized."""
|
||||
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
|
||||
):
|
||||
load_fn, triggers, inputs = component.load_event_to_attach
|
||||
has_target = len(triggers) > 0
|
||||
triggers += [(self, "load")]
|
||||
# Use set_event_trigger to avoid ambiguity between load class/instance method
|
||||
|
||||
dep = self.default_config.set_event_trigger(
|
||||
[EventListenerMethod(*trigger) for trigger in triggers],
|
||||
load_fn,
|
||||
inputs,
|
||||
component,
|
||||
no_target=not has_target,
|
||||
show_progress="hidden" if has_target else "full",
|
||||
)[0]
|
||||
component.load_event = dep.get_config()
|
||||
|
||||
def run_startup_events(self):
|
||||
"""Events that should be run when the app containing this block starts up."""
|
||||
self._queue.start()
|
||||
|
@ -74,6 +74,7 @@ class Renderable:
|
||||
with container_copy:
|
||||
self.fn(*args, **kwargs)
|
||||
blocks_config.blocks[self.container_id] = container_copy
|
||||
blocks_config.attach_load_events(self)
|
||||
finally:
|
||||
LocalContext.renderable.set(None)
|
||||
|
||||
|
23
js/spa/test/render_tests.spec.ts
Normal file
23
js/spa/test/render_tests.spec.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { test, expect } from "@self/tootils";
|
||||
|
||||
test("Test every= works in render", async ({ page }) => {
|
||||
const timebox = page.getByLabel("Time");
|
||||
const box_1 = page.getByLabel("Render 1");
|
||||
const slider = page.getByLabel("number input for Slider");
|
||||
let timebox_value_start = parseFloat(await timebox.inputValue());
|
||||
let box_1_value_start = parseFloat(await box_1.inputValue());
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
let timebox_value_end = parseFloat(await timebox.inputValue());
|
||||
expect(timebox_value_end).toBeGreaterThan(timebox_value_start);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await slider.fill("4");
|
||||
const box_2 = page.getByLabel("Render 2");
|
||||
let box_2_value_start = parseFloat(await box_2.inputValue());
|
||||
expect(box_2_value_start).toBeGreaterThan(box_1_value_start);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
let box_2_value_end = parseFloat(await box_2.inputValue());
|
||||
expect(box_2_value_end).toBeGreaterThan(box_2_value_start);
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user