WEBVTT

00:00:00.001 --> 00:00:01.760
Have you heard of the package rich?

00:00:01.760 --> 00:00:06.260
This library allows you to create, well, rich terminal-based UIs in Python.

00:00:06.260 --> 00:00:09.960
When you think of what you can typically build with basic print statements,

00:00:09.960 --> 00:00:11.420
they may seem quite limited.

00:00:11.420 --> 00:00:15.620
But with rich, imagine justified tables, progress bars,

00:00:15.620 --> 00:00:17.900
rendering of markdown, and way more.

00:00:17.900 --> 00:00:21.520
This is one of the fastest-growing projects in the Python space these days,

00:00:21.520 --> 00:00:24.420
and the creator, Will McGoogan, is here to give us the whole history

00:00:24.420 --> 00:00:28.540
and even a peek at the future of rich and a follow-on library called Textual.

00:00:29.240 --> 00:00:34.700
This is Talk Python To Me, episode 336, recorded October 13th, 2021.

00:00:34.700 --> 00:00:50.420
Welcome to Talk Python To Me, a weekly podcast on Python.

00:00:50.420 --> 00:00:52.160
This is your host, Michael Kennedy.

00:00:52.160 --> 00:00:54.420
Follow me on Twitter, where I'm @mkennedy,

00:00:54.420 --> 00:00:58.340
and keep up with the show and listen to past episodes at talkpython.fm.

00:00:58.480 --> 00:01:01.360
And follow the show on Twitter via at Talk Python.

00:01:01.360 --> 00:01:05.060
We've started streaming most of our episodes live on YouTube.

00:01:05.060 --> 00:01:08.800
Subscribe to our YouTube channel over at talkpython.fm/youtube

00:01:08.800 --> 00:01:12.580
to get notified about upcoming shows and be part of that episode.

00:01:12.580 --> 00:01:17.760
This episode is brought to you by Shortcut, formerly known as clubhouse.io,

00:01:17.760 --> 00:01:19.840
and us over at Talk Python Training.

00:01:19.840 --> 00:01:22.780
And the transcripts are brought to you by Assembly AI.

00:01:24.160 --> 00:01:25.980
Will, welcome to Talk Python To Me.

00:01:25.980 --> 00:01:26.380
Thank you.

00:01:26.380 --> 00:01:28.620
It's fantastic to finally have you on the show.

00:01:28.620 --> 00:01:32.400
I feel like we've talked a lot about the work that you've been doing many times.

00:01:32.400 --> 00:01:36.380
Not so much on Talk Python because we're more focused on a single topic.

00:01:36.380 --> 00:01:41.800
But even so, I believe, you know, at the end, I always ask for some project that needs attention,

00:01:41.800 --> 00:01:43.000
needs some sort of shout out.

00:01:43.000 --> 00:01:45.680
And, you know, I believe Rich has come up more than once.

00:01:45.740 --> 00:01:48.400
I think Textual has come up at least once there.

00:01:48.400 --> 00:01:51.780
So the prior guests of the show have been fans.

00:01:51.780 --> 00:01:53.920
And I know the audience is a big fan.

00:01:53.920 --> 00:01:56.440
So, yeah, congrats on all the progress there.

00:01:56.440 --> 00:01:57.120
Great. Thanks.

00:01:57.120 --> 00:01:58.920
Yeah, I really appreciate the coverage.

00:01:58.920 --> 00:02:02.140
You probably increased my star count by a few thousand.

00:02:02.140 --> 00:02:06.040
Well, I do want to talk about that because this project is super popular.

00:02:06.040 --> 00:02:12.260
And as we get into it, I think it's going to be fun to explore some of the things that you felt were key to that.

00:02:12.260 --> 00:02:18.700
And if this is the first time people are hearing about Rich, you definitely want to check out some of the screenshots.

00:02:18.700 --> 00:02:26.380
Maybe I'll do something fun, like make part of the show, have the show notes or the podcast player have some screenshots from the various sections.

00:02:26.380 --> 00:02:28.280
Like as I said, I'll see if I can make that happen.

00:02:28.280 --> 00:02:33.720
But before we get to all that, before we dive into Rich and Textual and all the other things, let's talk about you.

00:02:33.720 --> 00:02:37.840
How did you get into programming and how did you find yourself doing all this open source Python?

00:02:37.840 --> 00:02:39.220
How did I get into programming?

00:02:39.220 --> 00:02:39.780
Oh, OK.

00:02:39.780 --> 00:02:44.320
So as a kid in the 80s, I guess, I had a Spectrum 48K computer.

00:02:44.320 --> 00:02:51.360
It was a little plastic thing you plugged into your TV and you could create very simple animations and little games.

00:02:51.360 --> 00:02:52.780
And I think from there I was hooked.

00:02:52.780 --> 00:02:53.440
Oh, fantastic.

00:02:53.440 --> 00:02:57.660
That's just something about me that connected with programming, I guess.

00:02:57.660 --> 00:03:00.080
What's interesting is those games were so basic, right?

00:03:00.080 --> 00:03:03.720
They weren't like 3D, VR, oh my gosh, I'm there.

00:03:03.720 --> 00:03:08.600
Or some of the flashy, even the flashy mobile apps, mobile games these days.

00:03:08.600 --> 00:03:13.900
But something about those early, early games really captured the imagination, didn't they?

00:03:13.900 --> 00:03:14.160
Yeah.

00:03:14.160 --> 00:03:18.020
And the fact that they were so limiting had to make you a little bit creative.

00:03:18.020 --> 00:03:21.600
So it encouraged creativity because you couldn't do much of anything.

00:03:21.600 --> 00:03:24.160
So you had to make the best of what you got.

00:03:24.240 --> 00:03:26.100
So it encouraged you to experiment.

00:03:26.100 --> 00:03:29.940
And I think it was a great way to get people into programming again, I think.

00:03:29.940 --> 00:03:30.140
Yeah.

00:03:30.140 --> 00:03:32.180
Until recently, we haven't had that.

00:03:32.180 --> 00:03:35.440
And I think the Raspberry Pi does that to some extent, which is a great thing.

00:03:35.440 --> 00:03:35.780
Yeah.

00:03:35.780 --> 00:03:41.340
It sort of reaches out to the real world in a more simplistic way, kind of repeating that cycle, right?

00:03:41.340 --> 00:03:41.720
Yeah.

00:03:41.720 --> 00:03:42.220
Yeah.

00:03:42.240 --> 00:03:48.700
And it just allows people access to programming in a very kind of accessible form for children, I guess.

00:03:48.700 --> 00:03:55.340
So I think the next generation in 20 years will be citing Raspberry Pi as how they got into programming.

00:03:55.340 --> 00:03:55.820
Interesting.

00:03:55.820 --> 00:03:56.140
Yeah.

00:03:56.140 --> 00:03:59.120
I built a robot the first time around or something like that, right?

00:03:59.120 --> 00:03:59.540
Yeah.

00:03:59.800 --> 00:04:04.080
Instead of wanting to play a game or script a game out or something like that.

00:04:04.080 --> 00:04:04.800
Interesting.

00:04:04.800 --> 00:04:08.580
And, you know, a lot of times I ask people, okay, well, what are you doing now?

00:04:08.580 --> 00:04:13.040
They're like, oh, I'm, you know, head of data science at a company such and such.

00:04:13.040 --> 00:04:20.300
You've taken a very interesting, and I suspect a lot of people will be quite jealous of what you're up to these days, right?

00:04:20.300 --> 00:04:21.060
What are you doing now?

00:04:21.060 --> 00:04:21.420
Yeah.

00:04:21.420 --> 00:04:24.320
So up until recently, I was contracting.

00:04:24.320 --> 00:04:26.220
But I ended my contract.

00:04:26.300 --> 00:04:28.140
I'm going to take a year out.

00:04:28.140 --> 00:04:30.220
Well, possibly a year.

00:04:30.220 --> 00:04:31.060
It depends how much.

00:04:31.060 --> 00:04:32.840
It depends how things go.

00:04:32.840 --> 00:04:38.280
But the idea is to work on open source, specifically rich and textual.

00:04:38.280 --> 00:04:40.920
There are other projects that take my fancy as well.

00:04:40.920 --> 00:04:44.280
Anything that I can contribute to might try my hand at it.

00:04:44.280 --> 00:04:50.780
It's not entirely selfless because I do think there might be commercial applications for textual down the line.

00:04:51.600 --> 00:04:57.560
But certainly for this first six months, it'll be just focusing on just making it the best thing you can.

00:04:57.560 --> 00:04:59.140
Making it a super solid foundation.

00:04:59.140 --> 00:05:00.640
Yeah, absolutely.

00:05:00.640 --> 00:05:07.280
Well, I don't think it's going to take that much to get some things in place to make this long term for you.

00:05:07.280 --> 00:05:13.700
You know, people can go, if their company or individually they're finding huge value, they could go to GitHub and sponsor you.

00:05:14.140 --> 00:05:16.740
There's enterprise stuff that can be set up.

00:05:16.740 --> 00:05:19.880
We'll dive a little bit into that more possibly later as well.

00:05:19.880 --> 00:05:21.200
But I wish you a lot of luck.

00:05:21.200 --> 00:05:30.820
But I think with the traction that you're getting and the new things like I really find GitHub's sponsor feature to be something of a game changer.

00:05:30.820 --> 00:05:31.300
Yeah.

00:05:31.440 --> 00:05:34.320
I remember looking back, you'd see, oh, here's a popular project.

00:05:34.320 --> 00:05:37.160
Maybe it's not even an open source library, but it's like an app.

00:05:37.160 --> 00:05:40.000
And it's like, click here to thank the developer on PayPal.

00:05:40.000 --> 00:05:40.780
Right.

00:05:40.780 --> 00:05:41.120
And just.

00:05:41.120 --> 00:05:43.700
There was a little bit of a barrier to entry.

00:05:43.700 --> 00:05:44.260
Yeah.

00:05:44.260 --> 00:05:45.260
And maybe you do it once.

00:05:45.260 --> 00:05:45.440
Right.

00:05:45.440 --> 00:05:49.000
But with GitHub, you can say, I just kind of want to say, I want this to keep going.

00:05:49.000 --> 00:05:51.160
So here's two dollars a month.

00:05:51.160 --> 00:05:58.480
And if, you know, not that many people who find it valuable send in a couple of bucks a month, all of a sudden it starts to be a foundation that you can really build from.

00:05:58.480 --> 00:05:58.820
Yeah.

00:05:58.820 --> 00:06:08.820
It could build up and be something which is sustainable and sustain open source because so many people benefit from open source, including big companies, big corporations.

00:06:08.820 --> 00:06:13.060
But a lot of these developers are doing it in their spare time for the love of it.

00:06:13.060 --> 00:06:18.900
And they haven't asked for funding before, but a lot of them deserve funding.

00:06:18.900 --> 00:06:30.080
Certainly lots of projects which could really use funding to make sure they keep going, to make sure that the software that we all use is still available in a year, two years and five years down the line.

00:06:30.080 --> 00:06:30.680
Yeah.

00:06:30.680 --> 00:06:39.000
Otherwise, we're going to end up in a place with like open SSL where there's one person who maintains it and a quarter of the world seems to be built directly upon it.

00:06:39.000 --> 00:06:39.180
Right.

00:06:39.180 --> 00:06:39.620
Remember that?

00:06:39.620 --> 00:06:39.960
Yeah.

00:06:39.960 --> 00:06:41.360
It was a huge problem.

00:06:41.360 --> 00:06:42.440
Heartbleed, was it called?

00:06:42.720 --> 00:06:44.200
Which is a Heartbleed?

00:06:44.200 --> 00:06:44.580
Yeah.

00:06:44.580 --> 00:06:45.320
Heartbleed, that's right.

00:06:45.320 --> 00:06:46.300
Yeah.

00:06:46.300 --> 00:06:47.460
Which is a great name for a bug.

00:06:47.460 --> 00:06:49.440
It really is.

00:06:49.440 --> 00:06:50.620
Why wasn't this fixed?

00:06:50.620 --> 00:06:54.400
Well, there's one person who does it in their spare time, but everything depends on it.

00:06:54.400 --> 00:06:57.200
Yeah, but there's still one person who does it in their spare time.

00:06:57.200 --> 00:06:57.520
Yeah.

00:06:57.520 --> 00:07:01.960
And yeah, it's just really hard to put that kind of energy and responsiveness into it.

00:07:01.960 --> 00:07:02.440
All right.

00:07:02.440 --> 00:07:02.980
Fantastic.

00:07:02.980 --> 00:07:07.120
So let's start with textual, which I had on the screen, but let's start with rich.

00:07:07.120 --> 00:07:11.660
Rich is where things got started amongst rich and textual, right?

00:07:11.660 --> 00:07:12.700
If I remember the history.

00:07:12.700 --> 00:07:13.040
Yeah.

00:07:13.040 --> 00:07:14.240
Rich was first.

00:07:14.240 --> 00:07:16.120
That's about two years ago that I started that.

00:07:16.120 --> 00:07:16.580
Yeah.

00:07:16.580 --> 00:07:17.000
Cool.

00:07:17.000 --> 00:07:22.300
So tell people, you know, a lot of people have heard of rich, but maybe tell folks out there,

00:07:22.300 --> 00:07:23.840
how would you describe it?

00:07:23.840 --> 00:07:27.500
You know, it's, we've had ways to sort of print stuff nicer.

00:07:27.660 --> 00:07:29.200
We've got pretty print Python.

00:07:29.200 --> 00:07:33.420
We've got colorama where you can put color into your, your terminal, but this takes it

00:07:33.420 --> 00:07:35.040
to an absolutely new level.

00:07:35.040 --> 00:07:36.820
So tell us, tell us about rich.

00:07:36.820 --> 00:07:37.160
Yeah.

00:07:37.160 --> 00:07:40.840
that makes it difficult to describe sometimes when people ask me what it does, because it

00:07:40.840 --> 00:07:42.260
does quite a lot of things.

00:07:42.260 --> 00:07:47.460
but it's all under the umbrella of writing more sophisticated outputs to the terminal.

00:07:47.460 --> 00:07:53.140
At the basic level is you can set colors and you can set styles like bold and italic.

00:07:53.140 --> 00:07:58.360
the next level up, it'll do word wrap and it'll also word wrap the style.

