Transcripts
1. Introduction: In this course, we're going to create a cool profile page that looks like this. Now the super cool thing about this profile page is that it is driven by Google sheets. So I have a Google sheet here that if I edit this sheet, we'll change this webpage. Now this webpage is deployed on Google Cloud R1, and the course covers that as well. So let's just prove that this works. So let's say I suddenly decide that I have five years experience in MongoDB. I can just change that. Go back here. And it says two years experience here. But if I click Refresh, suddenly I have five years experience. And let's get a bit more serious here and say that. Yes, def lay went to a human, the city. Like so. Come back here, click refresh. And I, I definitely went to a university. Now the other cool thing about this is that we have a contact page here. And in our Google sheet, again, we have this contacts worksheet. And at the moment we've just got one contact in here. But if somebody else wants to get in contact with us, let's say Fred blocks. And he is Fred at Gmail and he wants a website creating. We can definitely help him out there. And so he's going to send a message, comes back to our homepage. And then if we go back to our worksheet, you can see that Fred has contacted us through our Google Sheet, which is super cool. We're gonna be using coal technologies like Python, three flask, bomber, Docker, Google Container Registry, Google Cloud run. Obviously Google sheets. You're going to learn an awful lot in this course. And this course is only an hour long. You're going to be touching on a lot of new technologies and getting a taste of what's possible with modern web application development. I hope you decide to take the course. And thanks for watching.
2. Software Prerequisites: For this course, you will need to install the following software. If you go to Docker.com, forward slash gets started. You can install Docker desktop for your particular OS. They do versions for Windows, Mac, and Linux. Once you have installed Docker, then if you go to code dot Visual Studio.com and install Visual Studio code again for your IRS. They do versions for Windows, Mac, and Linux. Once you have installed those two pieces of software, you are ready to start the course.
3. Hello World Reloaded: Okay, so if you open Visual Studio code and go to File and open folder, and now we're gonna create a new folder and I'm gonna call it flask profile. Click select folder. And we will create our main python app file. So right-click and choose New File. And let's call this AP dot. And before we go any further, we want to make sure we have an extension called Docker. So if we search for doctrine here, and it should be at the top here. So if you click on that and make sure you install that, I've already got it installed. Once you've done that, close that and go back to files. And then now if you hit F1, you'll get this command line up where you can search for certain commands. And so if I search for Docker, I get a whole list of options. And the one we want is add Docker files to workspace. So if you click on that, and then this will scaffold out some Docker files for us. And so we want the Python Flask one. So if we click on that, and our entry point is this app dot p y. So let's click on that. 5 thousand is fine for the port. And yes, we might as well include our docker-compose files as well. And so now this is scaffolded out all the Docker files that we will need actually. So that's kind of handy. So we've got our requirements. So that's flask and unicorn. We have our docker file, which is used to build our image, and a couple of docker-compose files. And importantly under VS code, we actually have some files here that help with debugging. So we now can actually debug our code within the Docker container using VS Code, which is very cool. Now we do want to make some small changes to this task dot JSON file to enable us to do hot reloading one when we make an edit in this app.js file. So that's pretty simple to do. So we need to come down here under ENV, we need to add flask, underscore ANOVA. And we want to specify that we're in development mode. That will mean that flask will restart its web server every time we make a change to our file. And then underneath this in V group, we need to create a volumes section. And so inside here, we need to specify a container path, which is in an app folder in our container. And the local path, which is actually the workspace folder that we're in. And then the other small change that we need to do is we need to remove these two lines here. Because we do want to use the debugger and we do want to do hot reloads. And if we control S to save. And just so you know, why I know that this is slash app is because if we look in our docker file, we can see that we've set our working directory two slash app there. So that's why this needs to be slash app. Now if we go back to our app.js, let's start creating flask implementation. So this is fairly boilerplate code for creating a Flask app. Okay, so let's see if that works. So if we hit F5 now, or choose Run and start debugging, and I'm just gonna hit F5. And that will go away and creates our Docker container. And as you can see, we have our helloworld working here. Now let's just check that hot reloading is working. So if I make an amend here and put some exclamation marks on the end and safe. We should say that we are now reloading the Web server. And if we do a refresh, we get those exclamation marks on the end. So we have quite a nice development environment here that's been scaffolded out rather rapidly.
4. Index Template - A Start: So the next thing we want to do is actually set up a templates folder and a template. So let's do that now. So if we right-click and do new folder, and we create a folder called templates. And then inside this Templates folder I will create a new file. And we'll call this index dot HTML. So to quickly get up and running with index.html template, we're going to use CSS framework called Bohmer. So if you go to bomb it, I documentation, overview start. And if we scroll all the way down, we have a kind of starter template for Obama. So if we select and copy or just click copy here, come back to our index.html and just paste it in here. Boehm was quite nice in that it really only needs this one CSS file to work, but that saved as a little bit of typing. So if we save that control is to save. And then to show that template, if we come back to app.js file and we now from Flask need render template. And so instead of just returning a string, now, we want to render template. And what template to we want to render. Well, it's high index.html. And so if we save that, we should get a reload. And if we click refresh, we see our helloworld, my first website with Bulmer. Now if we go back to our index dot HTML and we come down to our body area. And we will delete everything inside this first section. And we'll start writing our own code here. So the first section is going to have our profile image and then just our name and Twitter handle. So we can put in an image using this figure tag. And we're going to say this is an image. So also a container which helps us centering. And then we want it to be a 128 by 128. And then we're going to put an image in here. And we're going to have it grounded. So Bohmer gives you lots of really handy classes. Things like is rounded, which really saves you going away in having to write CSS, your NCSS for this, you go to class are already, will give you rounded images. And then for our source, well, we want a profile image. But if you haven't got one to hand, let's say if we can use say, cat image or something. So I just do a link to your profile image here. We'll use something like cat as a service to get an image back that's preferably square. And then if we take a look at that, we can see we've got a cat hair. Now underneath this, we want to show on name, specify it on my name ham. And then underneath this, we're going to have a subtitle, which is your twitter handle. We save that. Go back and refresh. You can say, see that we've got a title and a subtitle. But the first thing we want to do is you want to send to these underneath image. So that's nice and easy to do in Bohmer. We can just say has text centered, save, go back and now we have sent a text. And also if we're not happy with this size, I mean, this looks pretty massive. So if I want to fix that and children gotta fix that, that that needs to be An equals. So yeah, I don't like that. This is so big. And this is pretty big as well. Okay, so we can say something like Is Dash full, save. And that makes that a little bit smaller. And then we can play around with the size of this as well. So I can say, is dash six, say save. And that looks a bit smaller up further Atlas better. And there's not much of a gap between our image and our title. So we can easily fix that as well because balm is awesome. So we can just do a bottom margin hair of say, full. Save that, refresh, and we got a little bit more of a gap. Now this grant.
5. Index Template - Buttons: So now we want to add a couple of links. Below here. A contact link and another link can be linked to anything come just linking to YouTube. So, but let's have these links look like buttons. And we have some fears default colors in Bohmer. So I'm going to use is info, which will give it a default color. And I'm gonna use an outlined button and a rounded button. So the moment is H ref is not gonna go anywhere. But we'll fix that. And we want this to be contact. And I'm just going to copy that line because I want the YouTube to be similar, but just a different color. Danger I happen to know is a red color which suits YouTube. Everything else the same. And I'm just going to call that YouTube. So if I save that, take a look at that. So now we have two buttons side-by-side like so. So that's the end of our first section.
6. Index Template - Main Section: So let's start on our second section now. Now this section is going to have two columns. So I'm gonna give this a class of columns to tell it, to tell bomber that we're using columns. And we actually want to start off with one central column that takes up three-fifths of the page and is in the center. So we can do that pretty easily. First of all, we have to say that this is a column. Then we can specify the width we want. So we want it to be three-fifths of the page. And then we went to in the center. So it's going to have to be offset by 1 fifth. And I want to give it a background and just quite a light background. And I've just put some junk in here for the moment, save that. So if we take a look at that, it doesn't look like it's working here. Because that's, but that's actually because columns don't kick in until the width is over 1024. So if I stretch it and you can see that our column is actually working, and we've got this central column underneath our first section. And so within here we want to put in a couple of columns that we can fill in with some profile information. So let's do that now. So we want another div, and this time we want two columns. So we tell that div that it's going to contain columns. And we're going to have two columns. And we actually want each column to take up half the space. So we say column is half. And I copy that and paste that. And again, then we have our two columns. And if we save that and go back, we can say, say that we've got two columns taken up half and half. So in our first column, you want to create a card. And I'm going to actually start using Emmett to make this a little bit quicker. Where you can do is you can do div. Dot tab. Now let's actually create a div with a class of card. It's quite a nice little shortcut. And then I wanna div if current content. And then I went to one class of title. And that's going to be about and then I just wanna pay tag. And I'm just going to say for the moment about me, dot-dot-dot. So that's our first card inside our first column. So let's create another card which is gonna be identical below this. So I can just actually copy that. And I'm going to call this interests so that I want to give this cart a little bit of a background so I can set, say has background. I'm gonna give it one of the colors that Balmer gives me. So let's have a look at that. So that's fine. But as you can see, these are too close together. So let's fix that now. So we can basically put a margin around these counts. I'm gonna say m three x. If I refresh a little bit of a margin now, okay, let's just change my zoom a bit. I was zoomed in just so make things a bit clearer, but we're not really seeing the page very well. So let's make, let's, you zoom down to a 100%. And so you can see the whole page now a little bit clearer. Ok, so let's fill out the second column now. So what we can do is saying is we're lazy, is we can just copy in this column here and just paste over the top of this column here. And instead of about me, I want this to be Experience and Education. And let's do some backgrounds for this one as background. And then I'm gonna do primary light. I'm gonna change this to background warning light. And let's see how that looks. So that's looking pretty good except we've got this kind of large gap here. And the reason for that is that we have sort of default gap between the first two columns. So let's just sort that out. So in here, we can say is gap plus I and II, we don't want a gap between those two columns. And then if we refresh omega less, little bit better. Okay, so we kinda scaffolded out Profile page now. And so now we want to pull in data from a Google sheet that we're going to use to fill out these cards. So that makes it super easy for as to if we decide we've got another interest. If you're like me, you get a new interest every other day. Instead of going back and having to deploy the sight or anything, you can just go into your Google Sheet and add the interest in here and it will just pop up. So let's do that next.
7. Sheets Setup: Right, we now want to enable reading and writing to a Google sheet. And we're going to be using G spread for this. So if you go to g spread dot read the docs dot actually goes through how to do this. So we're gonna go to our Google Developers console. And if you click on this drop-down box here and create a new project. And then I'm going to call this flask profile. And click Create. And then make sure that project is selected by going in and selecting it. And then if we enable APIs and services, and we want to enable the Google Drive API. So if you type in Drive and should find that one. And then click Enable. And then if we search for Sheets, click on the Google Sheets API and enable that one. And then if we go down to credentials and click there, and then click on Create Credentials and choose service account. I'm going to call this flask profile. And then click Create Named, just click continue, and then click Done. And then if we click on manage service accounts. And then if we click on these three dots here and choose Create Key. And then we want to choose the key type of JSON and click Create. And then save that. You then want to copy that JSON file you just downloaded into your workspace folder. And then I'm just going to rename my flask dash profile, like so. And if you have a look at it, you should see that you've got all this sort of information in there. Now what you actually want to do is you want to copy this email address here. And then you want to create a Google Sheet. And I've called Mind flask dash profile. And the important step here is that we need to click on Share into paste in that email address, and then click on it to choose it. We can take now to phi and we want to click Share. So now if we go back to Python app and in requirements, we need to tell Pip to install g spread. So we type in ci spread into requirements. And then that will make sure that this line here installs the G spread module using PIP, which is a package manager for Python. And so this will enable us to go back into our app and import G spread. And then underneath here, we can set up J spread with the service account that we just created using that flask profile dot JSON file. And that will enable us to open that spreadsheet. Now we're going to use two worksheets in that spreadsheet. The first one, we'll just hold on profile information. And the second one will handle the contacts page. When we've got around to writing it. And for a quick test to see if this works, we will just try to add a dummy contact to that second sheet. So if we save that, and let's go back to our shape and add a new sheet at the bottom here. And let's rename these profile. So that's the sheet at index 0 and contacts like so. And then if we go back to our page and refresh it, and that's correct. Actually, we haven't got this module because we actually have to rebuild our image so that Pip can install this extra module. So let's go back and do that. So if we stop that likes and hit F5, that will rebuild the Docker image. And if we go back to our sheet, we should see, depending on how many times you've click refresh, you should see that we have successfully written out to our Google Sheet.
8. Sheets Profile: Now, if we go back to our profile page, we're going to want to have a row where we specify the contents. One for interests on, for experience and one for education. And if we make this a little bit bigger so we can type something in here. So I'll just say my name. Walden, dot dot, interesting, dot-dot-dot, question mark. Experienced and the staff. And so educated I can spell education. Also. Got education. Okay. So let's pull these into our webpage so that we can see them in here. So that's pretty simple to do. We come down here and we'll set up a profile dictionary object. And we'll say about and we're going to use SH profile. And we want to look into specific cell in that worksheet, which is b1. And we want to value if that cell. And let's copy that. And to interests, Experience and Education. And that was going to be B2, B3, B4. Save that. Now we need to pass this through to our template. So the way we do that is by doing profile equals profile. So I'll template will have access to this profile object. So if we go into our template now and we can simply find are relevant cards. And instead of putting about me like that, in net's double curly brackets, we can do profile dot about. Let's copy that. Peripheral dot interests per file dot experience profile.edu. So now if we come back here and do a refresh, as you can see, we now have the information from Google sheet directly into our profile page. So say if I want to expand that out, I can just simply go into here. So come back here to refresh. And that immediately pops up in here. Now there's some other cool stuff you can do. Like perhaps you might want to send across some HTML styling so that some perfectly possible. So I'm not gonna do that with about, but let's do that for the other ones. So if I do, if I remove things so I didn't have any existing styling and have to supply it myself. And what I need to do. At the end of this, I can say safe. And that means that we will render the HTML because we have designated it as safe HTML. And then a moment it went look great because we haven't, we've already got the paragraph here, but nothing here. But let's, I'll paste in some stuff into the spreadsheet. So if I paste in some HTML I prepared earlier, so I've pasted that in now. So if I go back here and do a refresh, as you can see, we've got some unordered lists. And you can actually put any kind of HTML you want in here. And it will be reflected in your webpage.
9. Contacts: Okay, so let's start work on our contact form now. So if we right-click on our templates folder, choose New File. And we will call this contact dot HTML. And let's just cheat a bit and copy over some of the HTML from this index.html. In fact, before we do that, let's just fix this title here. So let's call this my profile page. And let's just copy all of this into contact. We will get rid of these two sections. And we'll call this contact page. Okay, so this is just going to have one section and it's going to contain a form. And that form is just going to consist of one column. So setup columns here. And we're actually going to do a post request to our main index.html page when we click the Submit button. So I'll show you how that works in a little bit. So let's set up a single column. And we want to make sure the text is on the left. And this is going to be, again three-fifths. We have an offset of 1 fifth. So let's create our first failed. And a field is just a container for a label and a control. And it's due label first. This is going to be on name field. And so gray TO control, which is just an input type of text. And we're going to name this input name, which is important when we want to access this as part of the post request. Okay, let's create another field, going to be the email field. Now we want to label and I'll start using it just to speed things up. So we want to input control. And we want to name the same. And our last field, which is going to be I'll message failed. So many Nader label. Who's his message. And control is going to be a text area because the name of message can delete this. And finally, we're going to have a button that says send message. And this is going to submit a post request like soon. So if we type contact in here, we can't find it because I'm going to root for it yet. So let's sort that out now. So if we go back to app dot PY file, and let's create a route for contact. So we create a function called contact, and this is going to return the contact dot HTML template. So now if we refresh, we should see our form here. And it's not quite working correctly because this should be in the center. So let's see what's going on there. Okay, so made a slight mistake here. So instead of ISAF offset 1 fifth needed dash in there between the one and the fifth. So if we save that and go back and do a refresh. As you can see now, a contact form is centered correctly. So be quite nice if they send message button went across they form and was slightly nicer color. So let's sort that out now. We'll make it a blue color and we'll set it to full width. And then I think it just needs to be a little bit bolder. So let's solve that out. Okay, so I'm happy with this Contact Form now. So let's make it so we can get to the contact form from the button. So we need to amend this H ref. So the way we do this in Flask is we use this for function and we actually pass it the name of the contact function, like so. And then let's just put in the H ref here for your YouTube channel. So I'm just going to paste my Youtube channel in here. So if I click contact now, I should take us to hear we've got no way getting back. So let's fix that now. But let's just check that YouTube works as well. Yeah, that's good. So let's just put in a close here so we can get back if we don't want to send a message. So if we go back to our Contact dot HTML, and we'll just put another field at the top here. And this will be a link of class delete. And again we'll use all four. But this time it's the home function. And we want our delete button will close button to be large. And we want to pull right over to the right. If we save that. And now we have a close button here, which we can click on, and it will take us back to our homepage. Okay, if we go to a contact form and we click on send message, we will get this method not allowed because we're trying to do a post request to our home function. And if we take a look at that home function, it just has a default app which only handles get requests. So the way we fix that is we specify the methods that we can use. And you want to say we can do a post method and the get method. So now if we save that and click here, it's now happy and goes back to here and has done a post request here, but where we haven't handled it. So let's handle that request now. So from Flask, we want to import requests so we can handle different types of requests. And what we want to do is you want to say if the request method It's equal to post. And we actually want to do very well this line here. So let's take this, cut it because we're gonna wanna do, we wanna do it down here. But instead of appending Bob, every time, we want to upend what is coming into here from our form. And so we get two form by doing a request dot form. And then we specify the name of the control. So if I copy that, paste that in here and we know we're sending for the name, the email, and the message. So let's say that. First of all, let's go back to our spreadsheet and go into contacts. And we've got a lot of Bob's in. Let's delete Bob. Let's go back to page. Get a contact. And if you click send jetpack, Jamnagar. We've appended the information coming back from the form.
10. Deployment: Let's deploy our site now. And since we're using Google Sheets, why not deploy our site using Google Cloud to if you go to cloud dot google.com forward slash SD clay docs install. So you want to install the Cloud SDK for your system. So I'm on Windows, so I would download and run this Cloud SDK installer. So follow those instructions here and get that Cloud SDK installed. Then we're gonna come back to Google Cloud Platform console. And again inside a flask profile project, we are going to want to search for the Container Registry. So if you click on this and we want to enable the Container Registry API. So if we click here, that's enabled the container registry, but we haven't got any repositories up there at the moment. So this is blank. If we hit refresh, we went Say anything in here. That's fine. So if we come back to VS code now, now inside our docker file, we actually need to change this line to make it a little bit happier for Google Cloud. So if we comment this line out and then I'm just going to paste in the line that's needed. So it's quite similar, except that it needs this port here and it also specifying the works and threads through we want to use. So I'll leave that on the screen for a second. You can always pause the video and just type that in. And so let's save that troll s. So first of all, we need to make sure we are in the correct G Cloud Project. So if we do G-Cloud config set project and our project is called Flask dash profile. So let's build Docker image. So we can do docker image built. And we need to tag it with a very specific name, which is g x0 dot slash flask profile. And this must be the name of your project. And then I'm just going to call my image flask dash profile as well. And I'm just going to use tag one. Can be anything. And I forgot to put the dots on the end. So you gotta do space. And to say that we're building the working directory. Okay, so that's built the image. So now we want to do a docker. Push forward slash flask profile slash flask profile, carillon tag one. So that's pushed our image to their posit train. We can double-check that by going up here and clicking refresh. And we've got our floss profile image in there. And now we can do G-Cloud. Run. Deploy. Dash, dash image, g dot slash, flask per file, slash flask dash profile, curl on Guam. And we want to choose option one cloud around fully managed service name is correct, so I'm just going to hit enter. So Google Cloud R1 is not enabled on this project yet. So we do want to enable it and retry. So let's say yes to that. So that enabled that successfully. And we want to choose where we want to deploy it to. I'm just gonna say the US East one. I'm going to say yes to that because it's a public webpage. And so now we should be able to go to this a and C are running application. And then you go, we have deployed web page to Google Cloud ram. And the good thing about Google Cloud run is it gives you a fully working HTTPS webpage. So you don't have to do anymore setup to get that working. So that's quite nice. And then of course, you can always set up a custom domain here as well.