back to indexStreamlit 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
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: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: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.