00:07:58.360 --> 00:08:00.720
So you can apply bold and then, then word wrap it.

00:08:00.720 --> 00:08:03.360
And then we have things like tables.

00:08:03.560 --> 00:08:08.140
There's quite sophisticated table support, which are quite close to HTML tables.

00:08:08.140 --> 00:08:10.640
You can, you know, put things in cells.

00:08:10.640 --> 00:08:13.760
You've got a header row, you've got a little divider, and then you've got the data.

00:08:13.760 --> 00:08:14.000
Yeah.

00:08:14.000 --> 00:08:14.460
Yeah.

00:08:14.460 --> 00:08:17.480
And then you can draw lines around it and change the styles.

00:08:17.480 --> 00:08:22.060
And, it's, it's all, you even have like alternating rows, right?

00:08:22.060 --> 00:08:25.500
So it kind of helps you line across, which is pretty neat.

00:08:25.500 --> 00:08:25.940
Exactly.

00:08:25.940 --> 00:08:26.200
Yeah.

00:08:26.200 --> 00:08:27.860
So it's, it's quite sophisticated.

00:08:27.860 --> 00:08:29.280
It's all composable.

00:08:29.280 --> 00:08:33.420
So if I've got a table, I can obviously put text inside it, but I can put another

00:08:33.420 --> 00:08:37.840
table inside it, or I could put a progress bar inside it or syntax highlighting inside

00:08:37.840 --> 00:08:38.000
it.

00:08:38.000 --> 00:08:41.860
So the idea is that, rather than like lots of separate libraries, which don't work

00:08:41.860 --> 00:08:45.080
well together, which I think was a situation that we had previously.

00:08:45.080 --> 00:08:46.520
Now they all work together.

00:08:46.520 --> 00:08:49.720
They fit inside each other and they integrate quite well.

00:08:49.720 --> 00:08:50.000
Right.

00:08:50.000 --> 00:08:53.300
So you could take your formatting and put it in your word wrap and put it inside of a

00:08:53.300 --> 00:08:54.520
table cell or something like that.

00:08:54.520 --> 00:08:54.920
Exactly.

00:08:54.920 --> 00:08:55.180
Yeah.

00:08:55.180 --> 00:08:55.740
Yeah.

00:08:55.740 --> 00:08:56.060
Yeah.

00:08:56.060 --> 00:08:56.640
Yeah.

00:08:56.640 --> 00:08:56.800
Yeah.

00:08:56.800 --> 00:09:00.660
So one of the things that struck me, well, there's a couple of things, but one of them

00:09:00.660 --> 00:09:03.020
is just how popular Rich is.

00:09:03.280 --> 00:09:03.600
Right.

00:09:03.600 --> 00:09:05.820
It's almost 30,000 GitHub stars.

00:09:05.820 --> 00:09:11.680
That's, that's close to FastAPI level of popularity and not that far behind Flask and

00:09:11.680 --> 00:09:11.940
Django.

00:09:11.940 --> 00:09:13.560
That's a really, really popular.

00:09:13.560 --> 00:09:14.940
When did you create this?

00:09:14.940 --> 00:09:15.600
Two years ago.

00:09:15.600 --> 00:09:16.420
Yeah.

00:09:16.420 --> 00:09:16.780
Yeah.

00:09:16.780 --> 00:09:24.160
So I guess on the timeline, similar age to FastAPI, but much younger than Flask and Django,

00:09:24.160 --> 00:09:25.680
if I'm comparing them to those.

00:09:25.680 --> 00:09:30.340
And over here, it says on your page, you have 2 million downloads a month.

00:09:30.340 --> 00:09:31.340
That's pretty incredible.

00:09:31.340 --> 00:09:31.700
Yeah.

00:09:31.700 --> 00:09:32.960
That's, that's, that's pretty crazy.

00:09:33.080 --> 00:09:35.560
I think quite a few of those are automated.

00:09:35.560 --> 00:09:37.420
They're from CI systems.

00:09:37.420 --> 00:09:37.740
Yeah.

00:09:37.740 --> 00:09:37.940
Yeah.

00:09:37.940 --> 00:09:41.220
But I do see that, that rising quite, quite steadily.

00:09:41.220 --> 00:09:41.560
Yeah.

00:09:41.560 --> 00:09:47.840
I wonder how many of the CI systems just in general out there do caching at some level where it

00:09:47.840 --> 00:09:48.540
wouldn't register.

00:09:48.540 --> 00:09:48.860
Right.

00:09:48.940 --> 00:09:52.380
you know, I pip install a thing I've already installed and it's a certain version.

00:09:52.380 --> 00:09:53.900
And it'll just say using cached version.

00:09:53.900 --> 00:09:54.160
Mm-hmm.

00:09:54.160 --> 00:09:54.540
Mm-hmm.

00:09:54.540 --> 00:09:55.020
Right.

00:09:55.020 --> 00:09:55.060
Right.

00:09:55.060 --> 00:10:00.200
versus if you create a brand new Docker image and then the next thing you do is install

00:10:00.200 --> 00:10:03.140
your, you know, pip install your dependencies inside of your Docker.

00:10:03.140 --> 00:10:04.260
That's a true download, right?

00:10:04.260 --> 00:10:05.940
Because that machine is totally fresh.

00:10:05.940 --> 00:10:06.300
Yeah.

00:10:06.300 --> 00:10:07.040
Yeah.

00:10:07.040 --> 00:10:08.300
So it's, it's hard to tell.

00:10:08.300 --> 00:10:08.660
Yeah.

00:10:08.660 --> 00:10:09.340
I don't know.

00:10:09.340 --> 00:10:11.520
Do you have any feel for what that breakdown is?

00:10:11.520 --> 00:10:12.840
To be honest, I'm not sure.

00:10:12.840 --> 00:10:15.060
That site doesn't give you the breakdown.

00:10:15.060 --> 00:10:20.120
To be honest, what I would be interested in is how many developers typed pip install rich

00:10:20.120 --> 00:10:22.260
in that month.

00:10:22.260 --> 00:10:24.360
You know, how many human beings played with it.

00:10:24.360 --> 00:10:25.520
That would interest me more.

00:10:26.160 --> 00:10:29.720
But suffice to say, quite a lot of people have used it.

00:10:29.720 --> 00:10:30.280
It is quite a lot.

00:10:30.280 --> 00:10:30.780
Downloading it.

00:10:30.780 --> 00:10:31.080
Yeah.

00:10:31.080 --> 00:10:31.400
Yeah.

00:10:31.400 --> 00:10:35.620
I'm sure it's changed the way that you think about working on the library and whatnot.

00:10:35.620 --> 00:10:36.160
Right.

00:10:36.160 --> 00:10:39.400
You know, it's, oh, maybe this might, might destable it.

00:10:39.400 --> 00:10:41.580
This might cause a problem or this might cause confusion.

00:10:41.580 --> 00:10:43.820
It's one thing to do that for a thousand people.

00:10:43.820 --> 00:10:45.520
It's another to do that for two million.

00:10:45.520 --> 00:10:47.060
That's right.

00:10:47.060 --> 00:10:47.700
Right.

00:10:47.700 --> 00:10:48.380
It's, I am.

00:10:48.380 --> 00:10:49.820
You're going to hear about it, I bet.

00:10:49.820 --> 00:10:50.400
Absolutely.

00:10:50.400 --> 00:10:53.820
I didn't follow Semver very strictly originally.

00:10:54.100 --> 00:10:58.720
I always plan to use Semver and people are starting to use it.

00:10:58.720 --> 00:11:00.780
And I made, I made a breaking change.

00:11:00.780 --> 00:11:03.340
And I didn't think anyone was using this particular feature.

00:11:03.340 --> 00:11:06.520
So I didn't increase the major version number.

00:11:06.520 --> 00:11:10.960
And then a couple of days later, I got an issue, someone telling me off.

00:11:10.960 --> 00:11:12.680
Quite rightly so.

00:11:12.680 --> 00:11:13.360
Oh man.

00:11:13.360 --> 00:11:15.280
For not warning them about a breaking feature.

00:11:15.280 --> 00:11:17.900
So since then, I've been very, very strict.

00:11:17.900 --> 00:11:19.460
It's a version 10.

00:11:19.460 --> 00:11:24.020
And that's because I've made 10 changes, breaking changes to the API.

00:11:24.300 --> 00:11:25.260
They're actually quite small.

00:11:25.260 --> 00:11:30.980
You know, it might just be one signature and one method, but that requires a major version

00:11:30.980 --> 00:11:31.460
change.

00:11:31.460 --> 00:11:31.760
Right.

00:11:31.760 --> 00:11:34.860
But at that scale, obviously, that's still going to affect it.

00:11:34.860 --> 00:11:37.120
That people, you're going to hear about it and whatnot, right?

00:11:37.120 --> 00:11:37.480
Exactly.

00:11:37.480 --> 00:11:39.000
I don't want to break anyone's code.

00:11:39.000 --> 00:11:40.260
I don't want to give them a bad day.

00:11:40.260 --> 00:11:42.820
So I'm very strict about that kind of thing.

00:11:42.820 --> 00:11:43.240
Yeah.

00:11:43.240 --> 00:11:43.720
Fantastic.

00:11:43.980 --> 00:11:46.680
And also people should pin their versions, right?

00:11:46.680 --> 00:11:53.800
So on the flip side, they can also make sure that what they're working on is nice and stable,

00:11:53.800 --> 00:11:54.020
right?

00:11:54.020 --> 00:11:54.360
Yeah.

00:11:54.360 --> 00:11:55.360
A lot of people don't.

00:11:55.360 --> 00:11:59.680
I do search GitHub sometimes for rich and I look at their PyTummel.

00:11:59.680 --> 00:12:00.060
What is it?

00:12:00.060 --> 00:12:01.320
PyProjectTummel.

00:12:01.320 --> 00:12:02.120
Yeah.

00:12:02.120 --> 00:12:02.520
PyProjectTummel.

00:12:02.520 --> 00:12:02.660
Yeah.

00:12:03.220 --> 00:12:06.840
And a lot of people don't pin their rich version.

00:12:06.840 --> 00:12:10.280
They'll just be rich and it shouldn't break too much.

00:12:10.280 --> 00:12:13.380
And often it's a hobby project, so it's not the biggest deal.

00:12:13.380 --> 00:12:13.640
Right.

00:12:13.640 --> 00:12:14.800
It really depends.

00:12:14.800 --> 00:12:16.460
Like it's one of the things I struggle with.

00:12:16.460 --> 00:12:18.660
So I do a lot of course development, right?

00:12:18.660 --> 00:12:23.220
And I don't necessarily want to pin people to the oldest version.

00:12:23.220 --> 00:12:27.480
I'd rather let them have the newest stuff so it exactly matches the documentation.

00:12:27.480 --> 00:12:30.880
If they go check it these days and stuff, if they go back, you know, six months and watch

00:12:30.880 --> 00:12:33.400
the video or check out the demo app.

00:12:33.400 --> 00:12:35.960
But at the same time, there's a chance of that instability.

00:12:35.960 --> 00:12:37.220
There's always this tension, right?

00:12:37.220 --> 00:12:41.380
And I guess it depends on what the use case of that app or that library is.

00:12:41.380 --> 00:12:41.720
Yeah.

00:12:41.720 --> 00:12:42.240
Yeah.

00:12:42.240 --> 00:12:43.340
It's tricky to say.

00:12:43.340 --> 00:12:48.520
The less critical it is for your business or your project, the more you can relax.

00:12:48.520 --> 00:12:51.560
If it's a tutorial, maybe it doesn't matter quite so much.

00:12:51.560 --> 00:12:55.520
But if it's critical infrastructure, then you want to pin.

00:12:55.520 --> 00:12:57.460
Yeah.

00:12:57.460 --> 00:12:58.060
Yeah.

00:12:58.060 --> 00:13:00.360
For my web apps, versions are pinned.

00:13:00.360 --> 00:13:01.300
Super strict.

00:13:01.300 --> 00:13:05.180
Even the dependencies of the dependencies, like the transitive closure of the dependencies

00:13:05.180 --> 00:13:05.860
are all pinned.

00:13:05.860 --> 00:13:06.120
Yeah.

00:13:06.120 --> 00:13:07.880
On like little demo apps and stuff.

00:13:07.880 --> 00:13:09.040
Like it's just wide open.

00:13:09.040 --> 00:13:10.760
So I think it depends.

00:13:10.760 --> 00:13:11.160
All right.

00:13:11.160 --> 00:13:15.120
So out in the audience, we have Hybotics says, Will, this looks really good to me.

00:13:15.120 --> 00:13:16.020
I'm looking at repo now.

00:13:16.020 --> 00:13:19.560
So not everyone has previously heard of Rich, which is awesome.

00:13:19.560 --> 00:13:22.820
Oh, it's good to know there's a few people left.

00:13:25.000 --> 00:13:25.560
That's right.

00:13:25.560 --> 00:13:25.800
Yeah.

00:13:25.800 --> 00:13:28.480
I suspect there's actually a lot of people.

00:13:28.480 --> 00:13:30.380
So who haven't heard it before.

00:13:30.380 --> 00:13:36.000
Again, check out the screenshots because if you think, oh, here's something that sort of

00:13:36.000 --> 00:13:41.840
enhances terminal output that completely undersells the level of what you've pulled off here.

00:13:41.840 --> 00:13:44.560
And that's only before we even talk about textual, right?

00:13:44.700 --> 00:13:50.120
Let's talk about compatibility because one of the things I find with these sort of nicer

00:13:50.120 --> 00:13:54.220
terminal output things is like, this works fantastic on POSIX systems.

00:13:54.220 --> 00:13:55.700
Oh, but you better not be on Windows.

00:13:55.700 --> 00:14:00.000
Or if you're a data scientist, you like Jupyter Notebooks, you can forget about it.

00:14:00.000 --> 00:14:02.700
But if you really want to run this thing, like, so what's the story?

00:14:02.700 --> 00:14:03.580
Like, where can I use this?

00:14:03.580 --> 00:14:04.440
Just about everywhere.

00:14:04.440 --> 00:14:07.160
Linux, OSX, Windows, and Jupyter.

00:14:07.740 --> 00:14:13.280
It started out, it was Linux OSX because that is the easiest platform to develop this kind

