Where there is a Will

Will McGugan's Blog

I am a freelance software engineer living in Edinburgh.

I post mostly about tech (particularly Python) and photography.

Background: A code monkey

I recently came to a decision which will have a big impact on my open source work. In particular Rich and Textual, but also pyfilesystem and lomond. For the foreseeable future, possibly up to a year, I'll be working on them essentially full time.

Rich is a very popular project now, with over 29K stars on Github. It has near 100% coverage and a stable API, but no codebase is ever really finished so there will be on-going work. Textual is Rich's sister project which is brand new and under active development, but already has 4.8K stars. It is also a much larger project than Rich. To do Textual justice I'm going to need to put in some serious time over and above what I could realistically do for a hobby project.

Some of the applications in the Textual examples directory continue reading…

If you work with JSON regularly (90% of Python developers I suspect) you might appreciate the print_json function just landed in Rich v10.9.0

If you call this function with a string, Rich will decode the string, reformat it, and print it to the console with nice syntax highlighting. Here's an example:

Here's the output:

Calling print_json with a string will decode the JSON and pretty print it.

Note that the atomic values false, true, and null have their own color. I find this helpful when scanning a JSON blob.

If you call print_json with a data keyword argument it will encode that data and pretty print it in the same way.

Here's the output:

Calling the print_json function with a data keyword argument. continue reading…

I've started work on a new project called Textual.

Textual is (or will be) a TUI framework using Rich as a renderer. It's still very early days, but ultimately the goal is to have something which you can uses to build a Text User Interface with little to no boiler-plate.

It is async powered. Each "widget" runs in an async task and communicates via a message queue. This should allow the UI to remain responsive even when the app is doing work.

Running a Textual app in Vscode.

An example Textual app (currently the only one) with a default layout. Title bar with working clock. Side panel that can be toggled with a key. And a scrolling window containing Markdown. continue reading…

Rich has become a popular (20K stars on GH) way of beautifying CLIs, and I'm pleased to see a number of projects using it.

Since Rich is mature and battle-tested now, I had considered winding-down development. Until, I saw this tweet:

Do you want to see something really cool you can do with @willmcgugan 's rich library?

Checkout ghtop https://t.co/mn7oLbpw8e. It's a really fun CLI tool that demonstrates the power of rich (and other things).

Examples below 🧵👇 (1/8)

— Hamel Husain (@HamelHusain)

@HamelHusain and @jeremyphoward used Rich to enhance ghtop (a repo owned by the CEO of Github, no less). Ghtop shows a realtime a stream of events from the Github platform. And it looks good! So good that I realised how much potential Rich has for these type of htop-like applications. continue reading…

The latest version of Rich adds a tree view. Here's an example of one:

The labels of each branch in the tree can be text or anything else that rich can render. The guide lines can have a color per-branch and one of three styles; normal, thick, and double line.

The API to generate these trees is super simple and currently has just one public method to add a new branch.

Here's a simple example demonstrating that money does, in fact, grow on trees. continue reading…

Rich 5.1.0 adds the ability to integrate highlighted pretty printing with the Python REPL. Here's how you would use it in a session:

Assuming you have installed Rich of course.

Now any data will be formatted and highlighted. Here's an example:

Rich will expand builtin containers until the output fits in to the width of the screen.

In addition to Python data structures, any object supporting the Rich Console Protocol will be displayed. Here's an example:

The Panel class is one of a number of renderables in Rich.

The formatting and highlighting really comes in to its own when you're working with JSON data. The following video shows an example of pretty printing data queried from a web service. In this instance, its cat facts.

Follow @willmcgugan for updates regarding Rich.

I recently tested Rich logging with a Django project and the results were good. Here's what it looks like:

A Django app with Rich logging

Note the file and line at the right hand of the terminal which shows were the log function was called. If your terminal supports hyperlinks, you can click that link to open the file!

For reference, here's what it looks like without Rich logging.

A Django app without Rich logging

This is the default RichHandler class in Rich. It would be possible to do a little more customization for Django logs. Maybe highlight 5xx in red, for example.

To add this to your Django project, pip install rich then configure the console to use "rich.logging.RichHandler" rather than StreamHandler.

Since my last post on Rich there have been a number of improvements. Here are the major highlights:

Progress bars now have an indeterminate state which displays a pulsing animation. This a fairly common thing from graphical UIs, here's what it looks like in the terminal:

To see it in action install Rich and run the following:

Or just watch this video.

You can use this new state to show when something is working, but before you know how many 'steps' are involved. For instance, when making a request over the internet, you won't know how many bytes you have to download until you get a response. Rather than show a progress bar at 0% you can show this pulse effect while waiting on the server. continue reading…

Since releasing Rich 1.0.0 I've discovered that terminals support hyperlinks. And I don't mean the helpful highlighting of URLs that most terminals do, I mean actual HTML-like hyperlinks that launch a browser.

This was news to me, as I've never seen this feature in the wild. I just had to add it to Rich. The easiest way to output hyperlinks is via console markup. Here's a simple example:

This will output the text "Visit my blog!" in the terminal where the word "blog" is a clickable link that opens the browser.

This is a relatively new (2017) addition to the spec, so it isn't supported on all terminal apps. If your terminal doesn't support hyperlinks then the link won't be clickable, but you will see the text as normal.

I'm happy to announce the release of version 1.0.0 of Rich - my Python library for fancy terminal rendering.

Rich is a project I started back in October 2019 when I was staying in Wuhan, a few weeks before it was locked down. Back then it was a toy project designed to pass the time while traveling. In the spirit of XKCD 927 I wanted to create a library that could display rich content in the terminal as effortlessly as you can with HTML. continue reading…