-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Run events every given number of seconds #2512
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
2f0c059
13a021e
ae7f979
9c9e65f
d2ad009
ed0823a
2bb52ca
ac0087b
ca601a8
2be5c9a
2c9cb88
469b8d2
a15dab2
0647c05
a40d83a
de6d48e
1c3d068
1471e03
fbb6e78
5685f11
6b78d79
475686a
29aacdf
0b5c0f8
f673803
9e8f876
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| plotly |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import math | ||
| import gradio as gr | ||
| import datetime | ||
| import plotly.express as px | ||
| import numpy as np | ||
|
|
||
|
|
||
| def get_time(): | ||
| return datetime.datetime.now() | ||
|
|
||
|
|
||
| plot_end = 2 * math.pi | ||
|
|
||
|
|
||
| def get_plot(period=1): | ||
| global plot_end | ||
| x = np.arange(plot_end - 2 * math.pi, plot_end, 0.02) | ||
| y = np.sin(2*math.pi*period * x) | ||
| fig = px.line(x=x, y=y) | ||
| plot_end += 2 * math.pi | ||
| return fig | ||
|
|
||
|
|
||
| with gr.Blocks() as demo: | ||
| with gr.Row(): | ||
| with gr.Column(): | ||
| c_time2 = gr.Textbox(label="Current Time refreshed every second") | ||
| gr.Markdown("Change the value of the slider to automatically update the plot") | ||
| period = gr.Slider(label="Period of plot", value=1, minimum=0, maximum=10, step=1) | ||
| plot = gr.Plot(label="Plot (updates every half second)") | ||
| with gr.Column(): | ||
| name = gr.Textbox(label="Enter your name") | ||
| greeting = gr.Textbox(label="Greeting") | ||
| button = gr.Button(value="Greet") | ||
| button.click(lambda s: f"Hello {s}", name, greeting) | ||
|
|
||
| demo.load(lambda: datetime.datetime.now(), None, c_time2, every=1) | ||
| dep = demo.load(get_plot, None, plot, every=0.5) | ||
| period.change(get_plot, period, plot, every=0.5, cancels=[dep]) | ||
|
|
||
| if __name__ == "__main__": | ||
| demo.queue().launch() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,7 +46,12 @@ | |
| set_documentation_group, | ||
| ) | ||
| from gradio.exceptions import DuplicateBlockError | ||
| from gradio.utils import component_or_layout_class, delete_none, get_cancel_function | ||
| from gradio.utils import ( | ||
| component_or_layout_class, | ||
| delete_none, | ||
| get_cancel_function, | ||
| get_continuous_fn, | ||
| ) | ||
|
|
||
| set_documentation_group("blocks") | ||
|
|
||
|
|
@@ -134,6 +139,7 @@ def set_event_trigger( | |
| batch: bool = False, | ||
| max_batch_size: int = 4, | ||
| cancels: List[int] | None = None, | ||
| every: int | None = None, | ||
| ) -> Dict[str, Any]: | ||
| """ | ||
| Adds an event to the component's dependencies. | ||
|
|
@@ -163,10 +169,22 @@ def set_event_trigger( | |
| inputs = [inputs] | ||
| if not isinstance(outputs, list): | ||
| outputs = [outputs] | ||
|
|
||
| if Context.root_block is None: | ||
| raise AttributeError( | ||
| f"{event_name}() and other events can only be called within a Blocks context." | ||
| ) | ||
| if every is not None and every <= 0: | ||
| raise ValueError("Parameter every must be positive or None") | ||
| if every and batch: | ||
| raise ValueError( | ||
| f"Cannot run {event_name} event in a batch and every {every} seconds. " | ||
| "Either batch is True or every is non-zero but not both." | ||
| ) | ||
|
|
||
| if every: | ||
| fn = get_continuous_fn(fn, every) | ||
|
|
||
| Context.root_block.fns.append(BlockFunction(fn, preprocess, postprocess)) | ||
| if api_name is not None: | ||
| api_name_ = utils.append_unique_suffix( | ||
|
|
@@ -177,6 +195,7 @@ def set_event_trigger( | |
| "api_name {} already exists, using {}".format(api_name, api_name_) | ||
| ) | ||
| api_name = api_name_ | ||
|
|
||
| dependency = { | ||
| "targets": [self._id] if not no_target else [], | ||
| "trigger": event_name, | ||
|
|
@@ -188,6 +207,7 @@ def set_event_trigger( | |
| "api_name": api_name, | ||
| "scroll_to_output": scroll_to_output, | ||
| "show_progress": show_progress, | ||
| "every": every, | ||
| "batch": batch, | ||
| "max_batch_size": max_batch_size, | ||
| "cancels": cancels or [], | ||
|
|
@@ -885,7 +905,6 @@ async def process_api( | |
| data = [self.postprocess_data(fn_index, o, state) for o in zip(*preds)] | ||
| data = list(zip(*data)) | ||
| is_generating, iterator = None, None | ||
|
|
||
| else: | ||
| inputs = self.preprocess_data(fn_index, inputs, state) | ||
| iterator = iterators.get(fn_index, None) if iterators else None | ||
|
|
@@ -983,8 +1002,9 @@ def load( | |
| api_key: Optional[str] = None, | ||
| alias: Optional[str] = None, | ||
| _js: Optional[str] = None, | ||
| every: None | int = None, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated to your PR, this event trigger is missing many arguments, such as
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll do that in a separate PR! Thank you for pointing this out! |
||
| **kwargs, | ||
| ) -> Blocks | None: | ||
| ) -> Blocks | Dict[str, Any] | None: | ||
| """ | ||
| For reverse compatibility reasons, this is both a class method and an instance | ||
| method, the two of which, confusingly, do two completely different things. | ||
|
|
@@ -1002,6 +1022,7 @@ def load( | |
| fn: Instance Method - Callable function | ||
| inputs: Instance Method - input list | ||
| outputs: Instance Method - output list | ||
| every: Run this event 'every' number of seconds. Interpreted in seconds. Queue must be enabled. | ||
| Example: | ||
| import gradio as gr | ||
| import datetime | ||
|
|
@@ -1026,13 +1047,14 @@ def get_time(): | |
| kwargs["outputs"] = outputs | ||
| return external.load_blocks_from_repo(name, src, api_key, alias, **kwargs) | ||
| else: | ||
| self_or_cls.set_event_trigger( | ||
| return self_or_cls.set_event_trigger( | ||
| event_name="load", | ||
| fn=fn, | ||
| inputs=inputs, | ||
| outputs=outputs, | ||
| no_target=True, | ||
| js=_js, | ||
| no_target=True, | ||
| every=every, | ||
| ) | ||
|
|
||
| def clear(self): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.