00:14:13.280 --> 00:14:13.900
of stuff for.

00:14:13.900 --> 00:14:15.660
Windows is a bit of a black sheep.

00:14:15.660 --> 00:14:18.520
It didn't quite work as is.

00:14:18.520 --> 00:14:20.240
Windows is getting better though, right?

00:14:20.240 --> 00:14:24.180
I mean, when it was cmd.exe, it was like, oh boy, this is really different.

00:14:24.180 --> 00:14:27.080
But the new Windows terminal, I'm really digging it.

00:14:27.080 --> 00:14:30.740
You know, the new PowerShell, the things like, oh, my Posh extensions.

00:14:30.740 --> 00:14:34.040
I can feel much more at home on Windows on the terminal than I used to.

00:14:34.040 --> 00:14:34.800
Yeah, yeah.

00:14:34.800 --> 00:14:36.980
So the new Windows terminal is much better.

00:14:36.980 --> 00:14:43.300
Rich doesn't have to do quite so many, doesn't have to jump so many hoops to get Windows support.

00:14:43.300 --> 00:14:46.400
In fact, it just runs kind of as is.

00:14:46.400 --> 00:14:51.020
It still supports the older Windows terminal, which does have a few issues.

00:14:51.020 --> 00:14:53.280
It doesn't, it has very limited colors.

00:14:53.280 --> 00:14:54.020
That's brave.

00:14:54.020 --> 00:14:54.380
Yeah.

00:14:54.380 --> 00:14:56.200
But I guess maybe you want to, right?

00:14:56.200 --> 00:15:01.320
If you're going to give the app to somebody, you can't really package up the terminal they're going to run it in.

00:15:01.320 --> 00:15:04.100
So you probably want to have your best possible experience on.

00:15:04.100 --> 00:15:08.380
To be honest, most people are still going to be running cmd.exe, even if they shouldn't.

00:15:08.380 --> 00:15:09.500
Yeah, exactly.

00:15:09.500 --> 00:15:09.920
Yeah.

00:15:09.920 --> 00:15:15.280
I mean, I could just tell them to install Windows terminal, but that kind of goes against the ethos of this library.

00:15:15.280 --> 00:15:19.700
I just want it to work so that people don't have to think about what it runs on.

00:15:19.700 --> 00:15:19.960
Yeah.

00:15:19.960 --> 00:15:21.240
Put a lot of work initially into.

00:15:21.240 --> 00:15:30.800
Yeah, so Linux, macOS, and Windows with good support for the new Windows terminal, very limited support for the old command prompt.

00:15:30.800 --> 00:15:31.860
That's still pretty good.

00:15:31.860 --> 00:15:32.620
That's still pretty good.

00:15:32.620 --> 00:15:34.080
I think it's fantastic, actually.

00:15:34.080 --> 00:15:39.340
If people are really passionate about their terminal and they're on Windows, they probably know about Windows terminal anyway.

00:15:39.340 --> 00:15:40.460
So they're probably good.

00:15:40.460 --> 00:15:40.660
That's true.

00:15:40.660 --> 00:15:41.300
Yeah.

00:15:41.300 --> 00:15:44.800
The one that I thought was interesting and nice is Jupyter Notebooks.

00:15:44.800 --> 00:15:46.260
What's the support there?

00:15:46.260 --> 00:15:49.180
So it works quite, quite well.

00:15:49.180 --> 00:15:52.760
So I wasn't a big Jupyter user at the time.

00:15:52.760 --> 00:15:55.400
I was obviously aware of it, but I didn't use it myself.

00:15:55.400 --> 00:15:58.360
And people asked me for Jupyter support.

00:15:58.360 --> 00:16:00.000
And I thought, it doesn't do that.

00:16:00.000 --> 00:16:00.820
It just works in the terminal.

00:16:00.820 --> 00:16:01.980
But then I looked into it.

00:16:01.980 --> 00:16:08.000
And it wasn't too bad because I already had functionality to export terminal content to HTML.

00:16:08.520 --> 00:16:14.580
So I could put a little wrapper around that, export it to HTML, and then insert it into Jupyter.

00:16:14.580 --> 00:16:18.320
They've got an API which allows you to write content into a notebook.

00:16:18.320 --> 00:16:22.540
And so I got Jupyter support up quite quickly, quite easily.

00:16:22.540 --> 00:16:25.720
And it works quite nicely, which people appreciate.

00:16:25.720 --> 00:16:29.780
It means that you can write code which writes to terminal mostly.

00:16:29.780 --> 00:16:34.180
But if you do happen to run it in a Jupyter notebook, then it'll write the same thing there as well.

00:16:34.180 --> 00:16:38.240
It just knows, it detects that it's running in the Jupyter environment.

00:16:38.240 --> 00:16:40.280
And then it just, all right, output is not print.

00:16:40.280 --> 00:16:41.780
Output is generate HTML.

00:16:41.780 --> 00:16:42.740
Exactly, yeah.

00:16:42.740 --> 00:16:45.040
And Jupyter does have support for that.

00:16:45.040 --> 00:16:49.200
It will capture standard output and it will convert the colors and everything.

00:16:49.820 --> 00:16:52.700
But the problem is it wrapped the lines.

00:16:52.700 --> 00:16:56.240
So if you expanded the window, it would break any kind of neat formatting.

00:16:56.240 --> 00:16:59.400
If you've got like a grid or a table, it would break that.

00:16:59.400 --> 00:17:03.720
So I had to do the HTML export within Rich as well.

00:17:03.720 --> 00:17:04.020
Yeah.

00:17:04.020 --> 00:17:11.200
Basically, most anywhere people do Python with a UI of some sort, this works is the takeaway.

00:17:11.200 --> 00:17:11.620
Yeah.

00:17:11.620 --> 00:17:18.760
This portion of Talk Python To Me is brought to you by Shortcut, formerly known as Clubhouse.io.

00:17:18.920 --> 00:17:20.640
Happy with your project management tool?

00:17:20.640 --> 00:17:24.920
Most tools are either too simple for a growing engineering team to manage everything,

00:17:24.920 --> 00:17:29.000
or way too complex for anyone to want to use them without constant prodding.

00:17:29.000 --> 00:17:31.940
Shortcut is different though, because it's worse.

00:17:31.940 --> 00:17:33.380
No, wait, no, I mean it's better.

00:17:33.380 --> 00:17:37.140
Shortcut is project management built specifically for software teams.

00:17:37.140 --> 00:17:41.900
It's fast, intuitive, flexible, powerful, and many other nice, positive adjectives.

00:17:41.900 --> 00:17:44.520
Key features include team-based workflows.

00:17:44.520 --> 00:17:48.900
Individual teams can use default workflows or customize them to match the

00:17:48.900 --> 00:17:49.560
the way they work.

00:17:49.560 --> 00:17:51.620
Org-wide goals and roadmaps.

00:17:51.620 --> 00:17:55.720
The work in these workflows is automatically tied into larger company goals.

00:17:55.720 --> 00:18:01.320
It takes one click to move from a roadmap to a team's work to individual updates and back.

00:18:01.320 --> 00:18:03.180
Tight version control integration.

00:18:03.180 --> 00:18:07.660
Whether you use GitHub, GitLab, or Bitbucket, Clubhouse ties directly into them,

00:18:07.660 --> 00:18:10.040
so you can update progress from the command line.

00:18:10.040 --> 00:18:11.800
Keyboard-friendly interface.

00:18:11.980 --> 00:18:16.820
The rest of Shortcut is just as friendly as their power bar, allowing you to do virtually

00:18:16.820 --> 00:18:18.740
anything without touching your mouse.

00:18:18.740 --> 00:18:20.000
Throw that thing in the trash.

00:18:20.000 --> 00:18:21.580
Iteration planning.

00:18:21.580 --> 00:18:26.580
Set weekly priorities and let Shortcut run the schedule for you with accompanying burndown

00:18:26.580 --> 00:18:27.740
charts and other reporting.

00:18:27.740 --> 00:18:32.580
Give it a try over at talkpython.fm/shortcut.

00:18:32.800 --> 00:18:36.140
Again, that's talkpython.fm/shortcut.

00:18:36.140 --> 00:18:40.740
Choose shortcut because you shouldn't have to project manage your project management.

00:18:42.740 --> 00:18:47.340
Just going back to the pip-pinning version stuff, Wayland on the livestream says pip-compile.

00:18:47.340 --> 00:18:52.680
Pip-tools is a game changer for pin dependencies and pip-compile specifically for managing pin

00:18:52.680 --> 00:18:53.560
dependencies.

00:18:53.560 --> 00:18:54.700
That's what I've switched to as well.

00:18:54.700 --> 00:18:59.040
So I just run a script, checks for all the new versions, regenerates all the pip-compiled

00:18:59.040 --> 00:18:59.640
stuff.

00:18:59.640 --> 00:19:01.180
And I'm really enjoying that.

00:19:01.180 --> 00:19:01.940
I think that's fantastic.

00:19:01.940 --> 00:19:02.260
Okay.

00:19:02.260 --> 00:19:03.260
I've not used pip-compile.

00:19:03.260 --> 00:19:03.980
I'll have to check that out.

00:19:03.980 --> 00:19:04.280
All right.

00:19:04.280 --> 00:19:11.440
You basically define a requirements file that has what you actually would have pip-typed,

00:19:11.440 --> 00:19:17.040
pip install, and then it will generate a requirements.txt that is the transitive closure of all of

00:19:17.040 --> 00:19:18.420
those dependencies, which are pinned.

00:19:18.420 --> 00:19:22.560
And then you can ask any time for it to update the versions, the pinned versions of that.

00:19:22.560 --> 00:19:22.900
Okay.

00:19:22.900 --> 00:19:25.880
Is that like Poetry's log files?

00:19:25.880 --> 00:19:27.100
I think it's similar.

00:19:27.100 --> 00:19:27.380
Yeah.

00:19:27.380 --> 00:19:29.220
I'm not 100% sure, but I think so.

00:19:29.220 --> 00:19:29.760
All right.

00:19:29.760 --> 00:19:32.700
So let's talk about various features here.

00:19:32.700 --> 00:19:36.360
I think just going through, I mean, we touched on them, but let's dive into it a little bit,

00:19:36.360 --> 00:19:38.160
maybe talk a little bit about the code you write.

00:19:38.160 --> 00:19:38.320
Sure.

00:19:38.520 --> 00:19:41.540
So Kim Van Wake is here to kick us off on the first one.

00:19:41.540 --> 00:19:46.120
Try something as simple as from rich import print in your next project, and you will be

00:19:46.120 --> 00:19:46.620
amazed.

00:19:46.620 --> 00:19:50.800
So Will, tell us why we'll be amazed.

00:19:50.800 --> 00:19:52.980
Like what's this alternate print?

00:19:52.980 --> 00:19:57.660
When I first wrote this as a console class, you have to construct a class and that's got

00:19:57.660 --> 00:19:58.680
a print method.

00:19:59.240 --> 00:20:04.900
But I figured I could just overwrite the existing, the built-in print because it's a, it's a function

00:20:04.900 --> 00:20:05.980
in Python three.

00:20:05.980 --> 00:20:07.820
I can just replace it with my own version.

00:20:07.820 --> 00:20:09.480
So that's what I've done here.

00:20:09.480 --> 00:20:13.440
I'll give, there's a version of print that you can import from rich, which has the same

00:20:13.440 --> 00:20:18.500
signature as a built-in print, but it supports the console markup.

00:20:18.620 --> 00:20:24.100
So you can insert these little square brackets with a style like, here we've got bold magenta

00:20:24.100 --> 00:20:28.280
and it'll do emojis, colon, vampire, colon.

00:20:28.280 --> 00:20:34.560
And these styles, like the square bracket, bold magenta slash bold magenta, this is specific

00:20:34.560 --> 00:20:35.140
to rich.

00:20:35.140 --> 00:20:37.180
This is something that you came up with.

00:20:37.260 --> 00:20:38.080
Yeah, that's right.

00:20:38.080 --> 00:20:42.560
It's called, I call it console markup and the syntax is very BB code like.

00:20:42.560 --> 00:20:44.680
I don't know if you ever used BB code.

00:20:44.680 --> 00:20:45.400
Yeah.

00:20:45.400 --> 00:20:46.240
It's quite simple.

00:20:46.240 --> 00:20:50.560
It's just like a markup where the tags have square brackets.

00:20:50.560 --> 00:20:51.020
Yeah.

00:20:51.020 --> 00:20:56.160
I like this a lot because one of the things that I'll use a lot still is, which maybe I

00:20:56.160 --> 00:20:58.960
need to start switching to what you're doing here, is Colorama.

00:20:58.960 --> 00:21:06.360
But for Colorama, you'll do things like you'll import the foreground settings or styles and then

00:21:06.360 --> 00:21:10.840
you can say foreground dot green plus the text.

00:21:10.840 --> 00:21:11.400
Yeah.

00:21:11.400 --> 00:21:15.320
Foreground reset to go back to normal, but you don't have the bold.

00:21:15.320 --> 00:21:18.260
And then all of that stuff has to happen in code, right?

00:21:18.260 --> 00:21:22.700
If I wanted to say import some text and then show it on the screen, that text could have

00:21:22.700 --> 00:21:24.360
these styles in it, right?

00:21:24.360 --> 00:21:24.800
That's right.

00:21:24.800 --> 00:21:25.020
Yeah.

00:21:25.020 --> 00:21:29.520
So you can embed it in code easier or read it from a file, et cetera.

00:21:29.520 --> 00:21:33.800
I think it's a bit easier to read rather than doing lots of string concatenations.

00:21:34.180 --> 00:21:36.640
And also the benefit over the Colorama approach.

00:21:36.640 --> 00:21:38.500
Colorama is a very good bit of software.

00:21:38.500 --> 00:21:40.080
I've relied on it for years.

00:21:40.080 --> 00:21:45.240
But the problem is when you concatenate strings like that, you insert these ANSI codes.

00:21:45.240 --> 00:21:47.880
Once you've built that string, you can't do anything with it really.

00:21:47.880 --> 00:21:49.340
You can't word wrap it.

00:21:49.340 --> 00:21:50.820
You can't format it.

00:21:50.820 --> 00:21:52.960
So with console markup, you can do.

00:21:52.960 --> 00:21:55.960
You can markup bits of text with color and style, et cetera.

