Spaces:
Running
Running
from __future__ import annotations | |
from gradio.blocks import Block, Blocks | |
from typing import Dict | |
from fastapi import FastAPI | |
class LayoutBase: | |
main_layout: Block | |
name: str | |
global_children_dict: Dict[str, Block] | |
renderables: list | |
def __init__(self) -> None: | |
self.main_layout = None | |
self.name = "Layout Base" | |
self.global_children_dict = {} | |
self.renderables = [] | |
def add_component(self, name: str, component: Block) -> None: | |
self.renderables.append(component) | |
self.global_children_dict[name] = component | |
def add_layout(self, layout: LayoutBase) -> None: | |
self.renderables.append(layout) | |
self.global_children_dict.update(layout.global_children_dict) | |
def render(self) -> None: | |
with self.main_layout: | |
for renderable in self.renderables: | |
renderable.render() | |
self.main_layout.render() | |
def clear(self) -> None: | |
self.global_children_dict.clear() | |
for renderable in self.renderables: | |
if isinstance(renderable, LayoutBase): | |
renderable.clear() | |
self.renderables.clear() | |
def attach_event(self, block_dict: Dict[str, Block]) -> None: | |
raise NotImplementedError | |
class Application: | |
app: Blocks | |
children: list[LayoutBase] | |
# Blocks constructor parameters are omitted for brevity | |
def __init__(self, title: str) -> None: | |
self.app = Blocks(title=title) | |
self.children = [] | |
def add(self, child: LayoutBase): | |
self.children.append(child) | |
def _render(self): | |
with self.app: | |
for child in self.children: | |
child.render() | |
self.app.render() | |
def _attach_event(self): | |
block_dict: Dict[str, Block] = {} | |
for child in self.children: | |
block_dict.update(child.global_children_dict) | |
with self.app: | |
for child in self.children: | |
try: | |
child.attach_event(block_dict=block_dict) | |
except NotImplementedError: | |
print(f"{child.name}'s attach_event is not implemented") | |
def _clear(self): | |
from gc import collect | |
for child in self.children: | |
child.clear() | |
self.children.clear() | |
collect() | |
# launch function parameters are omitted for the brevity | |
def launch(self) -> tuple[FastAPI, str, str]: | |
self._render() | |
self._attach_event() | |
self._clear() | |
return self.app.launch() | |
from gradio import Row, Column, Tab, Textbox | |
class RowLayout(LayoutBase): | |
def __init__(self, name: str) -> None: | |
super().__init__() | |
self.main_layout = Row() | |
self.global_children_dict[name] = self.main_layout | |
class ColumnLayout(LayoutBase): | |
def __init__(self, name: str) -> None: | |
super().__init__() | |
self.main_layout = Column() | |
self.global_children_dict[name] = self.main_layout | |
class TabLayout(LayoutBase): | |
def __init__(self, name: str) -> None: | |
super().__init__() | |
self.main_layout = Tab(label=name) | |
self.global_children_dict[name] = self.main_layout | |
def change_text(new_str: str): | |
return Textbox(value=new_str) | |
class RowExample(RowLayout): | |
def __init__(self, name: str) -> None: | |
super().__init__(name=name) | |
self.left_textbox = Textbox( | |
value="Left Textbox", interactive=True, render=False | |
) | |
self.right_textbox = Textbox(value="Right Textbox", render=False) | |
self.add_component("left_textbox", self.left_textbox) | |
self.add_component("right_textbox", self.right_textbox) | |
def attach_event(self, block_dict: Dict[str, Block]) -> None: | |
self.left_textbox.change( | |
change_text, | |
inputs=self.left_textbox, | |
outputs=self.right_textbox, | |
) | |
class FirstTab(TabLayout): | |
def __init__(self, name: str) -> None: | |
super().__init__(name) | |
self.row = RowExample(name="first tab row layout") | |
self.add_layout(self.row) | |
def attach_event(self, block_dict: Dict[str, Block]) -> None: | |
self.row.attach_event(block_dict) | |
class SecondTab(TabLayout): | |
def __init__(self, name: str) -> None: | |
super().__init__(name) | |
self.column = ColumnLayout(name="second tab column layout") | |
self.top_textbox = Textbox(value="Top Textbox", interactive=True, render=False) | |
self.bottom_textbox = Textbox(value="Bottom Textbox", render=False) | |
self.column.add_component("top_textbox", self.top_textbox) | |
self.column.add_component("bottom_textbox", self.bottom_textbox) | |
self.add_layout(self.column) | |
def attach_event(self, block_dict: Dict[str, Block]) -> None: | |
block_dict["left_textbox"].change( | |
change_text, | |
inputs=block_dict["left_textbox"], | |
outputs=self.bottom_textbox, | |
) | |
gui = Application(title="Wrap Gradio") | |
first_tab = FirstTab(name="First Tab") | |
second_tab = SecondTab(name="Second Tab") | |
gui.add(first_tab) | |
gui.add(second_tab) | |
gui.launch() | |