Spaces:
Running
Running
File size: 2,717 Bytes
b72ab63 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
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
|