00:21:55.960 --> 00:22:02.260
And then you can further do operations on them like word wrap and centering text and putting

00:22:02.260 --> 00:22:03.260
it inside the table, et cetera.

00:22:03.260 --> 00:22:03.600
Right.

00:22:03.600 --> 00:22:07.920
Two other things that jump out here that are interesting is you have emoji support.

00:22:07.920 --> 00:22:12.220
So you can say colon vampire colon, which is pretty awesome.

00:22:12.860 --> 00:22:19.080
You can technically, if the file format supports it, you could actually put a vampire emoji

00:22:19.080 --> 00:22:19.960
in the string.

00:22:19.960 --> 00:22:20.540
Yeah.

00:22:20.540 --> 00:22:23.740
But it's still kind of nice that you have this sort of emoji lookup, right?

00:22:23.740 --> 00:22:24.140
Exactly.

00:22:24.140 --> 00:22:28.900
Because if you want to insert the Unicode character, you'd have to go and find it and then cut and

00:22:28.900 --> 00:22:29.360
paste it.

00:22:29.360 --> 00:22:29.680
Yeah.

00:22:29.720 --> 00:22:30.920
You can just do colon.

00:22:30.920 --> 00:22:36.260
You can set that into console markup, just colon vampire colon or colon smiley colon.

00:22:36.260 --> 00:22:38.960
I think there's a couple of thousand emojis you can use there now.

00:22:38.960 --> 00:22:39.400
Fantastic.

00:22:39.400 --> 00:22:45.380
Then another thing that jumps out is you're printing hello, bold magenta world.

00:22:45.380 --> 00:22:48.300
So that's the word world, bold and magenta.

00:22:48.300 --> 00:22:49.460
And then the vampire.

00:22:49.460 --> 00:22:51.820
But then you're also printing out a dictionary.

00:22:51.820 --> 00:22:57.620
And the dictionary is like pretty printed, but also syntax highlighted.

00:22:57.620 --> 00:23:04.000
So if you print a container, like a dictionary, a list, or like an atomic Python type, it'll

00:23:04.000 --> 00:23:05.760
run the pretty printer over it.

00:23:05.760 --> 00:23:09.280
So it will format it in kind of the style that people like.

00:23:09.280 --> 00:23:11.560
In code, you'd probably format.

00:23:11.560 --> 00:23:13.520
This is how black would format it.

00:23:13.520 --> 00:23:15.020
So it looks much the same.

00:23:15.020 --> 00:23:18.620
Then it runs the syntax highlighting over it.

00:23:18.620 --> 00:23:19.860
There's a few regular expressions.

00:23:19.860 --> 00:23:25.620
So in which you can say anything between two quotes is a string and therefore it's green.

00:23:25.620 --> 00:23:29.220
Anything in angle of brackets is a tag-like thing.

00:23:29.220 --> 00:23:35.260
So I'll bold the brackets and change the tag name to bright red or whatever it is.

00:23:35.260 --> 00:23:41.920
And so that the output you get is quite readable and looks like something that came out of VS Code or your editor.

00:23:42.680 --> 00:23:43.120
Yeah.

00:23:43.120 --> 00:23:49.380
The more I look at this, the more I think maybe just every project, I'm going to follow Kim's advice and just from rich import print.

00:23:49.380 --> 00:23:50.840
Because why not?

00:23:50.840 --> 00:23:53.500
This looks, it has all this cool auto formatting.

00:23:53.500 --> 00:23:58.320
Does it look actually at the type that it's printing to make any determination?

00:23:58.320 --> 00:24:01.720
Or does it just look and see if it's source code and then try to format it?

00:24:01.720 --> 00:24:03.200
It looks at the type.

00:24:03.400 --> 00:24:07.440
Like if it gets a dictionary or it gets an object versus getting it like a true string.

00:24:07.440 --> 00:24:08.120
It'll do both.

00:24:08.120 --> 00:24:10.120
It'll syntax highlight a string.

00:24:10.120 --> 00:24:15.640
But if it's a container, if it knows that the type, it'll do some syntax highlighting there.

00:24:15.640 --> 00:24:23.080
There's also a simple protocol you can add to your own objects if you want them pretty printed and formatted.

00:24:23.280 --> 00:24:23.700
Oh, okay.

00:24:23.700 --> 00:24:27.860
But not dunder stir, dunder repper, but something else.

00:24:27.860 --> 00:24:28.700
Dunder rich.

00:24:28.700 --> 00:24:30.500
It is dunder rich repper.

00:24:30.500 --> 00:24:30.980
Right.

00:24:30.980 --> 00:24:36.180
You can specify the arguments and parameters and the indentation.

00:24:36.180 --> 00:24:39.940
It'll render something that's very much like a pretty printed dict.

00:24:39.940 --> 00:24:44.640
That sounds like something that would be fantastic to add to some intermediate library that people use.

00:24:44.640 --> 00:24:47.380
So I, sure, I could create a class and add it to mine.

00:24:47.380 --> 00:24:53.400
But so often what I want to do is print out a MongoEngine model or a SQLAlchemy model or a Pydantic model.

00:24:53.400 --> 00:24:53.700
Yeah.

00:24:53.700 --> 00:24:54.780
Pydantic could add that.

00:24:54.780 --> 00:24:55.560
Or, you know what I mean?

00:24:55.560 --> 00:24:58.460
Like these like intermediate SQLAlchemy could add something like that.

00:24:58.460 --> 00:25:00.420
Oh, this is how you describe.

00:25:00.420 --> 00:25:02.300
Like this one has an index and whatnot.

00:25:02.300 --> 00:25:03.320
I think that'd be fantastic.

00:25:03.320 --> 00:25:03.560
Yeah.

00:25:03.560 --> 00:25:05.540
So I've added to Attrs.

00:25:05.540 --> 00:25:08.580
So it'll pretty print objects from the Attrs library.

00:25:08.580 --> 00:25:11.800
I have a PR for Pydantic as well.

00:25:11.800 --> 00:25:18.240
So hopefully in the future, you print a Pydantic object and it will format it quite similar to the built-in data structures.

00:25:18.240 --> 00:25:18.540
Yeah.

00:25:18.540 --> 00:25:19.180
Okay.

00:25:19.180 --> 00:25:19.780
Fantastic.

00:25:19.780 --> 00:25:20.340
I love it.

00:25:20.340 --> 00:25:25.000
Before we move on to this, I do want to talk about some other things because we're just scratching the surface here.

00:25:25.000 --> 00:25:31.720
But one of the things that I think has both impressed me and, you know, Brian and I over on Python Bytes on our podcast we do there,

00:25:31.720 --> 00:25:39.800
we've been continuously impressed at how fast you're adding new features and still kind of keeping the ethos of this library together.

00:25:40.040 --> 00:25:44.060
So how, maybe give people a little hint on just the velocity here.

00:25:44.060 --> 00:25:44.880
Like how's that work?

00:25:44.880 --> 00:25:47.600
Well, I'm not convinced that it's been that fast.

00:25:47.600 --> 00:25:49.080
I mean, bear in mind Rich is...

00:25:49.080 --> 00:25:50.140
It felt like a lot of work.

00:25:50.140 --> 00:25:51.040
It didn't feel that fast.

00:25:51.040 --> 00:25:55.880
When I add new stuff to Rich, I'm not starting from scratch.

00:25:55.880 --> 00:26:00.260
There's several layers which are already built and well tested.

00:26:00.260 --> 00:26:04.540
The bit that I add might not be as large as it, maybe it looks.

00:26:04.540 --> 00:26:05.040
I see.

00:26:05.040 --> 00:26:09.940
So you've already got a lot of structure and architecture that makes adding a new feature...

00:26:09.940 --> 00:26:10.340
Yeah.

00:26:10.340 --> 00:26:11.640
...from scratch sort of thing, right?

00:26:11.640 --> 00:26:12.780
So a good design basically.

00:26:12.780 --> 00:26:13.480
I hope so, yeah.

00:26:13.480 --> 00:26:20.760
And it seems to be working quite well because, you know, I did build a core feature set and then I added some things to it.

00:26:20.760 --> 00:26:24.920
And admittedly, those things came quite fast because it wasn't that hard to implement.

00:26:24.920 --> 00:26:28.880
And I've got to a point now where Rich is quite large.

00:26:29.140 --> 00:26:36.400
I'd be resistant to adding any more stuff to it unless it is very useful for like a broad selection of users.

00:26:36.400 --> 00:26:36.820
Sure.

00:26:36.820 --> 00:26:38.960
Do you have a sense of how many lines of code it is?

00:26:38.960 --> 00:26:40.420
I know you don't mean large in that sense.

00:26:40.420 --> 00:26:41.660
You mean large in sort of feature set.

00:26:41.660 --> 00:26:43.360
But do you have a sense of how many lines of code?

00:26:43.360 --> 00:26:43.980
You know what?

00:26:43.980 --> 00:26:44.600
I've never checked.

00:26:44.600 --> 00:26:46.780
I couldn't guess.

00:26:46.780 --> 00:26:52.660
By the time we're done with this recording, someone out in the audience will have like already downloaded and checked for us.

00:26:52.660 --> 00:26:53.000
Who knows?

00:26:53.000 --> 00:26:53.760
Probably.

00:26:53.760 --> 00:26:53.920
All right.

00:26:53.920 --> 00:26:56.340
So the next thing let's talk about is the REPL.

00:26:56.340 --> 00:27:02.880
So I can create a REPL redevelop print loop by typing the word Python on the terminal.

00:27:02.880 --> 00:27:04.160
And that opens it up.

00:27:04.160 --> 00:27:05.740
But it looks just...

00:27:05.740 --> 00:27:09.860
It's probably the least possibly good experiences you can have in Python, right?

00:27:09.900 --> 00:27:11.100
There's no color.

00:27:11.100 --> 00:27:14.800
There's no feedback on sort of what's happening, right?

00:27:14.800 --> 00:27:18.940
But then I can say from rich import pretty, pretty.install.

00:27:18.940 --> 00:27:26.760
And then all of a sudden, basically the output of the REPL, like if I'd set a variable name, it'll print it out.

00:27:26.760 --> 00:27:28.960
Like that becomes rich printed, right?

00:27:28.960 --> 00:27:30.020
That's right.

00:27:30.020 --> 00:27:30.220
Yeah.

00:27:30.220 --> 00:27:30.820
Yeah.

00:27:30.820 --> 00:27:33.620
So yeah, you call pretty.install.

00:27:33.620 --> 00:27:36.380
And then everything you put into the...

00:27:36.380 --> 00:27:38.360
After the prompt will be pretty printed.

00:27:38.740 --> 00:27:45.580
So previously, if you print a dict without rich, it'll just smash it onto a few lines.

00:27:45.580 --> 00:27:47.880
It's quite hard to visually parse.

00:27:47.880 --> 00:27:51.640
It's all one line except for the word wrapping, which doesn't even break on words.

00:27:51.640 --> 00:27:53.720
And there's zero color, right?

00:27:53.720 --> 00:27:54.380
Yeah.

00:27:54.380 --> 00:27:55.160
Exactly.

00:27:55.160 --> 00:27:57.160
So it's quite difficult to read.

00:27:57.160 --> 00:28:00.700
I'm quite a visual person, so I always had difficulty with this.

00:28:00.700 --> 00:28:05.260
If it was more than two lines, it'd be quite difficult for me to figure out where the keys and the values are.

00:28:05.260 --> 00:28:12.420
But if you do it with rich, it'll pretty print it onto lines and it'll indent it like you would code and then it'll highlight it.

00:28:12.480 --> 00:28:14.460
So it makes things just much more readable.

00:28:14.460 --> 00:28:14.960
Yeah.

00:28:14.960 --> 00:28:18.940
A lot of people will put it in their startup file, so they just get this ripple by default.

00:28:18.940 --> 00:28:19.620
Oh, interesting.

00:28:19.620 --> 00:28:20.780
Yeah, that's a good idea.

00:28:20.780 --> 00:28:31.000
Have you tried this on the more advanced repls like PT Python or BT Python or those where you kind of get an Emacs E or Vim experience?

00:28:31.160 --> 00:28:31.600
I haven't.

00:28:31.600 --> 00:28:37.280
No, I've tried it on IPython and it works quite nicely on IPython, but I haven't tried it on other repls.

00:28:37.280 --> 00:28:40.340
Yeah, it probably works on PT Python, but I haven't tried it.

00:28:40.340 --> 00:28:40.900
Cool.

00:28:40.900 --> 00:28:41.640
All right.

00:28:41.640 --> 00:28:47.640
Now, another thing that you can do a lot with is sort of taking it up to the next level is the console.

00:28:47.640 --> 00:28:48.460
Tell us about this.

00:28:48.460 --> 00:28:53.760
Yeah, so the console class gives you more kind of advanced features.

00:28:53.760 --> 00:28:55.920
There's more options, more things to specify.

00:28:56.580 --> 00:28:59.460
Typically, you'd have a single console per project.

00:28:59.460 --> 00:29:03.540
You'd keep it in your top level object or as a global.

00:29:03.540 --> 00:29:12.900
It has a print method and there's also some other methods like there's a log method and there's a whole bunch of features you can do when you construct the console.

00:29:12.900 --> 00:29:16.040
Things like exporting the output to HTML.

00:29:16.040 --> 00:29:16.480
Okay.

00:29:16.480 --> 00:29:17.420
Nice.

00:29:17.420 --> 00:29:18.360
That's fantastic.

00:29:18.360 --> 00:29:18.620
Yeah.

00:29:18.620 --> 00:29:25.420
So one of the things you can do with the console, for example, is you can set a style on console.print and set some styles.

00:29:25.800 --> 00:29:31.780
And then it'll come out in that style as opposed to embedding this console markup into the text itself, right?

00:29:31.780 --> 00:29:32.160
Yeah.

00:29:32.160 --> 00:29:39.160
So sometimes you might not want the console markup, especially if there's going to be square brackets in the output.

00:29:39.160 --> 00:29:40.980
You don't want them to be confused with.

00:29:40.980 --> 00:29:41.240
Right.

00:29:41.240 --> 00:29:51.200
Or even if you're receiving a string and you just need to put it on the screen, but you haven't generated the string or it was generated by some other part of the app.

00:29:51.200 --> 00:29:53.340
Like here's a message I need to log this that I got.

