Playing with rich
One of the things I do as a side project for Freexian is to work on various bits of business automation: accounting tools, programs to help contributors report their hours, invoicing, that kind of thing. While it’s not quite my usual beat, this makes quite a good side project as the tools involved are mostly rather sensible and easy to deal with (Python, git, ledger, that sort of thing) and it’s the kind of thing where I can dip into it for a day or so a week and feel like I’m making useful contributions. The logic can be quite complex, but there’s very little friction in the tools themselves.
A recent case where I did run into some friction in the tools was with some commands that need to present small amounts of tabular data on the terminal, using OSC 8 hyperlinks if the terminal supports them: think customer-related information with some links to issues. One of my colleagues had previously done this using a hack on top of texttable, which was perfectly fine as far as it went. However, now I wanted to be able to add multiple links in a single table cell in some cases, and that was really going to stretch the limits of that approach: working out the width of the displayed text in the cell was going to take an annoying amount of bookkeeping.
I started looking around to see whether any other approaches might be
easier, without too much effort (remember that “a day or so a week” bit
above). ansiwrap looked
somewhat promising, but it isn’t currently packaged in Debian, and it
would have still left me with the problem of figuring out how to
integrate it into texttable
, which looked like it would be quite
complicated. Then I remembered that I’d heard good things about
rich, and thought I’d take a look.
rich
turned out to be exactly what I wanted. Instead of something
like this based on the texttable
hack above:
import shutil from pyxian.texttable import UrlTable termsize = shutil.get_terminal_size((80, 25)) table = UrlTable(max_width=termsize.columns) table.set_deco(UrlTable.HEADER) table.set_cols_align(["l"]) table.set_cols_dtype(["u"]) table.add_row(["Issue"]) table.add_row([(issue_url, f"#{issue_id}")] print(table.draw())
… now I can do this instead:
import rich from rich import box from rich.table import Table table = Table(box=box.SIMPLE) table.add_column("Issue") table.add_row(f"[link={issue_url}]#{issue_id}[/link]") rich.print(table)
While this is a little shorter, the real bonus is that I can now just
put multiple [link]
tags in a single string, and it all just works.
No ceremony. In fact, once the relevant bits of code passed
type-checking (since the real code is a bit more complex than the
samples above), it worked first time. It’s a pleasure to work with a
library like that.
It looks like I’ve only barely scratched the surface of rich
, but I
expect I’ll reach for it more often now.
Comments
With an account on the Fediverse or Mastodon, you can respond to this post. Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one. Known non-private replies are displayed below.
Learn how this is implemented here.