textual icon indicating copy to clipboard operation
textual copied to clipboard

TUI does not refresh automatically after I send a aiohttp request

Open DIGITALCRIMINAL opened this issue 3 years ago • 0 comments

Hello, I am unable to get the TUI to automatically refresh itself after I make a aiohttp request. The only way I can get it to refresh is if I interact with the TUI by hovering or clicking. I also noticed that aiohttp request creates an asyncio process.

import asyncio
import aiohttp
from rich.panel import Panel
from rich.text import Text
from textual.app import App
from textual.layouts.grid import GridLayout
from textual.widgets import Placeholder
from textual.widget import Widget


def layout_template(grid: GridLayout):

    grid.add_column(name="left")
    grid.add_column(name="center", fraction=4)
    grid.add_column(name="right")

    grid.add_row(name="top")
    grid.add_row(name="middle")
    grid.add_row(name="bottom")
    grid.add_row(name="bottom_input")

    grid.add_areas(
        area1="center-start|center-end,bottom",
        area2="center-start|center-end,bottom_input",
    )

    grid.place(
        area1=Placeholder(name="area1"),
        area2=Placeholder(name="area2"),
    )
    return grid


class CustomText(Widget):
    def __init__(
        self, name: str, text: str, title: str = "", subtitle: str = ""
    ) -> None:
        super().__init__(name)
        self.text = text
        self.title = title
        self.subtitle = subtitle

    def render(self) -> Panel:
        text_widget = Text(self.text)
        panel = Panel(text_widget, title=self.title, subtitle=self.subtitle)
        return panel


class DashboardController(App):
    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)
        self.dashboard = None
        self.main = None

    async def on_load(self) -> None:
        await self.bind("q", "quit", "Quit")
        await self.bind("enter", "submit", "Submit")
        await self.bind("escape", "reset_focus", show=False)
        await self.bind("ctrl+i", "next_tab_index", show=False)
        await self.bind("shift+tab", "previous_tab_index", show=False)

    async def on_mount(self):
        grid = await self.view.dock_grid(edge="left", name="left")
        self.dashboard = layout_template(grid)
        future = asyncio.ensure_future(main(self))

    async def add_text(
        self, text: str, title: str = "", subtitle: str = "", area="area1"
    ):
        if self.dashboard:
            custom = CustomText("custom_text", text, title, subtitle)
            args = {area: custom}
            self.dashboard.place(**args)
            return custom


async def main(dashboard_controller: DashboardController):
    await dashboard_controller.add_text(
        "Shows automatically before executing aiohttp. Please hover your mouse over the Dashboard",
        area="area1",
    )
    async with aiohttp.ClientSession() as session:
        # Creating a session is fine as it doesn't block Dashboard from updating, but making a request does.
        async with session.get("http://python.org") as response:
            pass
        pass
    await dashboard_controller.add_text(
        "Does not show automatically after executing aiohttp function, text only shows after interacting with the Dashboard",
        area="area2",
    )


DashboardController().run()

DIGITALCRIMINAL avatar Jul 14 '22 09:07 DIGITALCRIMINAL