00:29:53.340 --> 00:29:53.740
Exactly.

00:29:53.740 --> 00:29:57.260
You don't want to parse the string to try to put text into it or more text, right?

00:29:57.260 --> 00:29:57.580
Yeah.

00:29:57.580 --> 00:29:58.240
Exactly.

00:29:58.240 --> 00:30:05.700
So you can disable the highlighting and you can still set a style globally for that string if you want it in red or cyan, whatever.

00:30:05.700 --> 00:30:09.440
You can still get that, but you can disable the console markup.

00:30:09.580 --> 00:30:09.780
Nice.

00:30:09.780 --> 00:30:13.440
And then we have the inspect, rich inspect.

00:30:13.440 --> 00:30:14.740
What is this one?

00:30:14.740 --> 00:30:19.980
This is my favorite function in rich and it came quite late.

00:30:19.980 --> 00:30:30.400
But what it does is you call it with any object and it'll inspect the object and it'll pull out doc strings and it'll pull out methods.

00:30:30.400 --> 00:30:35.420
And then it'll render it in quite a nice little table that's quite easy to read.

00:30:35.420 --> 00:30:39.680
And I find this terrific for exploring APIs.

00:30:39.680 --> 00:30:42.220
Sometimes it's better than documentation.

00:30:42.220 --> 00:30:46.760
You know, if you get an object back from an API, you don't quite know what methods it supports.

00:30:46.760 --> 00:30:48.680
You just call rich.inspect.

00:30:48.680 --> 00:30:53.460
I could have typed something like dir, my, you know, print dir, my object.

00:30:53.460 --> 00:31:01.220
And I get a list of dictionary objects which are representing, you know, fields and methods and whatnot.

00:31:01.220 --> 00:31:01.860
Exactly.

00:31:01.860 --> 00:31:02.620
But they're all jammed together.

00:31:02.620 --> 00:31:04.140
There's no like help.

00:31:04.140 --> 00:31:05.260
This is fantastic.

00:31:05.260 --> 00:31:11.380
So it's like almost a table version of that with one line of help next to it, right?

00:31:11.380 --> 00:31:11.640
Yeah.

00:31:11.640 --> 00:31:14.660
So it does the same kind of thing as dir or help.

00:31:14.660 --> 00:31:16.060
But way, way nicer, yeah.

00:31:16.060 --> 00:31:17.720
It makes it easier, easier to read.

00:31:17.720 --> 00:31:18.740
There's also two things.

00:31:18.740 --> 00:31:24.500
I see there's a block of stuff that has, it's like a list of, I guess those are field names.

00:31:24.500 --> 00:31:26.080
And then it has the methods.

00:31:26.080 --> 00:31:28.300
It's sort of called out separately as well.

00:31:28.300 --> 00:31:31.320
So you're like, these are the fields or properties or these are the fields.

00:31:31.320 --> 00:31:33.540
And then here's the probably methods and properties, right?

00:31:33.540 --> 00:31:33.920
That's right.

00:31:33.920 --> 00:31:34.120
Yeah.

00:31:34.120 --> 00:31:40.140
So it basically shows you the signature of all the methods and the first line of the doc string.

00:31:40.140 --> 00:31:42.620
There's an option to show you the full details.

00:31:42.620 --> 00:31:47.620
But I find just that abbreviated information is generally as much as I need.

00:31:47.780 --> 00:31:48.480
Oh, this is fantastic.

00:31:48.740 --> 00:31:52.700
So it says things like copy equals def, copy, bracket, bracket.

00:31:52.700 --> 00:31:55.420
Would it say async def if it was an async method?

00:31:55.420 --> 00:31:58.760
Or what's the alternative of def there?

00:31:58.760 --> 00:31:59.980
Is it just to show it's a method?

00:31:59.980 --> 00:32:01.160
That's just to show it's a method.

00:32:01.160 --> 00:32:02.420
That's a good point about async.

00:32:02.420 --> 00:32:04.660
I don't think it does do async def.

00:32:04.660 --> 00:32:05.840
And that's a good idea.

00:32:06.020 --> 00:32:11.060
It'd be pretty dope to throw in an async def or maybe a property if it's a getter method, right?

00:32:11.060 --> 00:32:11.780
You're right.

00:32:11.780 --> 00:32:12.060
Yeah.

00:32:12.060 --> 00:32:13.380
I think they probably should do that.

00:32:13.380 --> 00:32:17.800
They should inspect the method and see whether it's async and then emphasize that.

00:32:17.800 --> 00:32:18.020
Yeah.

00:32:18.020 --> 00:32:18.640
It's a good idea.

00:32:18.640 --> 00:32:19.660
Yeah, sure.

00:32:19.660 --> 00:32:21.940
We'll open a PR on that podcast here.

00:32:21.940 --> 00:32:22.320
No problem.

00:32:22.320 --> 00:32:23.440
All right.

00:32:23.440 --> 00:32:28.360
So those are ones that you've got like graphics calling them out as some of the really main

00:32:28.360 --> 00:32:28.840
things.

00:32:28.840 --> 00:32:30.100
There's so much happening here.

00:32:30.100 --> 00:32:31.020
That's that's amazing.

00:32:31.020 --> 00:32:36.160
But like Waylon out in the live stream points out like mention rich tracebacks.

00:32:36.160 --> 00:32:37.460
They're so good.

00:32:37.460 --> 00:32:40.060
I have my ipython automatically start up with that.

00:32:40.060 --> 00:32:45.220
And yeah, you've got a whole section down here under the library of things like logging,

00:32:45.220 --> 00:32:50.180
log handlers, progress bars, status, tree views, like crazy.

00:32:50.180 --> 00:32:54.100
You have tree views in the terminal that can expand and collapse with the mouse.

00:32:54.100 --> 00:32:57.400
You know, there's there's more going on here than just the stuff we've touched on.

00:32:57.400 --> 00:32:57.560
Right.

00:32:57.560 --> 00:32:58.700
There's a bunch of cool features.

00:32:58.700 --> 00:32:59.780
There's a lot going on.

00:32:59.780 --> 00:33:00.000
Yeah.

00:33:00.000 --> 00:33:02.480
Well, Rich will render the tree view.

00:33:02.480 --> 00:33:06.840
It's textual, which provides the collapsing and navigation features.

00:33:06.840 --> 00:33:07.100
Yeah.

00:33:07.100 --> 00:33:07.980
Ah, got it.

00:33:07.980 --> 00:33:08.220
Got it.

00:33:08.220 --> 00:33:08.480
Got it.

00:33:08.480 --> 00:33:08.620
Okay.

00:33:08.840 --> 00:33:10.720
So we'll get to the interactive bits.

00:33:10.720 --> 00:33:14.720
But yeah, so I can still draw a tree view even with like little your example here.

00:33:14.720 --> 00:33:17.680
You've got emoji icons for say folders and files.

00:33:17.680 --> 00:33:22.560
And then even in the file, you've got an embedded syntax highlighted bit of code that comes out

00:33:22.560 --> 00:33:27.200
of one of the files and a markdown with some of the markdown rendered as a rich markdown.

00:33:27.200 --> 00:33:27.520
Yeah.

00:33:27.520 --> 00:33:28.380
Just a markdown.

00:33:28.380 --> 00:33:31.740
Like not, not rich the library, but like just colorized and formatted.

00:33:31.740 --> 00:33:32.060
Yeah.

00:33:32.060 --> 00:33:36.080
So it goes back to the composability of rich, rich objects.

00:33:36.080 --> 00:33:40.060
I call them renderables, but you can use them in various contexts.

00:33:40.060 --> 00:33:43.740
So in here, you can set a renderable per node on the tree.

00:33:43.740 --> 00:33:50.400
So you can like do what we've done here, add a table next to a tree item or some syntax highlighting

00:33:50.400 --> 00:33:51.900
or render some markdown.

00:33:51.900 --> 00:33:55.800
It doesn't really matter to rich what you ask it to render.

00:33:55.800 --> 00:33:57.900
You can just do it in various contexts.

00:33:58.060 --> 00:33:58.280
Yeah.

00:33:58.280 --> 00:33:58.800
Very cool.

00:33:58.800 --> 00:33:59.020
Okay.

00:33:59.020 --> 00:34:00.720
So we've got the tree, which is amazing.

00:34:00.720 --> 00:34:03.880
Let's, you know, since Waylon mentioned it, let's talk tracebacks real quick.

00:34:03.880 --> 00:34:10.080
I mean, one of the things that really is tricky with the tracebacks is, you know, a lot of

00:34:10.080 --> 00:34:13.820
times you've got to go to like one end of them to see sort of the error.

00:34:13.820 --> 00:34:15.580
And then like, there's no color.

00:34:15.580 --> 00:34:17.880
There's just a lot of stuff dropping in there.

00:34:18.580 --> 00:34:22.940
Maybe sometimes it'll show the variable values, but they're not really got to kind of pull

00:34:22.940 --> 00:34:23.440
them out.

00:34:23.440 --> 00:34:23.760
Right.

00:34:23.760 --> 00:34:24.400
Things like that.

00:34:24.400 --> 00:34:27.460
And what you get here is, is ridiculous.

00:34:27.460 --> 00:34:30.260
First of all, what do I do to make this happen with the beautiful tracebacks?

00:34:30.260 --> 00:34:34.280
You can do from rich import traceback, traceback.install.

00:34:34.280 --> 00:34:34.820
Oh, good.

00:34:34.820 --> 00:34:35.140
Yeah.

00:34:35.140 --> 00:34:39.240
From then on, if you don't, if you don't handle an exception, it'll be printed with rich

00:34:39.240 --> 00:34:40.740
or you can explicitly.

00:34:40.740 --> 00:34:41.180
All right.

00:34:41.180 --> 00:34:42.200
There's the second thing I got.

00:34:42.200 --> 00:34:43.280
I just put on all my apps.

00:34:43.780 --> 00:34:44.040
Yeah.

00:34:44.040 --> 00:34:46.120
It's a piece of cake to add.

00:34:46.120 --> 00:34:47.560
So yeah, it's easy to do.

00:34:47.560 --> 00:34:47.780
Yeah.

00:34:47.780 --> 00:34:51.900
So tell me what people who are not seeing this necessarily on the screen, like what is this

00:34:51.900 --> 00:34:54.140
alternative traceback style look like here?

00:34:54.140 --> 00:34:54.460
Okay.

00:34:54.460 --> 00:34:59.220
So it actually follows much the same format as a regular Python traceback.

00:34:59.220 --> 00:35:05.560
It's just underneath the file, you'll see some syntax highlighted code showing you that

00:35:05.560 --> 00:35:11.640
the line where the exception happened for each frame and underneath each block of code,

00:35:11.700 --> 00:35:14.840
it'll show you the locals at that point in the frame.

00:35:14.840 --> 00:35:16.180
So you can see the local variables.

00:35:16.180 --> 00:35:16.540
Right.

00:35:16.540 --> 00:35:20.580
And these are called out in a nice table with a nice formatting that we've already talked

00:35:20.580 --> 00:35:20.760
about.

00:35:20.760 --> 00:35:25.260
So kind of as if you had done print, you know, from rich import print and then printed out

00:35:25.260 --> 00:35:26.500
the locals into a table.

00:35:26.500 --> 00:35:26.900
Yeah.

00:35:26.900 --> 00:35:28.340
And it's all, it's all pretty printed.

00:35:28.340 --> 00:35:29.680
So it's quite easy to read.

00:35:29.680 --> 00:35:35.780
I find with regular Python tracebacks is it, it takes quite a bit of skill to read them.

00:35:35.780 --> 00:35:36.080
Yeah.

00:35:36.080 --> 00:35:38.840
Particularly for beginners and even for intermediates.

00:35:38.980 --> 00:35:44.000
You've got to sit down and analyze the tracebacks, but I'm hoping, but this, this just kind of

00:35:44.000 --> 00:35:48.860
presents the information in a more readable way and you can like get more of the context

00:35:48.860 --> 00:35:49.280
of the error.

00:35:49.280 --> 00:35:49.620
Yeah.

00:35:49.620 --> 00:35:50.920
I think this is fantastic.

00:35:50.920 --> 00:35:52.560
This definitely super interesting.

00:35:52.700 --> 00:35:57.540
I guess one more thing here to really dive into, maybe two, two.

00:35:57.540 --> 00:35:59.720
I think the log handler is really nice.

00:35:59.720 --> 00:36:01.680
People should check that out, but maybe tables.

00:36:01.680 --> 00:36:06.540
I know it's, it doesn't sound as appealing and amazing as necessarily as what we've been

00:36:06.540 --> 00:36:07.020
talking about.

00:36:07.020 --> 00:36:13.240
But if I want to have a nice formatted table in a text output, I basically just don't do

00:36:13.240 --> 00:36:13.380
that.

00:36:13.380 --> 00:36:15.440
I'm like, that is way too much work.

00:36:15.440 --> 00:36:15.940
Yeah.

00:36:15.940 --> 00:36:16.480
Yeah.

00:36:16.540 --> 00:36:17.540
to worry about this.

00:36:17.540 --> 00:36:18.120
Right.

00:36:18.120 --> 00:36:25.900
But with using rich here, you can have almost HTML level formatting styles, you know, borders

00:36:25.900 --> 00:36:29.820
on border off, just header content divider, like alternating rows.

00:36:29.820 --> 00:36:31.800
Like I said, a right align, left align.

00:36:31.800 --> 00:36:33.800
There's all sorts of amazing stuff here.

00:36:33.800 --> 00:36:34.680
Tell us about the tables.

00:36:34.680 --> 00:36:38.640
I didn't realize how hard tables would be to implement when I started it or I might

00:36:38.640 --> 00:36:39.040
not have.

00:36:39.040 --> 00:36:41.240
You might not have done it, huh?

00:36:41.240 --> 00:36:47.620
Tables are quite complicated because you've got to calculate optimal column widths and that

00:36:47.620 --> 00:36:53.460
gets really complicated when you've got text, which can, can wrap and other like renderables

00:36:53.460 --> 00:36:54.620
that can go in those cells.

00:36:54.620 --> 00:37:00.740
It does work quite nicely now and it can handle just about anything you can throw at it and

00:37:00.740 --> 00:37:06.340
it will scale the table nicely and elegantly if, if it doesn't fit into the, you know,

