Preface
Goal: Single Panel Watchfiles with Rich Live
We will do this step by step:
- Simple watch task using table.
- Prepare single watch task with panel.
- Dual task concurrently with split layout.
- Class refactoring for further use.
1: Simple Watchfiles Using Table
Python Source Code
You can visit my github, and download the sourse. So you can run a complete script.
Class: Skeleton
We start with only two methods.
class SingleWatch:
filepath = '/home/epsi/awatch/code-02-enh'
def generate_table(self, changes) -> Table:
async def main(self):
Required Package
Do not forget to import your friendly neighbourhood awatch
.
This will act as a backend process,
while the rich
is terinal frontend.
import asyncio
from watchfiles import awatch
from rich.live import Live
from rich.table import Table
Constructor
No need.
We need constructor later. But not now.
Async Main Method: Live
This is the heart of our script project. Instead of updating the layout, we update the live directly.
async def main(self):
with Live(None, refresh_per_second=4) as live:
watchloop = awatch(
self.filepath, recursive=True)
async for changes in watchloop:
live.update(self.generate_table(changes))
But why?
Because of the block building scope in live
.
As we can see when thing got complex later.
Renderable: Table
In this example, we start from simple renderable. It is the table without panel nor padding.
def generate_table(self, changes) -> Table:
# Make a new table
table = Table(expand=True)
table.add_column("Type")
table.add_column("File")
if changes != None:
for change in changes:
table.add_row(
*[str(change[0]),change[1]])
return table
Watchfiles Changes
Each changes has two property. And each change always return those two values.
- Change type
- File name (full path)
if changes != None:
for change in changes:
table.add_row(
*[str(change[0]),change[1]])
In order to setup table with empty change,
I add None
value to changes.
So you can do something like this:
with Live(self.generate_table(None)) as live:
...
I reallyt hink the flow is clear with simple setup. Let’s get it o and see the output.
TUI in CLI
With this simple setup, we can already display this output:
Just change something on folder, such as save excel files in libreoffice, or else. The terminal will immediately show any folder changes.
2: Live with Single Task
This would be very similar to previous example. There is not much changes, except that we have panel.
Python Source Code
It is always nice, when we have access to complete source code of working script.
Class: Skeleton
class SingleWatch:
filepath = '/home/epsi/awatch/code-02-enh'
def generate_table(self, changes) -> Table:
def get_panel(self, changes) -> Panel:
async def main(self):
Constructor
No need.
Brief
No such changes. Except Panel package.
import asyncio
from watchfiles import awatch
from rich.live import Live
from rich.table import Table
from rich.panel import Panel
class SingleWatch:
filepath = '/home/epsi/awatch/code-02-enh'
...
# Program Entry Point
single = SingleWatch()
asyncio.run(single.main())
Renderable: Table
Skip
No such changes.
def generate_table(self, changes) -> Table:
# Make a new table
table = Table(expand=True)
table.add_column("Type")
table.add_column("File")
if changes != None:
for change in changes:
table.add_row(
*[str(change[0]),change[1]])
return table
Renderable: Panel
Nothing special, just another simple panel.
def get_panel(self, changes) -> Panel:
dataTable = self.generate_table(changes)
panel = Panel(
dataTable, title="A Single Panel",
subtitle="A single [yellow]Thank you")
return panel
We wrapped the renderable table
inside the panel
.
panel = Panel(dataTable)
We can wrapped panel
inside the layout
.
And the layout
inside the live
.
Async Main Method: Live
The same as previous, as you can see below.
Except using renderable panel
inside live
, instead of table
.
async def main(self):
with Live(
self.get_panel(None),
refresh_per_second=4
) as live:
watchloop = awatch(
self.filepath, recursive=True)
async for changes in watchloop:
live.update(self.get_panel(changes))
In the next section we can wrapped layout
inside live
.
But meanwhile, enjoy the view result.
TUI in CLI
It is much more prettier with box.
Again, change something on folder, delete or move file. The terminal will immediately show any folder changes.
Many changes to ahead
Prepare
Understanding panel is necessary, before we step into the next section. I know there is not much to see in this section. All we do is just adding panel.
Now that we know the concept, we are ready to make more changes.
What is Next 🤔?
More panel please
In real life we need more than one watchfiles panel. We need to deal with the asyncio complexity.
Consider continue reading [ Python - Rich - Dual Watchfiles ].