back to index

Streamlit for ML #4 - Adding Bootstrap Components


Chapters

0:0 Intro
2:35 Streamlit Caching
6:56 Experimental Caching Primitives

Whisper Transcript | Transcript Only Page

00:00:00.000 | Okay, in the last few videos, we've put together this Streamlit app for open domain question
00:00:08.000 | answering. And what it does at the moment is we can ask you a question like, "Who are
00:00:12.940 | the Normans?" Or we can ask somewhere, I don't know, "Where are the Normans from?" I'm not
00:00:19.600 | sure if we have, I'm not sure what topics we have in there in the vector database. I'm
00:00:25.300 | just going to ask Norman questions for now. Maybe I can ask something like, "Where is
00:00:32.300 | Italy?" That must come up with something, surely. Yeah, okay, so we see different things
00:00:40.440 | in there. Okay, cool. So, we have this and we can ask it questions and it all works,
00:00:49.440 | but it's not very nice to look at at the moment. We just get these big chunks of text back,
00:00:57.160 | and I mean, that's pretty much all we can do with the current backend, but we can at
00:01:03.240 | least format it a little nicer. So, what we're going to do is convert these big chunks of
00:01:09.960 | text into what are called cards. Now, to create these cards, we are going to use Bootstrap.
00:01:17.920 | So if I just type in Bootstrap cards, you can see it's in my history, but I'm going
00:01:25.560 | to just put Bootstrap cards for now, so you can follow. And go on here, and let's make
00:01:34.240 | this a little bit bigger, zoom in a little bit, and scroll down. So, we have some cool
00:01:39.920 | examples here. So, this is one card, we can go down a little bit more, or this one. I
00:01:46.180 | think this is probably the one I'll use. Okay, so basically Bootstrap is like a framework,
00:01:53.280 | which is pretty lightweight, and you have all these really nice examples of how you
00:01:57.840 | can build something that's super nice. So, what we can do is actually just copy this.
00:02:02.200 | We'll go back over to our code, and what I'm going to do is I'm going to create the definition
00:02:10.640 | for one of these cards. I'm going to do that in a function. So, we'll make our lives a
00:02:17.580 | little bit easier. We made this a lot easier to read, anyway. Okay, so I'm going to, what
00:02:25.060 | we're going to do is return an F string. Let me clean up a little bit, so unindent that.
00:02:39.420 | And that's our card. So, now, well, actually, no, this won't work yet, but if I come down
00:02:45.960 | here, I'm going to write, okay, for context, instead of taking this stwrite metadata, I'm
00:02:53.280 | going to just write st.write card. Okay, actually, not stwrite, we actually want to include st.markdown,
00:03:08.780 | and so markdown is another useful component in Streamlet. Let me open it up here. So,
00:03:17.480 | it would be a text element, and we have st.markdown. So, let's have a look at that, and display
00:03:23.740 | string formatted as markdown. Now, what it also allows you to do is if we take this,
00:03:29.420 | put it in here, and say it's true, we can also use it to display HTML. Let's save that.
00:03:38.620 | Let's go to our app, and get, okay, always rerun at the top there. Okay, and now we have
00:03:49.380 | these cards. Now, they're not very nice looking, and we'll figure out why in a moment, but
00:03:54.340 | before we figure out why, let's actually make this a little bit nicer, or make it relevant,
00:04:00.220 | because at the moment, we don't have anything relevant in here. So, I'm going to include
00:04:04.380 | the title, or maybe the, yeah, let's go ID value, title, and context. Okay, we'll make
00:04:14.940 | this an F format string, and what I'm going to do is remove these links at the bottom,
00:04:22.500 | because I don't really have anywhere to link to with these, and what I'm going to do is
00:04:28.380 | replace this default text with a context. Let me minimize that here. There's our context.
00:04:43.880 | The title, we'll make title, and the subtitle, I want it to be the ID value. Okay, so if
00:04:56.980 | I do that, okay, it's not going to work straight away, because we need to actually pass our
00:05:00.780 | ID value, title, and context, so let's do that. So, we know the text is here. Okay,
00:05:15.060 | so we have the context, which is the last parameter. We also have in the context, or
00:05:21.020 | in the metadata, we also have the title, and then the ID is in a different part of the
00:05:27.500 | JSON response, so that is in, if I remove this, that is in ID. Okay, let's run this,
00:05:36.620 | see if it works. Okay, cool, so now we have the title, so the Wikipedia topic that came
00:05:44.100 | from, the ID, unique ID for each context we have, and then we also have this chunk of
00:05:51.460 | text, the context. Now, there's a few things that are kind of going a little bit weird
00:05:57.100 | here. First, the formatting of the card isn't what we saw in the bootstrap example. Come
00:06:03.140 | over here, it looks really nice. Okay, so something weird going on there. So, what we
00:06:09.340 | actually need to do is if we, let's search CSS, see if it comes up. Okay, so we have
00:06:20.380 | this compiled CSS and JS, come down to here. What we need to do is actually copy the style
00:06:30.860 | sheet for bootstrap, so basically how it's been styled, and we need to put that into
00:06:35.260 | our app. So, all we need to do is copy that first line, which is a style sheet, the second
00:06:42.780 | one is for, if you have JavaScript components, we don't for the cards, so we don't need to
00:06:48.740 | worry about that. And what we're going to do is actually create another markdown component,
00:06:56.100 | so st.markdown, because as before, all we need to do here is add some HTML to our app.
00:07:06.900 | So we're just going to paste that in. Okay, but as before, with HTML, we also need to
00:07:15.740 | use this allow, or unsafe allow HTML. Okay, now if I add that in here and rerun the app,
00:07:27.620 | our card should start looking nicer. Okay, so you can see now we have that nice little
00:07:32.820 | border and we have, it just looks better. The only thing is now that it's actually like
00:07:38.860 | really tight, it's not taking the full width of the parent container that it's within,
00:07:44.700 | so to change that, we don't actually need to really do anything, we just need to remove
00:07:49.440 | this style component. Okay, so let's remove that and see what happens. Okay, so now we
00:07:56.220 | will see this card sticks to the same width as our search component, so we're now getting
00:08:05.100 | something a little nicer. The only issue is that now, if we look between our cards, they're
00:08:11.540 | like attached and we also don't really want that. So what we can do is add a margin to
00:08:17.740 | our cards. So this is all just like HTML and CSS, it's nothing like too complicated, so
00:08:24.060 | you can look this up if you want to. I'm going to use 1rem, which is a more flexible measure
00:08:34.980 | rather than using pixels. I'm going to save that, that's how it looks and what we get.
00:08:40.240 | So now we get a little bit of a gap between one of the edges, you can remove that if you
00:08:45.580 | want by using the margin top and margin bottom, but I think it looks nice, so I'm going to
00:08:49.660 | keep it and we have an actual gap between each of our cards. Okay, so yeah, that's pretty
00:08:57.500 | cool. If we go back to something that we know works, so who are the Normans, run that and
00:09:06.980 | we now get this cool response. I think that is pretty much like the core of our app. That's
00:09:15.820 | everything we need and the app is there. It's definitely not perfect, there's a lot we can
00:09:20.300 | do to it to make it much more interesting and we will look into those things, but for
00:09:24.700 | now that's pretty cool. It's the core of our app and with that, we can actually do something
00:09:32.580 | useful with it. We can actually help people find information in a quicker, more natural
00:09:39.020 | way. But that's it for that video. I really hope it's been useful and yeah, thank you
00:09:46.380 | very much for watching. I'll see you in the next one. Bye.