00:37:06.340 --> 00:37:07.060
the width of the terminal.

00:37:07.060 --> 00:37:09.880
And it's also quite a good layout tool.

00:37:09.880 --> 00:37:15.100
You can switch the borders off entirely and then use it to lay out other things.

00:37:15.100 --> 00:37:19.320
You know, one thing that comes to mind right away is I think of some of the nice progress

00:37:19.320 --> 00:37:22.400
bar type things for the terminal, like TQDM and stuff.

00:37:22.400 --> 00:37:26.460
And they're great, but I'm always like the stuff on the right, it'll have like what it's

00:37:26.460 --> 00:37:30.520
doing and then it'll have a progress bar and then it'll have maybe, you know, how fast

00:37:30.520 --> 00:37:32.740
is it operating or how much time has it got to go or something.

00:37:32.740 --> 00:37:35.840
And those are always kind of like doing like a little pulsing, like, cause the thing on

00:37:35.840 --> 00:37:38.600
the right is always changing and they don't never quite line up.

00:37:38.600 --> 00:37:42.480
You could just, you could do that here, but have a table and put the progress bar and one

00:37:42.480 --> 00:37:44.180
of the center fill bits, right?

00:37:44.180 --> 00:37:44.480
Yeah.

00:37:44.480 --> 00:37:48.860
So you can do lots of things regarding alignment to fit everything together.

00:37:48.860 --> 00:37:53.180
And like you said, stop that effect where bits of content will flicker because they're

00:37:53.180 --> 00:37:56.140
using less characters because it goes from a hundred and into 99 and then.

00:37:56.140 --> 00:37:56.540
Yeah, exactly.

00:37:56.540 --> 00:37:57.140
Yeah.

00:37:57.140 --> 00:37:57.600
Yeah.

00:37:57.600 --> 00:38:02.560
It's a very good layout tool and also just a good way of presenting tabular information,

00:38:02.560 --> 00:38:04.000
which is kind of what it was designed for.

00:38:04.000 --> 00:38:04.260
Yeah.

00:38:04.260 --> 00:38:05.700
It is a table, right?

00:38:05.700 --> 00:38:07.500
All right.

00:38:07.500 --> 00:38:14.420
So last one, I've got some content and probably a most common way that it's in a lightweight

00:38:14.420 --> 00:38:19.300
format, but you want to turn it into something full featured in terms of text is Markdown,

00:38:19.300 --> 00:38:19.700
right?

00:38:19.740 --> 00:38:23.920
So for example, the Python bytes website is almost like entire, like the vast majority

00:38:23.920 --> 00:38:27.820
of the content there is Markdown, talk by on training, like all the stuff we've got, the

00:38:27.820 --> 00:38:29.820
CMS we built in the back end, it's all Markdown.

00:38:29.820 --> 00:38:31.420
Rich has Markdown support too, right?

00:38:31.420 --> 00:38:31.820
That's right.

00:38:31.820 --> 00:38:31.980
Yeah.

00:38:31.980 --> 00:38:33.120
There's a Markdown class.

00:38:33.120 --> 00:38:37.200
And basically I took common Mark library, which parses the Markdown.

00:38:37.480 --> 00:38:37.720
Okay.

00:38:37.720 --> 00:38:43.260
I substituted the bits which were generating HTML with something which generates rich output.

00:38:43.260 --> 00:38:49.380
And it turns out there's a reasonable job of things like headers and does the style just

00:38:49.380 --> 00:38:49.800
fine.

00:38:49.800 --> 00:38:51.540
And there's also syntax highlighting.

00:38:51.540 --> 00:38:54.740
It'll actually call out to the syntax highlighting code.

00:38:54.740 --> 00:38:59.840
So if you've got a Python code block, it'll actually highlight that Python code block.

00:39:00.100 --> 00:39:00.140
Yeah.

00:39:00.140 --> 00:39:03.580
You have support for inline code with the backtick thing, backtick.

00:39:03.580 --> 00:39:03.860
Yeah.

00:39:03.860 --> 00:39:09.900
And the blocks of code, which are the triple backslashes or triple backticks or four spaces

00:39:09.900 --> 00:39:10.320
or whatever.

00:39:10.320 --> 00:39:10.660
Yeah.

00:39:10.660 --> 00:39:16.700
So it supports much of the basic common Mark syntax and does a reasonable job of rendering.

00:39:16.700 --> 00:39:20.820
It won't look quite as good as a web browser, but I find it quite readable.

00:39:20.820 --> 00:39:24.420
But it's in the terminal and I didn't have to do anything to get it there, right?

00:39:24.420 --> 00:39:26.620
So that's pretty fantastic.

00:39:26.620 --> 00:39:27.140
Yeah.

00:39:27.140 --> 00:39:28.280
Really, really nice.

00:39:28.280 --> 00:39:29.040
All right.

00:39:29.200 --> 00:39:35.620
So I think this is probably as much of the details of rich we want to dive into in terms

00:39:35.620 --> 00:39:38.780
of like the feature set and stuff, but there's still more to go.

00:39:38.780 --> 00:39:41.660
There's a lot to love out of this library, which is great.

00:39:41.660 --> 00:39:44.500
Maybe just give us a sense of the internals.

00:39:44.500 --> 00:39:45.900
Like, how did you make this happen?

00:39:45.900 --> 00:39:46.680
How do you make it work?

00:39:46.680 --> 00:39:50.400
Is this curses to the nth degree or what's happening?

00:39:50.400 --> 00:39:51.260
There's no curses.

00:39:51.260 --> 00:39:57.540
There's a layer, which what makes most of it work, where I render everything into, and that's

00:39:57.540 --> 00:39:59.620
a list of what I call segments.

00:39:59.620 --> 00:40:02.540
The segment consists of a bit of text plus a style.

00:40:02.540 --> 00:40:06.080
And the thing about having that intermediate layer before you actually render it to the

00:40:06.080 --> 00:40:09.860
terminal is you can manipulate it afterwards.

00:40:10.400 --> 00:40:17.460
So I can apply color and style and then do word wrapping and then I can render it onto the terminal.

00:40:17.460 --> 00:40:22.320
So everything is built on that and a protocol.

00:40:22.320 --> 00:40:24.540
So objects can add a couple of methods.

00:40:24.540 --> 00:40:28.380
They can add a Dunder rich or a Dunder rich console method.

00:40:28.380 --> 00:40:31.260
Then they can themselves be renderable.

00:40:31.340 --> 00:40:35.540
So you can print your own custom objects and that will use that intermediate layer of segments

00:40:35.540 --> 00:40:38.000
to render everything onto the terminal.

00:40:38.000 --> 00:40:38.460
Nice.

00:40:38.460 --> 00:40:38.840
Okay.

00:40:38.840 --> 00:40:39.380
Yeah.

00:40:39.380 --> 00:40:40.700
It sounds like a really good separation.

00:40:40.700 --> 00:40:44.820
And you could probably also, if you need to do something specific for one platform versus

00:40:44.820 --> 00:40:48.760
another, that layer, you can make a decision on how to do that without.

00:40:48.760 --> 00:40:49.660
That's exactly it.

00:40:49.660 --> 00:40:49.880
Yeah.

00:40:49.880 --> 00:40:52.240
Having to put it all over the place, right?

00:40:52.480 --> 00:40:52.660
Yeah.

00:40:52.660 --> 00:40:55.800
So I render onto the segments and that's platform independent.

00:40:55.800 --> 00:41:01.520
But there's another bit of code which will convert those segments onto the appropriate format

00:41:01.520 --> 00:41:02.280
of the platform.

00:41:02.280 --> 00:41:07.440
And the platform might be the number of colors that's supported by terminals because some will

00:41:07.440 --> 00:41:09.760
support 16.7 million colors.

00:41:09.760 --> 00:41:13.220
Some will support 256 and then some will support 16.

00:41:13.220 --> 00:41:13.520
Yeah.

00:41:13.520 --> 00:41:18.560
But because of that intermediate layer, I can make sure that no matter what you write, we'll

00:41:18.560 --> 00:41:21.000
work on the terminal on the given platform.

00:41:21.000 --> 00:41:21.340
Yeah.

00:41:21.340 --> 00:41:21.920
Fantastic.

00:41:22.320 --> 00:41:27.560
One of the things I do want to circle back to is this idea of you're taking a year off

00:41:27.560 --> 00:41:32.980
to continue to work on this project, to grow it even further and already has and also do

00:41:32.980 --> 00:41:34.840
other things in this general realm.

00:41:34.840 --> 00:41:38.280
And so there's a couple of ways which people can support you, right?

00:41:38.280 --> 00:41:44.880
If you're a large bank that depends on this kind of stuff, one of the good options is Tidelift,

00:41:44.880 --> 00:41:45.180
right?

00:41:45.180 --> 00:41:49.900
People can get a Tidelift subscription for Rich and that gives, what do they get with that?

00:41:49.900 --> 00:41:54.420
So I don't think you get a subscription for Rich per se, but you can get a Tidelift subscription.

00:41:54.420 --> 00:41:54.840
I see.

00:41:54.840 --> 00:42:00.660
And that means that that money is divided amongst all the open source projects that you use that

00:42:00.660 --> 00:42:02.520
are signed up to Tidelift.

00:42:02.520 --> 00:42:10.560
In return, you get more responsive developers and developers which will handle security issues,

00:42:10.560 --> 00:42:11.280
et cetera.

00:42:11.280 --> 00:42:16.920
It takes the risk of open source code for big organizations because there is a little bit of

00:42:16.920 --> 00:42:21.600
risk in that if you're relying on someone's hobby project, are they going to be around in

00:42:21.600 --> 00:42:22.740
six months to your time?

00:42:22.740 --> 00:42:23.020
Yeah.

00:42:23.180 --> 00:42:29.680
So Tidelift ensures that developers will be around in the future to support your code

00:42:29.680 --> 00:42:30.240
going forward.

00:42:30.240 --> 00:42:30.760
Absolutely.

00:42:30.760 --> 00:42:33.120
The other one is right up at the top here.

00:42:33.120 --> 00:42:36.880
I could click sponsor and then come over here.

00:42:36.880 --> 00:42:39.940
Also, that pulls up a link to the external funding for Tidelift.

00:42:39.940 --> 00:42:41.160
But I could hit sponsor.

00:42:41.160 --> 00:42:43.940
Do you have like plans or anything like that?

00:42:43.980 --> 00:42:49.520
I know some projects have, you know, there's like a gold sponsor and here's just a sort

00:42:49.520 --> 00:42:50.960
of keep it going sponsor.

00:42:50.960 --> 00:42:51.260
Yeah.

00:42:51.260 --> 00:42:53.780
Do you have anything like that or is it just, you know, what people want?

00:42:53.780 --> 00:42:55.760
GitHub sponsors supports tiers.

00:42:55.760 --> 00:43:00.100
So depending on how much you want to sponsor, I will help you with your projects.

00:43:00.100 --> 00:43:03.860
I'm always happy to help people actually open source projects.

00:43:03.860 --> 00:43:05.300
Always happy to do that.

00:43:05.300 --> 00:43:12.180
But for the larger tiers, I will do code reviews or I will help you with your project on a more

00:43:12.180 --> 00:43:13.460
more formal basis.

00:43:13.460 --> 00:43:15.280
I might even write code for you.

00:43:15.280 --> 00:43:17.560
It's up to what you want to sponsor.

00:43:17.560 --> 00:43:19.600
If you just want to say thanks, that's very much appreciated.

00:43:19.600 --> 00:43:24.040
You know, if I've solved, if I fixed a bug for you and just want to say thanks, then that's

00:43:24.040 --> 00:43:24.460
fantastic.

00:43:24.460 --> 00:43:29.360
But if you're a company which is benefiting from the work that I do or the work that other

00:43:29.360 --> 00:43:34.560
open source developers do, you can sponsor a bit more to ensure that it keeps the work

00:43:34.560 --> 00:43:34.860
going.

00:43:34.860 --> 00:43:35.320
Right on.

00:43:35.320 --> 00:43:35.560
Yeah.

00:43:35.560 --> 00:43:39.880
And I encourage people if they're depending heavily upon this, you know, help you keep going

00:43:39.880 --> 00:43:43.480
strong, especially as you're transitioning to just working on this.

00:43:43.480 --> 00:43:44.580
So yeah.

00:43:44.580 --> 00:43:47.740
Also, notice someone's forked it since we even pulled it up here.

00:43:47.740 --> 00:43:48.140
How cool.

00:43:48.140 --> 00:43:54.280
So the other, the next step that maybe you would, would take this, you talked about not

00:43:54.280 --> 00:43:58.180
wanting to add too many insane features to rich to keep growing that, right?

00:43:58.180 --> 00:44:02.500
Keep it focused on target is you also have this project called textual.

00:44:03.040 --> 00:44:04.520
Textual is a TUI.

00:44:04.520 --> 00:44:10.020
We've all heard of a GUI, but a TUI is a text user interface instead of a graphical user

00:44:10.020 --> 00:44:10.640
interface, right?

00:44:10.640 --> 00:44:10.860
Yeah.

00:44:10.860 --> 00:44:12.740
I think it's a bit of a misnomer.

00:44:12.740 --> 00:44:16.540
I mean, because the interface is constructed with text, granted, but it's still a graphical

00:44:16.540 --> 00:44:17.460
thing you're looking at.

00:44:17.460 --> 00:44:17.720
Yeah.

00:44:17.720 --> 00:44:17.940
Yeah.

00:44:17.940 --> 00:44:22.080
I think of it as a GUI, but with kind of like a fairly retro aesthetic.

00:44:22.080 --> 00:44:22.660
Yeah.

00:44:22.660 --> 00:44:25.300
It does have a bit of a retro aesthetic.

00:44:25.300 --> 00:44:28.740
I would say maybe if you built something with like Colorama or something, that would be maybe

00:44:28.740 --> 00:44:30.520
more TUI-esque, right?

00:44:30.520 --> 00:44:35.060
Where there's, where you look at what you build with textual, it's got scroll bars, it's got

00:44:35.060 --> 00:44:37.480
banners, it's got icons.

00:44:37.480 --> 00:44:41.280
It's, it's closer by far.

00:44:41.280 --> 00:44:43.240
Looks a bit more, a bit more graphical.

00:44:43.240 --> 00:44:43.680
Yeah.

