Full Stack Flask, React, and Postgres, pt. 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] welcome to this full stack tutorial we're going to be building a small application using flask and postgres on the back end and react in the front end for this video we're going to focus on getting our back end set up so a couple things that you need to make sure you've got installed number one is python uh in this video uh at the time of recording python 3.10.0 is the latest so that's what i'll be using make sure you've got postgres installed as well and follow the directions for your operating system i'd also recommend leaving pg admin checked because i'm going to be using that it's an interface that allows us to interact with our database uh directly through uh through a gui and then postman is a tool i'll be using uh you can see a screenshot of it here but basically it lets you test your api endpoints in this interface which is super helpful when you've only got a back end set up so as far as our project structure so recently had a little baby and i've got to track lots of fun things like diapers and bottles and so i'm going to be using that as inspiration for this project so i've got this baby tracker application uh or directory rather uh set up and then within it i've got a backend directory with nothing in it for our front end i'm just going to add that directory as well and that'll house our react app um you can structure this however you want you can make them separate entire directories if if that's how you want to do it but for uh for this project i'm just gonna keep it all in this one kind of parent directory so i'm in the uh the back end directory and before we start make sure that you've got pip and installed so pip install will install packages globally on your machine and make them accessible anywhere pip end if you're like me and you're coming from a javascript background is kind of similar to um like how package.json is set up using npm or yarn so this is going to tie our dependencies to this project specifically rather than having those uh dependencies just kind of float in uh in no man's land so i've already installed this i'm not going to run that but go ahead and install pip end if you uh don't have it and then to activate it we'll run pip and shell and it looks like i might have an uh a stale virtual environment so let me just kill this terminal i'm in baby tracker cd back into back end and now run pip and shell again cool and so here's my uh the location for that virtual environment just in case i'm going to copy this and then i'm going to control shift p and if you don't see select interpreter this was just recently used you can just type in python colon and then select interpreter and we want to make sure that we're using the right virtual environment so it gives a couple of suggestions none of which match this back end so what we're going to do is enter interpreter path i'm going to paste this in and hit enter and now you can see down at the bottom in vs code we've got the correct virtual environment uh python interpreter so i'm going to run clear and we're going to install the dependencies that we'll be using for this project so pip and install flask which is going to be our our main framework that we're using flask sql alchemy alchemy which is a an orm so if you're familiar with like mongoose if you use mongodb for example this is going to help us communicate with our database since we're using postgres we're going to install psycopg2 to allow us to interact with that from flask to postgres uh we'll use python.env so there are some scripts that you run to set up your environment but we can create an env file that's specific to flask that will just maintain those environment variables for us and then the last one is flask cores so when we're working on this to start and we're using postman it's not gonna be a huge deal but eventually when we're making requests from uh a different local host port or eventually from our front end to our back end uh we wanna make sure that those per those requests are allowed so we're going to use course to do that and this core is dependency so making sure it's like oops i'm going to hit enter okay now that those are installed we can take a look at our pip file and you can see that our packages are all here so this was created through pip envin so now we can go ahead and move forward with creating our initial application so inside of back end we're going to create a new file called app.pi and for this tutorial it's going to be a pretty small project so we're just going to use this one file so at the top we're going to import flask and we're also going to import sql alchemy there's some standard boilerplate but typically looks like this so we've got the name of our application app equals flask so we're instantiating the flask class and then we're passing in this underscore underscore name underscore underscore this is typically how it's going to be set up uh but essentially what we're doing is just like saying hey flask like this is where our application is running uh and so we're instantiating in here and passing in this underscore underscore name so it's pretty much always going to be like that and then we'll get our sql alchemy hooked in with db equals sql alchemy and we'll pass in our app then at the bottom we'll say if name equals underscore underscore main then we'll run our application and so typically here then we could run our application but it by default it's going to run in production mode so i mentioned before that we're going to install python.env and what this allows us to do is to create a flask env file where we can have uh some default information so inside of backend i'm going to create a new file called dot flask env and here we're gonna let flask know the name of the app the flask app is app and the environment uh is going to be develop or development okay so from here now if we run this we don't have really anything set up but if we run this we can run flask run and we can see that the environment is developed and our uh application is running on uh this is essentially localhost 5000. so if we wanted to set something up just to kind of see uh something in action we're gonna have our decorator here we're gonna say at app.route and we can define a route so we can just say like slash and then underneath that we'll define our uh like route handler so we'll say hello we'll call it and then we can just return a string that says hey so now if i open up postman and i'll bring it over and i can just create a request by default uh if we don't pass in any methods the default is a get request so we can do localhost 5000 and send it and we can see our response hey pretty quick setup so in 12 lines of code we've got a little mini application set up already so having it say hey is cool but it's not really anything actually useful so let's take this a step further in uh postgresql i mentioned we've got a tool called pg admin so i'm going to drag that over and i've got a couple of databases here so if you open it up if you open up servers and then postgres sql you should see a list of databases and it should come with one by default postgres and you might see a couple of other ones in here um you'll want to make sure that you know your the password that you set up because we're going to be referring to that but uh on databases i'm going to click and uh say create database and i'll say uh baby tracker and hit save and so now i've got a brand new uh database and so now we need to hook into that so in our app.pie uh we can set up a config for sql alchemy so we'll do app.config let's move this above whoops let's move this above our db so app.config at sql alchemy underscore database underscore uri and so for right now that's going to equal postgres colon slash slash and then uh it's going to be the user so we're using the uh the root user postgres your password sorry postgres colon your password at localhost slash the name of our database which is baby hyphen tracker and save that the next thing that we want to do is create our model so before we uh hook into our database so we've got it set up here um we're going to create our event model so we're just go we can call it whatever you want i'm going to call it an event so a bottle a diaper change whatever i'm classifying as an event so underneath db i'm going to define a class called event and then pass in db.model so remember we create a db here so uh passing in db.model and then we're going to give it a couple of columns so the first of which is going to be an id so we want to give it a unique identifier when we're doing things like editing and deleting and updating uh editing and updating the same thing but editing updating and deleting uh uh but it's important to have some sort of unique descriptor other other than just whatever kind of string that you're passing in so you create a column by saying db.capital c column and then we're going to give it a type the type is db.integer and then we're going to say primary underscore key equals true so this is the the we're setting this as the primary key next we'll have a description and this will be another column and this is going to be a uh we can say a string and we can give it a max of like 100 characters and this should not be nullable so we'll say nullable is false so we want uh to always have a value for description and then we can give it a created at just for another kind of reference point for us so we can see uh db.column and this is going to be a date time type we're going to say it's uh also not nullable and we'll give it a a a default value so we'll say default is equal to and we're going to import a date time so from date time import date time and so we'll say datetime.utc now and that should be good for our columns then we're going to give it a string representation of itself and we do that by saying uh def underscore underscore representation our repr and they it gives us our uh vs code just kind of auto filled this for us but i'm gonna undo that so underscore underscore and then it takes in self and we can say we'll return an f string an f string in python just allows you to uh inject uh python variables so we can say event and we'll say self.description so this is referring to the event itself and then we need to give it a [Music] set up our constructor so we'll say inet and this takes in self and description the uh the created ad and the id so we're the created at uh we're giving it a default so we're not gonna uh worry about passing that into the constructor for for this uh step if you were going to get to a point where you had like an updated ad or you wanted to um allow the person to enter like a specific time then you could pass that into the constructor but since the only thing that we're actually going to be like submitting is a description then the description is the only piece that we need to pass into the constructor so with self and description passed in we can say self.description equals description and so now our event model is set up and so what we can do to then get this uh in our database is we can create a new terminal and we can say python to get our uh python shell running and then we can say from app import db and let's make sure so we're in baby tracker okay gotta exit out of this so we'll hit exit and uh make sure we're in back end and then run python again whoops python and we'll run from app import db and then from here we can run db.create underscore all and what this will do is it'll create our uh our table for us so our event table by default since we didn't give this an explicit name this table is going to be called event so if we run this okay so dug in a little bit and the issue was that uh my uh password was incorrect and the uh i had postgres instead of postgresql so make sure you've got postgresql and then postgres colon password at localhost slash and then the name of the table so i did run uh from app import db so after killing the terminal updating the uh database uri and then running from app import db and db to create all those ran successfully without error this time and so if i bring over uh postgres there's baby tracker i can hit refresh go to schemas and then tables and now we have our event table and i can view and edit data and look at all rows and i can see an id a description and created app so let's go ahead and get some data going in uh our database so we have this hello route uh kind of a meaningless route so let's go ahead and create a an api route so we can say we'll have another decorator so we'll do app.route and then we'll do uh event so slash event then we're going to pass in uh methods a methods array and you can pass in since it's an array or a list you can pass in multiple methods i'm just going to do one method per endpoint for this but you could potentially um pass in multiple methods and use if statements if you wanted to try and consolidate so we'll do methods and we'll do a post request so that we can create a new event and then we'll define it so we'll define by saying create underscore event it doesn't take in any arguments and then we'll say uh we've got a description so we can say description is equal to the request that's coming in dot json so request.json is going to give us the json object that's coming in and we want to pull off the description so request i'm getting a squiggly line that's because it's not imported yet so at the top i'm going to import a request then going back down to our description so we're then going to create a variable called event and what that's going to do is it's going to take our event class and pass in the description that we pulled off of the request and then all we need to do is db.session dot add our event and then we need to commit it so db.session.commit and then what we can do is we can uh for set up a little like formatter so let's make a method underneath our event class and we'll define it as format underscore event it's going to take in an event and then it's going to return an object this object will have a description which is going to be the event.description it's going to have an id which is the event id and then the created at will be the event dot created app and so what this is allowing us to do is it'll take in our event and it'll format it so that we now have a a json object we can take that json object and pass it back to our front end so that it now has access to that information if we want to use it on the front end without making an additional network request so going back down we've got our commit and then we're going to return uh we'll format event and we'll pass in the event that was just created so again what's happening here we uh have our decorator which is going to be a hitting slash event we're passing in a uh a post request as the method the singular method and our requests array and then we're defining our function so create event our description is going to grab the request.json body and we're going to grab the description off of that object we're then going to create a variable called event which is going to pass in the description to our event class we're going to add that event to our session and then commit it and then we'll return our formatted event so that uh in this case postman but in the future our front end can grab that information and do something with it so now if i switch over to postman i can switch this to post and i can do slash event and in the body we can go to raw and json and we can do a description and we can say a 50 milliliter bottle and if we send this now we have not only our description 50 milliliter bottle but we've got the id that was automatically created for us and our timestamp and if we look in postgres if we refresh our event if we view and edit data now we can see our table now has its first row uh an id of one the 50 milliliter bottle and the created at time stamp pretty cool so now that we have at least one bit of information we can start chipping away at the rest of our method so typically with a rest api you're going to have create read update and delete methods so let's go ahead and do that so we have our create event let's go ahead and set something up too get all of our events so i'll comment up here create an event and then i'll comment that out here will be get all events so we'll create our decorator app.route slash event and in the sake of can for the sake of consistency let's call this events so slash if we'll post to slash events we'll uh get from slash events uh we don't have to add a method uh array here since get is the default but to make it more explicit we'll go ahead and add it so we'll say methods equals an array and then get will then define get underscore events and then from there we'll create a variable called events we're going to get our event class and we'll use event.query and from here we could uh we could do like an event.query.all but something that's uh nice about sql alchemy is that you can uh there's a variety of different methods the the one we're going to use now is this order by so after query so actually just get rid of the dot all for now so query dot order by order underscore by and we'll do event dot id and we'll sort in ascending order and then dot all so we only have one event uh for now but as we create more events it'll be nice to have them in a nice neat order so you can order by uh id in this case and uh since it's automatically incrementing so the next the next um well i'll prove it to you so if we go to events so i hit save and if i want to uh create another so let's say 100 milliliters this time and now we hit send it's got to be two events and now we hit send you can see id is two if we have uh like dirty diaper id is three so it's automatically incrementing so you could sort by created ad and that would work just as well but since the id is automatically incrementing anyway uh just easy just to sort by a an integer a single integer uh okay so we are getting all of our events so our events are going to order by the id from there we're going to create an event list which is going to be an empty array to start or an empty list excuse me and then we'll loop over our events so for event in events event list dot append and what we'll do here is so basically we're grabbing all of the events we have an empty array and we're just going to push each event to this list so we'll append the formatted event by saying format event so we're formatting the event each event in that events uh list and then what we'll do is we'll return an object where we say events and the events will be equal to that event list and so now we save that and if we go back to postman and instead of a post if we do a get and hit send now we have our events list and you can see it's ordered one two three if i got rid of the order by let's see what we get still in order so that's nice uh might not always be the case so i'm just going to leave that order by in place cool so the next uh next one that we'll do is uh we'll get a single event and so if you wanted to do like an event details page or something like that uh so we can make our decorator app.route and this time we'll do slash events slash id in the brackets here and so this just indicates that id is going to be a variable that we're passing in uh and an uh sorry a query parameter so it's going to grab the event slash whatever the id is in the url and then we'll use that as a variable to pass in and grab that specific event so this will once again be a get request and then we'll define get event and this is going to take in an id which is being passed in here the id we can create a variable say call it an event and we'll say event dot query dot filter underscore by uh where the id is equal to the um the event id so the id being passed in is equal to the event id and then we'll say dot one uh dot you might see dot first in some cases dot first is going to as the name implies give you the first result dot one could error out if there's more than one but since we're filtering by id and the id is unique we shouldn't run into that issue so we can use that one then we'll say formatted event is equal to format event and we'll pass in that event and then we will return the event as the formatted event we can hit save and so now if we switch over and we do slash events slash 2 we should see the 100 milliliter bottle and we do okay two more so we want to take care of deleting events and then we want to take care of updating them as well so we've got our single event underneath that we can delete an event so same setup app.route actually let's go ahead and just copy this but instead of a get we'll do a delete and so this is one example where like if you wanted to do like delete you could do something like this uh where this would be like if request uh request.method equals um get then then do this uh but to my eye it doesn't look as clean because then you have like get and delete and then your names are you know not as specific or whatever so i like to keep them just one by one but you could do this if you wanted to but we're not so let's undo that okay so uh we've got our delete and then we'll say um we'll define delete event and same thing it's going to take in an id which it's grabbing from the url so we will say uh same same deal uh as before where we're just grabbing that event uh and we're filtering by id and we're grabbing one and then all we need to do is db.session.delete whatever event that was and then we'll commit it and then we could say return to do or sorry event deleted and if you wanted to do like an f string you could say event uh parentheses id and then the id that's uh passed in this is fine as well so let's try this um bringing postman back over so we got our event slash two so now let's delete that one and we can see event with an id of two is deleted now if we go to get and we do events now we can see just one and three so the last one we want to set up is our update so we'll do app.route and again we can just grab this one actually again and we'll update it so we'll say edit an event and this will be a put and we'll say define update event and this once again will have and i take in an id uh and here we're going to grab our event or we'll say event.query dot filter by and then the id equals the id but we're not actually going to grab one we're gonna grab the list there are a couple of different ways to uh to update um items in a in a table uh using sql alchemy this is just one way of doing it so we're gonna grab the the list and in this case it's gonna be a list of one and then what we'll do is we'll say that the description is equal to the request.json at the description so similar to our post and then from there we'll say event dot update uh and we'll uh we'll have a new you can see a new empty dictionary mapping and from here we'll say the description is equal to the description that uh we grabbed from the um request and then we'll also update the created at so we'll say created at is equal to datetime.utc now and then we'll actually call it and then from there we just need to commit so we'll say db.session.commit and we'll return our updated event so we'll say event and we'll format it format event and we'll say event and now we can do event.1 which in this case event is still a list and we'll just chain on uh one so the the reason that we did um one here as opposed to up here is that update this event.update update that method can be chained off of filter by but if i were to do event of query.filterby.1.update that wouldn't work so this is just my way of breaking it breaking it out so now if i save this and i flip back over to postman and let's bring it over so i've got uh id of one so we'll say event slash one switch this to a put and i'll change my description to be a another 100 milliliter bottle and i'll send this and now i've got id 100 milliliter bottle and just to show you that let's say i put this to like 75 so let's look at the created ad and let's look at the description so it's 75 and you can see that created that timestamp changed so now if i make a get request i should still see that event which i do and if i go to all events i've got the 75 milliliter bottle and i still just have one and three so all of our endpoints now work so the next step is hooking these into our front end so in the next video what we'll do is we'll set up a react app just using create react app and we'll create a very simple interface for listing out all of our events editing them adding new events updating and deleting as well so go ahead and come back for that one
Info
Channel: Chris DeSilva
Views: 31,623
Rating: undefined out of 5
Keywords:
Id: RcQwcyyCOmM
Channel Id: undefined
Length: 39min 25sec (2365 seconds)
Published: Fri Nov 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.