back to index

Streamlit for ML #5.1 - Custom React Components in Streamlit Setup


Chapters

0:0 Intro
2:19 Environment Setup
3:42 Starting with a Template
7:41 Naming for Card Component
11:31 Installing Node Packages
15:12 Running the Component

Whisper Transcript | Transcript Only Page

00:00:00.000 | Today we're going to have a look at how we can build custom components in
00:00:04.700 | Streamlit using React and external libraries like Material UI. So there are
00:00:13.740 | already plenty of components that you can use directly from Streamlit and also
00:00:20.740 | from the Streamlit community but obviously you may find something to use
00:00:27.260 | something that doesn't already exist. So we'll go through that process
00:00:33.580 | fortunately it's not too difficult it does require a little bit of like front
00:00:40.780 | end code but Streamlit does make it pretty straightforward. So let's have a
00:00:51.020 | quick look at what this card might look like or this component is a card. So all
00:00:57.980 | we have for our custom component is this little card in the middle here. The
00:01:03.420 | rest of this is just Streamlit and then this bit here is based on a Material UI
00:01:10.820 | component. So if I go back we just have a title, subtitle, text or body of text and
00:01:19.060 | a link here which is a Material UI button. Click on it and for now let's just take
00:01:24.780 | this to Google. But we can essentially like an object in Python we can pass
00:01:32.460 | whatever values we like to this component. So here are the actual cards from
00:01:42.180 | Material UI that we're basing this on and with these cards we can include much
00:01:47.140 | more than what I've shown you this is just the absolute basics like we can
00:01:53.380 | include these little profile images, drop-downs, options and so on even little
00:02:04.380 | expanders, pictures. So yeah there's a lot we can do with it and as far as I know
00:02:12.940 | there isn't anything like this available directly within Streamlit. So let's go
00:02:20.220 | ahead and set up our environment for developing this component. So if you are
00:02:26.780 | on Mac and you have homebrew installed you can just go to brew, install node and
00:02:35.260 | this will install node.js and the node package manager. I already have it
00:02:41.660 | installed so I'm not going to rerun it. If you are not on Mac or you don't have
00:02:46.380 | homebrew you can download it from the node.js website. So over here this here
00:02:59.660 | node.js.org and then download. Okay you have Windows, Mac and so on. So once you
00:03:10.140 | have that installed you also need to install Streamlit. I'm going to assume
00:03:14.860 | you already have it installed
00:03:18.180 | but if not you just pip install Streamlit. Now I have Streamlit in another
00:03:24.500 | environment so I'm going to activate that. I'm going to activate Streamlit and the
00:03:32.380 | Streamlit side of things I will run from this terminal window. Now to build our
00:03:43.780 | component for Streamlit we need to follow a certain structure and
00:03:49.340 | fortunately Streamlit provides us with a few templates that we can start from to
00:03:54.740 | make our lives a little bit easier. So let me show you where you can find those.
00:04:02.380 | So if we just type in Streamlit GitHub or maybe we can go Streamlit
00:04:15.820 | components template. It's probably easier. Click on here. Okay we have a Streamlit
00:04:28.020 | component template repo. We just want to git clone this so we click on code over
00:04:35.300 | here, copy this and then switch back to our terminal. Navigate to whatever folder
00:04:45.420 | you're going to store the template folder within. So I'm going to go to
00:04:51.180 | documents, projects and I'm just going to write git clone and then I'm going to
00:04:56.780 | clone the component template repository. Okay let's open that VS Code
00:05:06.260 | and we'll have a look at what we have in here. Okay so
00:05:13.300 | on the right over here we have our directory structure. We have a few
00:05:18.300 | different templates so we're going to go this template here which uses react and
00:05:25.180 | within this template directory this is our actual project so we can almost
00:05:31.940 | ignore the rest of this stuff here. Just anything within template is what we care
00:05:37.460 | about. We have set up Pi so we're going to use this and manifest for creating a
00:05:45.100 | pip package which will contain our components. So to actually use that
00:05:49.620 | component we install our component and then we just import it into our
00:05:56.540 | streamlit app script or app.py usually and then use it and within here we just
00:06:09.600 | have the default file names here or default directory names of my component
00:06:13.860 | we're going to change some of these inside. Here we have init.py so that's
00:06:18.140 | where we're initializing our streamlit server or app from. We'll go through that
00:06:28.540 | it's fine. We have this front end which is anything in here is the react side of
00:06:37.060 | things so if we go a little further we have some styling the index and then in
00:06:48.220 | here we have these TSX files okay. So in here we're using TypeScript so if you
00:06:59.580 | know TypeScript it's really good if not it's not too much different from Python
00:07:06.980 | I mean it's fairly different but it's not unbelievably different so I think
00:07:12.420 | if you know Python probably read this at least and kind of follow what we're
00:07:16.140 | doing but I also don't really know TypeScript I'd like to just get through
00:07:22.340 | putting something simple together with this. So most of the work we're gonna do
00:07:30.940 | is going to be my component TSX but we are going to modify a lot of these files
00:07:37.780 | as well. So first let's rename everything because everything at the moment is using
00:07:47.220 | default names and we obviously are building a custom component we want to
00:07:53.820 | give our own name that makes it a little more identifiable. So we'll start by
00:08:03.020 | going to my component up here and rename that to STCardComponent. So ST
00:08:15.300 | just streamlet CardComponent. Down here we have my component going to rename
00:08:22.140 | that to CardComponent. Basically anywhere that we have my component we
00:08:29.260 | modify to CardComponent we update these imports.
00:08:35.020 | Okay so inside CardComponent here if we just find and replace so find my
00:08:50.540 | component and replace that with CardComponent. Place all of those see if
00:08:59.820 | we have anything for my component. No okay. Save that and let's have a look at
00:09:10.700 | the index. I think we also have something here just just my component here.
00:09:21.580 | Okay and replace those. So we have everything in there and in set of pi we
00:09:39.220 | also want to update the name here. So this will change it to Streamlet CardComponent.
00:09:48.060 | Okay so this defines it for our package later on and it's
00:10:00.540 | actually sorry so this should align with the directory folder that we have
00:10:06.460 | here. So not Streamlet but ST. And in our manifest here we also need to
00:10:15.700 | update this to be STCardComponent. So this needs to point to the front end
00:10:23.260 | /build. We don't have the build directory yet but we will. So that needs to go
00:10:28.060 | STCardComponent. Okay so that should pretty much be everything we need to
00:10:40.700 | rename. Maybe other little bits are actually in knit. Here we also want to
00:10:48.820 | change this to STCardComponent.
00:10:52.620 | So here STCardComponent. Anything else?
00:11:07.660 | Okay now that's good. So let's go ahead and actually initialize the current or
00:11:19.980 | the basically default other than the things we've renamed version of this
00:11:25.860 | component and see how that looks. So we'll go to and here we have the
00:11:35.500 | component template. Inside there's a template. So yeah template and then we
00:11:54.420 | have STCardComponent. So in here we also front-end directory and inside here we
00:12:06.660 | have all of our packages and everything. So like the node side of stuff. So first
00:12:14.500 | first things we need to do is actually install the node packages we need for
00:12:22.500 | our component. So to start we just do npm install and let's just try to install
00:12:33.180 | everything from this package.json file. So run that. It might take a moment so
00:12:42.540 | just give it a second. Okay so that's done and next thing we want to do is
00:12:48.900 | install the node packages that are required specifically for the card that we're
00:12:53.580 | going to build. So these are all the node packages we've just installed. They're
00:12:57.780 | extremely to function like the core of the packages that we need but because we
00:13:06.340 | are using this material UI card thing we need a few extra things. So we need to
00:13:14.900 | npm install again. This is kind of similar to like a pip install. Although
00:13:23.300 | specific to this directory. Okay so when we pip install, we install them to our
00:13:30.740 | Python environment. In this case it's almost like the environment is this
00:13:35.860 | directory in this project or react project. So npm install. We need a mui
00:13:46.220 | material, mui icons material, icons material, motion react and also in motion
00:14:05.180 | styled. Now I think this is probably going to give us an error.
00:14:11.860 | I see. Okay so yes we get this error. We have a dependency conflict with I
00:14:21.460 | think I remember correctly. Yeah so we have a stream component template and
00:14:27.420 | this throws some dependency conflicts with the mui material stuff. So it's
00:14:38.780 | annoying but we can just get around it by adding this legacy peer depths. Now I
00:14:47.980 | haven't I've been playing around this I haven't noticed any issues pop up from
00:14:53.420 | using this legacy peer depths but obviously you just need to be aware like
00:14:58.900 | don't just throw it in there all the time. But in this case it seems to work
00:15:04.300 | fine. Okay so with that we can we should be able to run everything. So let's go
00:15:18.740 | ahead and do that. First thing we want to do is so we're going to run two
00:15:24.780 | things here. We're going to run within this front-end directory we write npm
00:15:29.380 | start. This is going to initialize or execute the server that hosts our react
00:15:39.540 | component and then we also need to open another terminal window. We also need to
00:15:46.660 | navigate to our template directory so cd documents projects it is component
00:16:00.660 | template templates. Okay cd template and in here we have stcard component.
00:16:15.380 | Okay we have this initpy. Initpy is like a what it's not exactly that but
00:16:26.540 | whilst in development it is just like a template app for just running and
00:16:35.060 | testing our component. So we just write streamlit run init.py. So previous
00:16:44.980 | videos you've probably seen me write streamlit run app.py. This is kind of acting as our
00:16:50.340 | app.py whilst we're in the development stage but once we switch to a release
00:16:58.540 | version this initpy we will modify a little bit and it will not be for
00:17:06.380 | doing this streamlit run. It will do something slightly different. It will
00:17:11.220 | extract everything from a compiled build distribution. So now we have these we're
00:17:21.380 | hosting two servers. We have this localhost 3001. If we if we go over there
00:17:28.340 | open that we're going to see nothing. So this is just hosting our react component
00:17:40.080 | but a react component by itself doesn't actually show anything. So we actually
00:17:44.620 | need to go over and open the streamlit localhost. So that is in 8.5.0.1
00:18:03.540 | Okay and now we have this like template component. So we can click here and it updates
00:18:12.440 | this basically. Maybe you can change this. Enter. Yeah we get this. Okay so that's
00:18:21.960 | cool but obviously we want to build a custom component and we'll go ahead and
00:18:31.000 | we'll do that in the in the next video. For now I think we'll leave it there.
00:18:37.840 | We've sort of set up the environment. We've started running the default
00:18:45.340 | component and I think that's good enough now and yeah in the in the next video
00:18:51.020 | we'll be able to really focus on actually building the component itself
00:18:56.960 | which means we're going to be toying with code over in Card Component TSX
00:19:04.100 | quite a bit and clean this up and yeah creating our card. So I hope that's been
00:19:12.420 | useful. Thank you very much for watching and I will see you in the next one.