00:44:43.680 --> 00:44:44.280
Yeah.

00:44:44.280 --> 00:44:47.840
So tell us about textual and why not just more features on Rich.

00:44:47.840 --> 00:44:50.600
Rich has some kind of dynamic features.

00:44:50.600 --> 00:44:54.980
There are progress bars and they're updating live dashboards.

00:44:55.380 --> 00:45:01.120
And I've been asked quite, quite a lot if I could add keyboard support and mouse support.

00:45:01.120 --> 00:45:08.020
And I've resisted for quite a while because I want to keep the focus of Rich onto just generating

00:45:08.020 --> 00:45:09.660
mostly static output.

00:45:09.660 --> 00:45:16.420
But then, then I saw a project called GH top, which is kind of like H top, but it would take

00:45:16.420 --> 00:45:21.580
information from the GitHub API and it would show you like real-time events.

00:45:21.580 --> 00:45:23.780
And they used, oh, there we go.

00:45:23.940 --> 00:45:25.220
And they used Rich for that.

00:45:25.220 --> 00:45:28.600
And when I saw that, I realized, oh, I've got to do this.

00:45:28.600 --> 00:45:30.440
There's a lot of potential there.

00:45:30.440 --> 00:45:36.520
And I put it off a little bit, but then, then I started on it and I kind of realized that,

00:45:36.520 --> 00:45:39.220
yeah, there's quite a lot you can do with a terminal these days.

00:45:39.220 --> 00:45:40.880
This is one of the things that blew my mind.

00:45:40.880 --> 00:45:45.140
Maybe, you know, give us a sense of, I'm trying to pull a particular picture.

00:45:45.140 --> 00:45:47.380
Maybe this is just one I could sort of leave on the screen.

00:45:47.380 --> 00:45:54.460
But one of the things I remember from my early days of GUI type development is how do you

00:45:54.460 --> 00:45:55.920
resize stuff on the screen, right?

00:45:55.920 --> 00:46:00.660
So I want to put something where like the main window is here, but then I want the status

00:46:00.660 --> 00:46:02.600
bar thing, but I want it to stick to the bottom.

00:46:03.040 --> 00:46:04.660
And then I want some other stuff on the left.

00:46:04.660 --> 00:46:08.940
And it sounds like that would be pretty tricky to just dynamically try to generate with Rich.

00:46:08.940 --> 00:46:13.000
But with Textual, you can say like this thing docks to the left and this docks to the bottom.

00:46:13.000 --> 00:46:14.540
And here, this fills the main content.

00:46:14.540 --> 00:46:19.960
And then those bits in the middle, are those basically rendered either more of these containers

00:46:19.960 --> 00:46:20.600
and these widgets?

00:46:20.600 --> 00:46:22.060
Or is that Rich directly?

00:46:22.060 --> 00:46:25.220
Or give people a sense of like what they build with this.

00:46:25.220 --> 00:46:31.460
So Rich does the rendering, which is responsible for getting stuff onto the screen, but Textual

00:46:31.460 --> 00:46:33.380
handles the dynamic stuff.

00:46:33.380 --> 00:46:37.420
At the most atomic layer, there's something called a widget.

00:46:37.420 --> 00:46:41.260
And a widget is almost like a software component in itself.

00:46:41.260 --> 00:46:43.480
It's built on AsyncIO.

00:46:43.480 --> 00:46:48.380
So each widget has its own AsyncIO task and it's constantly processing events.

00:46:48.380 --> 00:46:55.340
And Textual will change the size of that and change the layout in response to resizing the terminal.

00:46:55.340 --> 00:47:02.800
And you can tell it how the widgets fit together within the given dimensions of the terminal.

00:47:02.800 --> 00:47:03.200
Right.

00:47:03.200 --> 00:47:07.500
So you've got like the layout elements that handle docking and whatnot.

00:47:07.500 --> 00:47:08.040
Yeah.

00:47:08.040 --> 00:47:08.180
Yeah.

00:47:08.180 --> 00:47:08.820
Yeah.

00:47:08.820 --> 00:47:09.260
Very cool.

00:47:09.260 --> 00:47:14.580
So one of the examples you have on the Textual readme is building one of these widgets.

00:47:14.580 --> 00:47:16.500
So you just create a class that drives from widget.

00:47:16.500 --> 00:47:21.260
Here you have a hover example and it has a way to render itself.

00:47:21.260 --> 00:47:27.540
And then it very much like traditional, you know, I'm thinking of building like VB6 apps

00:47:27.540 --> 00:47:31.420
or Windows Forms apps, like these traditional ones where you have drag and drop widgets.

00:47:31.420 --> 00:47:32.920
They have these events, right?

00:47:32.920 --> 00:47:37.020
And one of the events here, you wouldn't think of this as a terminal thing.

00:47:37.020 --> 00:47:43.580
You've got like, you know, on mouse, you know, on enter, on leave and, you know, mouse over

00:47:43.580 --> 00:47:45.160
and things like that.

00:47:45.160 --> 00:47:45.360
Right.

00:47:45.360 --> 00:47:52.900
Like those are regular UI types of interactions that you would not expect to see in a text-based

00:47:52.900 --> 00:47:53.300
app.

00:47:53.300 --> 00:47:53.600
Right.

00:47:53.600 --> 00:47:53.940
Yeah.

00:47:53.940 --> 00:47:54.680
That's fantastic.

00:47:54.680 --> 00:48:00.460
It's based partially on my knowledge of writing desktop applications, which is quite old now.

00:48:00.460 --> 00:48:00.980
Oh yeah.

00:48:00.980 --> 00:48:01.880
What did you write them in?

00:48:01.880 --> 00:48:03.000
WX widgets mostly.

00:48:03.000 --> 00:48:03.520
Yeah.

00:48:03.740 --> 00:48:05.620
It's a C++ framework.

00:48:05.620 --> 00:48:07.900
I think it's got a Python layer.

00:48:07.900 --> 00:48:08.320
Yeah.

00:48:08.320 --> 00:48:08.440
Yeah.

00:48:08.440 --> 00:48:08.520
Yeah.

00:48:08.520 --> 00:48:09.400
There's WX Python.

00:48:09.400 --> 00:48:13.180
I think that might be the next, the Python wrapper.

00:48:13.180 --> 00:48:13.620
That's right.

00:48:13.620 --> 00:48:13.840
Yeah.

00:48:13.840 --> 00:48:16.940
But in the last 10 years, I haven't done any desktop applications.

00:48:16.940 --> 00:48:18.380
I've been working mostly in the web.

00:48:18.880 --> 00:48:24.580
So it's mostly influenced by web development with modern frameworks, particularly Vue, which

00:48:24.580 --> 00:48:25.780
I've used a few times.

00:48:25.780 --> 00:48:26.280
Vue's nice.

00:48:26.280 --> 00:48:26.500
Yeah.

00:48:26.500 --> 00:48:27.220
Vue's very nice.

00:48:27.620 --> 00:48:32.980
So I'm trying to replicate some of the best features, I think, of you into the terminal.

00:48:32.980 --> 00:48:35.900
I'm surprised how well some of these features translate.

00:48:35.900 --> 00:48:36.320
Yeah.

00:48:36.320 --> 00:48:37.020
This is incredible.

00:48:37.020 --> 00:48:39.660
It really does build these interactive things.

00:48:39.660 --> 00:48:43.200
Now, another thing to talk about is how do you control the look and feel, right?

00:48:43.200 --> 00:48:48.000
Like the way you might do it in Rich is you might have one of these console markups or markdown,

00:48:48.000 --> 00:48:50.340
or you could use a console and set a style.

00:48:50.340 --> 00:48:58.600
But if you're inspired by the web, you know, like dot main container hash thing I want to

00:48:58.600 --> 00:48:59.180
style, right?

00:48:59.180 --> 00:49:01.240
Like it's some sort of CSS selector, right?

00:49:01.240 --> 00:49:01.660
Yeah.

00:49:01.660 --> 00:49:02.760
So you've read my mind.

00:49:02.760 --> 00:49:06.120
I've been last few days working on CSS.

00:49:06.120 --> 00:49:06.720
Okay.

00:49:06.720 --> 00:49:09.060
It's going to work very much like...

00:49:09.060 --> 00:49:11.840
Is it actual CSS or CSS-like stuff?

00:49:11.840 --> 00:49:12.900
Like what do you have in mind here?

00:49:12.900 --> 00:49:14.160
It's probably not actual CSS.

00:49:14.160 --> 00:49:16.940
A lot of the stuff just wouldn't apply to terminal.

00:49:16.940 --> 00:49:17.160
Yeah, it makes sense.

00:49:17.160 --> 00:49:17.340
Sure.

00:49:17.340 --> 00:49:18.880
But essentially, it's the selectors.

00:49:19.020 --> 00:49:26.100
So I will have selectors where you can select an ID and then a child with a class name,

00:49:26.100 --> 00:49:26.880
et cetera.

00:49:26.880 --> 00:49:29.660
I mean, that's basically what I was thinking when I was saying real CSS, right?

00:49:29.660 --> 00:49:30.260
Like is it...

00:49:30.260 --> 00:49:30.360
Right.

00:49:30.360 --> 00:49:37.320
Or will I say like hash container dot children type and I would write that or is it like...

00:49:37.320 --> 00:49:38.180
It's exactly like that, but it's...

00:49:38.180 --> 00:49:39.040
Exactly like that.

00:49:39.040 --> 00:49:39.420
Yeah.

00:49:39.420 --> 00:49:39.820
Oh, beautiful.

00:49:39.820 --> 00:49:41.940
And the only thing that differs is the...

00:49:41.940 --> 00:49:42.900
I don't know what you call them.

00:49:42.900 --> 00:49:46.260
The bit that goes inside the curly brackets, the actual rules, they will be different.

00:49:46.260 --> 00:49:46.580
Sure.

00:49:46.580 --> 00:49:47.200
Yeah, yeah.

00:49:47.400 --> 00:49:47.580
Yeah.

00:49:47.580 --> 00:49:51.320
They render different things, but very much like CSS.

00:49:51.320 --> 00:49:54.420
If you come from the web, you see this, you'd be very much at home.

00:49:54.420 --> 00:49:54.820
Nice.

00:49:54.820 --> 00:50:00.520
I could probably even use less and transpile that down to CSS and put the odds...

00:50:00.520 --> 00:50:00.900
Yeah, maybe.

00:50:00.900 --> 00:50:01.340
Who knows?

00:50:01.340 --> 00:50:02.200
Yeah, maybe.

00:50:02.200 --> 00:50:06.320
I was thinking, should I just do CSS, which is hard enough in itself?

00:50:06.540 --> 00:50:10.980
Or should I try to implement less or SAS or one of these things?

00:50:10.980 --> 00:50:13.760
Well, I'm going to try CSS first of all.

00:50:13.760 --> 00:50:19.980
If you get it working with CSS, then you probably can get the less compiler to generate the right CSS out of it somehow.

00:50:19.980 --> 00:50:20.760
Yeah, maybe.

00:50:20.760 --> 00:50:26.720
But actually, one of the worst things I think of JavaScript and web app development is all those pre-processors.

00:50:26.820 --> 00:50:27.160
I know.

00:50:27.160 --> 00:50:29.360
I'm 100% with you.

00:50:29.360 --> 00:50:29.700
Yeah.

00:50:29.840 --> 00:50:38.660
When you've got to run all these tasks and all these CLI things just to get it so you can start using your app, it's like, there's something kind of broken about this.

00:50:38.660 --> 00:50:41.140
Can I just include a file here and go?

00:50:41.300 --> 00:50:47.900
It's gotten so complicated that JavaScript is one of the more complicated ways to write code rather than one of the simplest, I think.

00:50:47.900 --> 00:50:48.540
Exactly.

00:50:48.540 --> 00:50:49.260
Yeah.

00:50:49.260 --> 00:50:56.940
There was a time where front-end development was seen as kind of like the baby brother of real development.

00:50:56.940 --> 00:50:58.460
You and your QJ query.

00:50:58.460 --> 00:51:00.960
That's not true anymore.

00:51:00.960 --> 00:51:02.380
I don't think it's been true for a while.

00:51:02.380 --> 00:51:08.680
I think front-end development requires just the same type of thinking as back-ends.

00:51:08.800 --> 00:51:13.440
You've got to organize all these different processes together and mental models.

00:51:13.440 --> 00:51:17.720
And it's actually more complicated because there's so much going on.

00:51:17.720 --> 00:51:19.640
There's so many little things you've got to remember.

00:51:19.640 --> 00:51:20.080
Yeah.

00:51:20.080 --> 00:51:28.400
You're taking so much of modern software development and squishing it down to this narrow little bit that is like run it in JavaScript on the browser.

00:51:28.400 --> 00:51:29.100
Yeah.

00:51:29.100 --> 00:51:34.980
It's kind of got to fit into this historically what used to be like a narrow-focused environment, and now it's definitely not.

00:51:34.980 --> 00:51:35.340
Yeah.

00:51:35.520 --> 00:51:46.380
So I'm trying to take what I think are the good things about front-end development and apply them to the terminal and hopefully leave out the things which I don't like so much.

00:51:46.380 --> 00:51:46.700
Yeah.

00:51:46.700 --> 00:51:47.640
That sounds great.

00:51:48.180 --> 00:51:54.100
So maybe for this one, I think what people should probably do is they should check out the examples, right?

00:51:54.100 --> 00:51:55.220
The examples from Textual.

00:51:55.220 --> 00:51:59.040
They can clone the repo and just run these, and it's super easy.

00:51:59.040 --> 00:52:02.600
There's also a way to see them, I guess, on the developer video log here.

00:52:02.600 --> 00:52:04.280
Are these you doing these videos here?

00:52:04.280 --> 00:52:05.260
That's me, yeah.

00:52:05.260 --> 00:52:08.000
It's just using a short demo of each.

00:52:08.000 --> 00:52:08.520
Nice.

00:52:08.920 --> 00:52:10.260
This is my ad apparently I'm getting.

00:52:10.260 --> 00:52:10.540
No.

00:52:10.540 --> 00:52:11.280
All right.

00:52:11.280 --> 00:52:12.520
We'll not play that.

00:52:12.520 --> 00:52:15.320
Go YouTube.

00:52:15.320 --> 00:52:15.720
All right.

00:52:15.720 --> 00:52:22.760
So, yeah, but people can go and check these out because I think seeing it in action is really what you need to appreciate Textual.

00:52:22.760 --> 00:52:31.000
And it can demonstrate the features which Textual can do, which I don't see in other TUI frameworks.

00:52:31.420 --> 00:52:33.420
I'm thinking particularly of animation.

00:52:33.420 --> 00:52:33.860
Yeah.

00:52:33.860 --> 00:52:37.680
I was just thinking like the CSS easing functions and those types of animations.

00:52:37.680 --> 00:52:38.000
Yeah.

00:52:38.000 --> 00:52:38.440
Yeah.

00:52:38.440 --> 00:52:41.000
I was surprised how well that worked.

00:52:41.000 --> 00:52:46.260
I was animating things at 60 frames a second, and it can go up to 120 frames per second.

00:52:46.260 --> 00:52:50.100
Terminals these days, they're built on the same technology as video games.

00:52:50.100 --> 00:52:56.720
They use hardware accelerated graphics under the hood, so they can actually render terminal updates very, very quickly.

00:52:56.720 --> 00:52:59.280
I don't think people have taken advantage of that.

00:52:59.280 --> 00:53:04.000
How long until someone re-implements Doom on Rich or on Textual?

00:53:04.000 --> 00:53:05.420
I'm sure it's possible.

00:53:05.420 --> 00:53:08.980
You could render it and then, you know, render it onto text.

00:53:08.980 --> 00:53:11.940
I don't know how you do it, but various ways of rendering images.

00:53:11.940 --> 00:53:15.240
So, in theory, you could put Doom in the middle of a Textual application.

00:53:15.240 --> 00:53:20.200
I would say start with really, really small fonts in a big terminal window so you get higher resolution.

00:53:20.200 --> 00:53:20.680
Yeah.

00:53:20.680 --> 00:53:21.080
Yeah.

00:53:21.080 --> 00:53:22.700
But, yeah, you've got the color.

00:53:22.700 --> 00:53:23.640
You've got the emojis.

00:53:23.640 --> 00:53:24.660
I bet you could make it happen.

00:53:24.660 --> 00:53:25.380
Awesome.

00:53:25.380 --> 00:53:25.740
All right.

00:53:25.740 --> 00:53:28.540
Well, we're getting pretty short on time here, Will.

00:53:28.700 --> 00:53:34.880
Anything else you want to sort of throw in about Textual or even Rich before we wrap it up?

00:53:34.880 --> 00:53:38.160
Just to say that I like getting feedback and input.

00:53:38.160 --> 00:53:42.560
So, if you have any suggestions, jump onto Textual discussion board.

00:53:42.560 --> 00:53:44.820
Or if you find any bugs, let me know.

00:53:44.820 --> 00:53:48.520
Or connect with me on Twitter and I'm happy to talk about these things.

00:53:48.520 --> 00:53:48.800
Yeah.

00:53:48.800 --> 00:53:49.220
Fantastic.

00:53:49.620 --> 00:53:52.960
Also, I want to give a shout out to one of your other projects real quick.

00:53:52.960 --> 00:53:53.380
Great.

00:53:53.380 --> 00:53:53.580
Yeah.

00:53:53.580 --> 00:53:55.180
So, this is PAL file system.

00:53:55.180 --> 00:53:57.240
I've been working on that for well over 10 years now.

00:53:57.240 --> 00:54:00.500
I've handed it over to some very talented developers.

00:54:00.500 --> 00:54:05.320
But, essentially, the idea is that there's an abstraction there for file systems.

00:54:05.800 --> 00:54:13.000
So, the same code can write to your disk drive or an FTP server or a zip file.

00:54:13.000 --> 00:54:15.260
And it just all works exactly the same way.

00:54:15.260 --> 00:54:15.520
Nice.

00:54:15.520 --> 00:54:19.100
Do you have, like, cloud format support, like S3 and things like that?

00:54:19.100 --> 00:54:19.420
Yeah.

00:54:19.420 --> 00:54:19.800
Exactly.

00:54:19.800 --> 00:54:20.020
Yeah.

00:54:20.040 --> 00:54:26.480
So, there's an S3 version and there's a Google Cloud version and there's dozens of other implementations.

00:54:26.480 --> 00:54:28.100
Any database stuff?

00:54:28.100 --> 00:54:31.940
Can I, like, treat a table as a directory or something like that?

00:54:31.940 --> 00:54:33.380
I wouldn't be surprised if there is.

00:54:33.380 --> 00:54:35.640
I don't know of any off the top of my head.

00:54:35.640 --> 00:54:42.120
But some people have done some quite creative things where they've made something which is not a file system look like a file system.

00:54:42.120 --> 00:54:42.900
Oh, look at this.

00:54:42.900 --> 00:54:44.520
Dropbox FS.

00:54:44.520 --> 00:54:46.880
Dropbox as a file system.

00:54:46.880 --> 00:54:47.600
Okay.

00:54:47.600 --> 00:54:48.660
That's pretty amazing.

00:54:49.240 --> 00:54:49.360
Okay.

00:54:49.360 --> 00:54:50.800
Here's the index of file systems.

00:54:50.800 --> 00:54:51.340
Let's see.

00:54:51.340 --> 00:54:54.440
We've got application data, FTP in memory.

00:54:54.440 --> 00:54:55.560
Oh, that's pretty slick.

00:54:55.560 --> 00:54:58.260
So, you can read and write files, like, say, for tests and not care.

00:54:58.260 --> 00:54:59.700
Or temp files, maybe.

00:54:59.700 --> 00:55:01.280
Tem files would be fantastic, right?

00:55:01.280 --> 00:55:01.640
Yeah.

00:55:01.640 --> 00:55:04.740
So, you can use temp files and, like you said, for testing.

00:55:04.740 --> 00:55:08.340
So, you can write it into memory without bothering to write it onto your hard drive.

00:55:08.340 --> 00:55:08.620
Okay.

00:55:08.620 --> 00:55:10.160
The multi-file system.

00:55:10.160 --> 00:55:12.540
So, you could multiplex reads and writes.

00:55:12.540 --> 00:55:13.220
That's pretty killer.

00:55:13.220 --> 00:55:13.600
Yeah.

00:55:13.600 --> 00:55:18.680
That's more, I remember correctly, you can layer several file systems.

00:55:18.680 --> 00:55:22.400
So, you could have one to write and then several to read.

00:55:22.400 --> 00:55:26.760
And depending on where the file is, it'll just make it appear like a single file system.

00:55:26.760 --> 00:55:27.000
Yeah.

00:55:27.000 --> 00:55:27.860
A lot of neat stuff here.

00:55:27.860 --> 00:55:30.760
So, you know, people, they got a lot of file reading and writing to do.

00:55:30.760 --> 00:55:31.440
They can check that out.

00:55:31.440 --> 00:55:33.040
Also, I want to give a quick shout out.

00:55:33.040 --> 00:55:35.080
I saw Paul Everett on the live stream out there.

00:55:35.200 --> 00:55:41.360
So, Paul and you dove inside in a more visual way into textual, right?

00:55:41.440 --> 00:55:44.380
So, I'll link to a live stream you all did over there together.

00:55:44.380 --> 00:55:44.660
Great.

00:55:44.660 --> 00:55:44.940
Cool.

00:55:44.940 --> 00:55:45.740
Yeah, that was fun.

00:55:45.740 --> 00:55:46.700
Yeah.

00:55:46.700 --> 00:55:47.100
Awesome.

00:55:47.100 --> 00:55:47.780
All right.

00:55:47.780 --> 00:55:50.760
Well, I think that pretty much wraps it up.

00:55:50.760 --> 00:55:54.940
So, I'll give you the final two questions before we get out of here, though.

00:55:54.940 --> 00:55:59.620
So, Will, if you're going to write some Python code, what editor do you use these days?

00:55:59.820 --> 00:56:00.840
I use VS Code.

00:56:00.840 --> 00:56:02.380
I've used that for quite a while.

00:56:02.380 --> 00:56:03.400
Quite happy with it.

00:56:03.400 --> 00:56:06.120
But I do try other editors from time to time.

00:56:06.120 --> 00:56:06.520
Nice.

00:56:06.520 --> 00:56:12.060
And then, in addition to pip install rich and pip install textual, any other packages out

00:56:12.060 --> 00:56:15.560
there you want to give a shout out to that you think you use some eyeballs and some attention?

00:56:15.560 --> 00:56:16.980
Anything that's impressed you lately?

00:56:16.980 --> 00:56:17.940
I'm drawing a blank.

00:56:17.940 --> 00:56:18.720
There's so many.

00:56:18.720 --> 00:56:20.320
It is hard to choose, isn't it?

00:56:20.320 --> 00:56:21.740
There's a project I saw.

00:56:21.740 --> 00:56:23.260
Can I mention one that uses rich?

00:56:23.260 --> 00:56:23.980
It was quite cool.

00:56:23.980 --> 00:56:24.320
Of course.

00:56:24.320 --> 00:56:24.900
Yeah, absolutely.

00:56:24.900 --> 00:56:26.900
It's called Object Explorer.

00:56:27.420 --> 00:56:29.640
It's a terminal user interface, but it's not.

00:56:29.640 --> 00:56:33.100
I think it's OBJ Explorer, which is quite nice.

00:56:33.100 --> 00:56:39.080
You could create an, you explore a Python object and you can navigate into it in a visual way

00:56:39.080 --> 00:56:41.740
and it will show you the attributes, et cetera.

00:56:41.740 --> 00:56:42.440
Oh, fantastic.

00:56:42.440 --> 00:56:43.700
Yeah, that sounds really fun.

00:56:43.700 --> 00:56:47.820
Is this for like in-memory Python objects or database objects or what is it?

00:56:47.820 --> 00:56:49.240
Oh, in-memory Python objects.

00:56:49.240 --> 00:56:51.240
So, I think it's like a debugging tool.

00:56:51.240 --> 00:56:54.880
It's kind of like, it's a bit like rich.inspect, but it's more visual.

00:56:54.880 --> 00:56:55.780
Okay.

00:56:55.780 --> 00:56:56.640
Yeah, fantastic.

00:56:56.760 --> 00:56:57.660
We'll have to link to that one.

00:56:57.660 --> 00:56:58.360
All right, Will.

00:56:58.360 --> 00:57:00.200
So, thank you for being here.

00:57:00.200 --> 00:57:01.340
This has been really great.

00:57:01.340 --> 00:57:07.280
Congratulations on both of these projects and all the momentum you've gotten.

00:57:07.280 --> 00:57:07.740
Thank you.

00:57:07.740 --> 00:57:08.440
Final call to action.

00:57:08.440 --> 00:57:11.400
People want to check out Rich or Textual.

00:57:11.400 --> 00:57:12.920
Maybe want to support you.

00:57:12.920 --> 00:57:17.500
Whatever else you want to give a final shout out for or call to action before we call it a show.

00:57:17.500 --> 00:57:19.280
Just connect with me on Twitter.

00:57:19.280 --> 00:57:21.500
My handle is at Will McGuggan.

00:57:21.500 --> 00:57:22.360
Say hi.

00:57:22.360 --> 00:57:24.880
I'm happy to talk on Twitter.

00:57:24.880 --> 00:57:25.360
Right on.

00:57:25.520 --> 00:57:27.060
Be sure to put the link in the show notes.

00:57:27.060 --> 00:57:28.220
Thanks for being here, Will.

00:57:28.220 --> 00:57:28.720
Thank you.

00:57:28.720 --> 00:57:29.220
It's been great.

00:57:29.220 --> 00:57:29.660
Bye.

00:57:29.660 --> 00:57:30.000
Bye-bye.

00:57:30.960 --> 00:57:33.640
This has been another episode of Talk Python To Me.

00:57:33.640 --> 00:57:36.380
Our guest on this episode was Will McGuggan.

00:57:36.700 --> 00:57:38.240
It's been brought to you by Shortcut.

00:57:38.240 --> 00:57:40.020
And us over at Talk Python Training.

00:57:40.020 --> 00:57:42.600
And the transcripts are brought to you by Assembly AI.

00:57:42.600 --> 00:57:47.320
Choose Shortcut, formerly Clubhouse.io, for tracking all of your project's work.

00:57:47.320 --> 00:57:50.700
Because you shouldn't have to project manage your project management.

00:57:50.700 --> 00:57:53.500
Visit talkpython.fm/shortcut.

00:57:53.500 --> 00:57:56.260
Do you need a great automatic speech-to-text API?

00:57:56.260 --> 00:57:58.800
Get human-level accuracy in just a few lines of code.

00:57:58.800 --> 00:58:01.660
Visit talkpython.fm/assembly AI.

00:58:02.460 --> 00:58:03.420
Want to level up your Python?

00:58:03.420 --> 00:58:07.460
We have one of the largest catalogs of Python video courses over at Talk Python.

00:58:07.460 --> 00:58:12.660
Our content ranges from true beginners to deeply advanced topics like memory and async.

00:58:12.660 --> 00:58:15.320
And best of all, there's not a subscription in sight.

00:58:15.320 --> 00:58:18.240
Check it out for yourself at training.talkpython.fm.

00:58:18.380 --> 00:58:20.120
Be sure to subscribe to the show.

00:58:20.120 --> 00:58:22.900
Open your favorite podcast app and search for Python.

00:58:22.900 --> 00:58:24.220
We should be right at the top.

00:58:24.220 --> 00:58:29.360
You can also find the iTunes feed at /itunes, the Google Play feed at /play,

00:58:29.360 --> 00:58:33.580
and the direct RSS feed at /rss on talkpython.fm.

00:58:33.580 --> 00:58:37.000
We're live streaming most of our recordings these days.

00:58:37.000 --> 00:58:40.420
If you want to be part of the show and have your comments featured on the air,

00:58:40.420 --> 00:58:44.840
be sure to subscribe to our YouTube channel at talkpython.fm/youtube.

00:58:45.280 --> 00:58:46.700
This is your host, Michael Kennedy.

00:58:46.700 --> 00:58:47.980
Thanks so much for listening.

00:58:47.980 --> 00:58:49.140
I really appreciate it.

00:58:49.140 --> 00:58:51.060
Now get out there and write some Python code.

00:58:51.060 --> 00:59:11.760
I'll see you next time.