WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:03.210 --> 00:00:06.540 CARTER ZENKE: OK, well hello, one and all, and welcome to CS50s week 00:00:06.540 --> 00:00:09.720 9 section, this week where a lot of it comes together. 00:00:09.720 --> 00:00:10.770 My name is Carter Zenke. 00:00:10.770 --> 00:00:12.750 I'm the courses preceptor here on campus. 00:00:12.750 --> 00:00:16.140 And the goal of these sections that we host online 00:00:16.140 --> 00:00:18.600 is to help you bridge the gap between lecture 00:00:18.600 --> 00:00:20.680 and this week's problem you'll be working on. 00:00:20.680 --> 00:00:23.550 In this case, you're building our own web application using Flask. 00:00:23.550 --> 00:00:26.730 And so today we'll dive into these three topics here. 00:00:26.730 --> 00:00:29.910 Flask and Jinja, how we can use forms in our websites, 00:00:29.910 --> 00:00:33.390 and how we can work with databases and build more dynamic applications 00:00:33.390 --> 00:00:33.970 overall. 00:00:33.970 --> 00:00:36.360 So I thought to kick things off, we do what we normally 00:00:36.360 --> 00:00:39.685 do and maybe on the count of three, we'll all unmute and say hello, 00:00:39.685 --> 00:00:41.560 so a big chorus of hellos to kick things off. 00:00:41.560 --> 00:00:42.750 So on the count of three. 00:00:42.750 --> 00:00:45.693 We'll do one, two, three. 00:00:45.693 --> 00:00:46.360 AUDIENCE: Hello! 00:00:51.560 --> 00:00:52.560 CARTER ZENKE: All right. 00:00:52.560 --> 00:00:54.600 It's so good to hear all of your voices here together. 00:00:54.600 --> 00:00:57.678 And again, our goal will be to go through these three topics right here. 00:00:57.678 --> 00:00:59.470 And again, this is going to be interactive. 00:00:59.470 --> 00:01:01.900 So if you have questions about these three topics as we work through them, 00:01:01.900 --> 00:01:04.140 please feel free to message them in the chat or chime 00:01:04.140 --> 00:01:06.600 in when I ask for responses here. 00:01:06.600 --> 00:01:08.970 Now we'll dive into Flask and Jinja. 00:01:08.970 --> 00:01:13.290 And as we saw in lecture, Flask and Jinja are these two-- 00:01:13.290 --> 00:01:15.750 well, Flask is more like a framework we can use 00:01:15.750 --> 00:01:19.800 and Jinja is this templating library we can use along with Jinja. 00:01:19.800 --> 00:01:23.670 But the goal is to build more dynamic applications than you could 00:01:23.670 --> 00:01:27.330 with just HTML, CSS, and JavaScript. 00:01:27.330 --> 00:01:29.640 So we saw those three languages-- 00:01:29.640 --> 00:01:32.700 HTML, CSS, and JavaScript-- in the prior week, week eight. 00:01:32.700 --> 00:01:34.650 But we saw some limitations of them. 00:01:34.650 --> 00:01:37.260 Maybe if you've worked on the homepage problem-- 00:01:37.260 --> 00:01:39.360 you've been doing a lot of copying and pasting, 00:01:39.360 --> 00:01:41.970 or you weren't able to do everything you wanted to do. 00:01:41.970 --> 00:01:44.250 Well, Flask comes in to help you build something that 00:01:44.250 --> 00:01:46.290 is going to be more dynamic for you. 00:01:46.290 --> 00:01:49.410 And one of my favorite examples of this, of a more dynamic website 00:01:49.410 --> 00:01:52.320 that Flask can enable us to build is something like this one right 00:01:52.320 --> 00:01:55.860 here, libraryofbabel.info. 00:01:55.860 --> 00:01:57.990 And you can actually go to this site. 00:01:57.990 --> 00:02:02.730 This site is based on the book, Library of Babel by Jorge Luis Borges. 00:02:02.730 --> 00:02:06.330 And in this book, this author imagines this library 00:02:06.330 --> 00:02:08.370 that has all the possible stories that have ever 00:02:08.370 --> 00:02:10.620 been written, the stories have been written before us, 00:02:10.620 --> 00:02:14.220 ahead of us, currently right now, because every book contains 00:02:14.220 --> 00:02:16.860 these random assortments of the 26 characters. 00:02:16.860 --> 00:02:19.110 This is an infinite library with infinite books 00:02:19.110 --> 00:02:22.350 and contains all the possible stories that have been written 00:02:22.350 --> 00:02:23.610 or could be written. 00:02:23.610 --> 00:02:26.115 And we can actually build our own website along the same, 00:02:26.115 --> 00:02:27.990 but let's check out this one just to be sure. 00:02:27.990 --> 00:02:32.280 So you can go to this you URL right here, libraryofbabel.info. 00:02:32.280 --> 00:02:34.680 And I'll do the same over here on my computer. 00:02:34.680 --> 00:02:35.830 I'll go over here. 00:02:35.830 --> 00:02:38.850 And you might see a home page like this, if I zoom in for you. 00:02:38.850 --> 00:02:42.570 And you can see we can browse this library to see what is inside of it. 00:02:42.570 --> 00:02:44.130 I'll click browse here. 00:02:44.130 --> 00:02:48.450 And maybe I'll choose to go to like the first section of this library. 00:02:48.450 --> 00:02:51.030 I'll go to section zero down here. 00:02:51.030 --> 00:02:51.870 I'll click on it. 00:02:51.870 --> 00:02:54.840 And I see I'm in this room with four walls around me. 00:02:54.840 --> 00:02:59.700 So maybe I'll click on this wall, wall one, and I'll see this shelf of books, 00:02:59.700 --> 00:03:00.270 right? 00:03:00.270 --> 00:03:04.080 And I'll look, maybe just at this third shelf, just randomly, now. 00:03:04.080 --> 00:03:06.745 And I'll go down to, let's say this book right here. 00:03:06.745 --> 00:03:08.370 Let's pick one randomly from the shelf. 00:03:08.370 --> 00:03:10.980 And you'll see that I have this page full of just 00:03:10.980 --> 00:03:13.080 lots of random bits of text. 00:03:13.080 --> 00:03:16.920 But the idea is, there are so many books in this library, 00:03:16.920 --> 00:03:20.520 full of so many pieces of random text, that all the stories that could 00:03:20.520 --> 00:03:23.133 possibly be made are somewhere in here. 00:03:23.133 --> 00:03:25.050 And so if you take my word for it, we actually 00:03:25.050 --> 00:03:27.150 go to the search function for this website. 00:03:27.150 --> 00:03:31.080 I'll go back to the home page here by going to that slash route. 00:03:31.080 --> 00:03:33.180 And I'll go down to search at this point. 00:03:33.180 --> 00:03:34.950 Maybe I'll search in this library. 00:03:34.950 --> 00:03:37.380 And I can Enter up to a certain number of characters here. 00:03:37.380 --> 00:03:41.820 Maybe I'll search for this is CS-- 00:03:41.820 --> 00:03:43.110 and I can't type 50. 00:03:43.110 --> 00:03:48.930 I'll say this is computer science fifty week nine section. 00:03:48.930 --> 00:03:50.710 I'll zoom in so you can see it there. 00:03:50.710 --> 00:03:54.300 And I want to find out where is this text in this infinite library of books? 00:03:54.300 --> 00:03:57.610 So I'll go down and I'll hit Search. 00:03:57.610 --> 00:04:01.840 And I can see down below, it shows up in a few different places. 00:04:01.840 --> 00:04:04.610 I can see the places it shows up with random characters around it. 00:04:04.610 --> 00:04:08.150 So I'll click this one, it looks like it's on page 61. 00:04:08.150 --> 00:04:09.400 I can see it highlighted here. 00:04:09.400 --> 00:04:13.030 This is computer science fifty week nine section-- 00:04:13.030 --> 00:04:14.590 whoops-- right down in here. 00:04:14.590 --> 00:04:18.290 And this is on page 61 of some random book 00:04:18.290 --> 00:04:20.282 that we can see the location of down here. 00:04:20.282 --> 00:04:21.490 And we can go back over here. 00:04:21.490 --> 00:04:22.990 We can search for other places, too. 00:04:22.990 --> 00:04:24.710 Maybe with some other English words. 00:04:24.710 --> 00:04:28.490 This is another book that it's in right over here. 00:04:28.490 --> 00:04:31.210 And so we can look at all of these books and see all the places 00:04:31.210 --> 00:04:33.220 that this phrase shows up. 00:04:33.220 --> 00:04:36.460 And all this is done just by virtue of taking in some random text 00:04:36.460 --> 00:04:40.400 and figuring out what it might make out of the randomness that we have here. 00:04:40.400 --> 00:04:43.518 So if we think about how this website is made, let's think about some 00:04:43.518 --> 00:04:45.310 of the routes we can go to-- some of places 00:04:45.310 --> 00:04:48.080 we can explore at the very basics first here. 00:04:48.080 --> 00:04:50.620 So if we go back to our slides over here. 00:04:50.620 --> 00:04:53.110 We think of a website often having these routes 00:04:53.110 --> 00:04:55.310 we can go to see different parts of it. 00:04:55.310 --> 00:04:58.840 And so if I look at this, you'll notice that I have this slash at the end. 00:04:58.840 --> 00:05:02.800 If I go to libraryofbabel.info and put a slash at the end, 00:05:02.800 --> 00:05:05.260 I'm asking for the home page of this site. 00:05:05.260 --> 00:05:07.570 Give me the very basic page of this site. 00:05:07.570 --> 00:05:10.000 The very initial site I want to see. 00:05:10.000 --> 00:05:14.090 But I could also go to, as we saw, slash-- this is the home page here. 00:05:14.090 --> 00:05:17.350 I could also go to slash browse.cgi. 00:05:17.350 --> 00:05:20.230 And this is just a name that the author of this website 00:05:20.230 --> 00:05:24.070 kind of made up browser-- browse.cgi sounded OK for their purposes. 00:05:24.070 --> 00:05:27.970 And when I ask for this route, browse.cgi, 00:05:27.970 --> 00:05:30.220 we'll all see something different. 00:05:30.220 --> 00:05:32.065 I'll go down here and see I-- 00:05:32.065 --> 00:05:36.920 OK, I can see some library of books I can click on and browse in this case. 00:05:36.920 --> 00:05:41.963 And because I have all of this, I'm able to see different parts of the website. 00:05:41.963 --> 00:05:45.130 And I ask the server different pieces to give me back different other pieces 00:05:45.130 --> 00:05:46.690 of the site I'm looking for. 00:05:46.690 --> 00:05:49.690 We could even, if we wanted to, add some parameters to it 00:05:49.690 --> 00:05:52.870 and look at particular books, if we wanted to, using something like this, 00:05:52.870 --> 00:05:56.560 having parameters and these dot dot dots at the end here. 00:05:56.560 --> 00:05:58.360 Now how is this really working? 00:05:58.360 --> 00:06:01.480 You can imagine this website is full of these HTML pages look a bit 00:06:01.480 --> 00:06:02.410 like this, right? 00:06:02.410 --> 00:06:05.067 And maybe if you were working on home page last week, 00:06:05.067 --> 00:06:06.400 you could think of it like this. 00:06:06.400 --> 00:06:10.060 Or we have maybe trillions of HTML pages full of different text. 00:06:10.060 --> 00:06:10.870 And let's see. 00:06:10.870 --> 00:06:14.630 So if I were to request a page from this server right here, 00:06:14.630 --> 00:06:15.790 I can make an HTTP request. 00:06:15.790 --> 00:06:16.840 I might say this. 00:06:16.840 --> 00:06:20.890 Give me the slash browse.cgi page. 00:06:20.890 --> 00:06:21.710 I'll do this. 00:06:21.710 --> 00:06:24.043 You're going to get back a 200 code for everything's OK, 00:06:24.043 --> 00:06:26.830 and give me back that page over here. 00:06:26.830 --> 00:06:29.370 But now, if I wanted to see the text of this site, 00:06:29.370 --> 00:06:31.120 well, I could think of it a bit like this. 00:06:31.120 --> 00:06:32.080 Go over here. 00:06:32.080 --> 00:06:38.080 I might see on the right hand side, well, some text up here on-- 00:06:38.080 --> 00:06:42.320 sorry, the left hand side and then some HTML on the right hand side. 00:06:42.320 --> 00:06:44.560 And again, if you're working on a homepage last week, 00:06:44.560 --> 00:06:46.477 you might have seen something like this, where 00:06:46.477 --> 00:06:49.370 I could actually try to put in the random string of text here. 00:06:49.370 --> 00:06:53.230 But how many pages would we need to have all of this kind of text? 00:06:53.230 --> 00:06:56.680 If it's all random, it's all a combinations of these 26 characters, 00:06:56.680 --> 00:07:00.550 how many HTML pages would we possibly need here if we had so many of these? 00:07:00.550 --> 00:07:02.350 Feel free to chime in in the chat. 00:07:02.350 --> 00:07:05.920 How many would we really need to have all combinations of these 26 00:07:05.920 --> 00:07:06.670 characters? 00:07:12.090 --> 00:07:13.890 I'm seeing a lot. 00:07:13.890 --> 00:07:16.590 We need a lot of pages, right, for all of these 26 00:07:16.590 --> 00:07:18.850 characters, all combinations of them. 00:07:18.850 --> 00:07:21.060 And so if we had trillions of these pages, 00:07:21.060 --> 00:07:23.180 well, that's not very efficient for us. 00:07:23.180 --> 00:07:28.440 We could do, instead, probably better, is we could actually have a single HTML 00:07:28.440 --> 00:07:33.390 page and we could just kind of slot in some random string of text to that page 00:07:33.390 --> 00:07:36.122 using something like Python or Flask, in this case. 00:07:36.122 --> 00:07:37.830 So we could do something like this, where 00:07:37.830 --> 00:07:40.260 instead of having millions and millions of pages that 00:07:40.260 --> 00:07:43.540 have all these random strings of text, we could have one page 00:07:43.540 --> 00:07:47.520 and we could use Python to slot in a single random string for us-- 00:07:47.520 --> 00:07:50.350 perhaps in this placeholder right over here. 00:07:50.350 --> 00:07:52.500 So let's actually explore how we could build 00:07:52.500 --> 00:07:55.143 our own mini-version of this website, where 00:07:55.143 --> 00:07:57.060 we can generate random strings of text and see 00:07:57.060 --> 00:08:01.000 if we find any interesting, useful information from that piece of text. 00:08:01.000 --> 00:08:03.990 So I'll go to my code space over here. 00:08:03.990 --> 00:08:06.480 And I've already set up this Flask application. 00:08:06.480 --> 00:08:07.590 I can zoom in a bit. 00:08:07.590 --> 00:08:08.970 And I'll type ls. 00:08:08.970 --> 00:08:11.370 And you can see I have these files down below. 00:08:11.370 --> 00:08:15.600 I have app.py, I have helpers.py, which is a similar file name 00:08:15.600 --> 00:08:17.400 you'll see in this week's problem set. 00:08:17.400 --> 00:08:21.060 I have history.db, and I have a templates folder. 00:08:21.060 --> 00:08:26.652 And just to refresh our memory, what do you think will go in app.py? 00:08:26.652 --> 00:08:29.880 I mean, what language is that written in and what do you 00:08:29.880 --> 00:08:32.159 think we'll put inside of it, as we saw in lecture? 00:08:32.159 --> 00:08:34.049 Feel free to chime in in the chat. 00:08:34.049 --> 00:08:37.926 What will go inside of app.py. 00:08:37.926 --> 00:08:39.853 So I'm seeing Python, Flask. 00:08:39.853 --> 00:08:42.270 Right, yeah, this is we're going to write some of our code 00:08:42.270 --> 00:08:44.940 that will be written in Python, and we'll 00:08:44.940 --> 00:08:49.290 use the Flask library inside of app.py. 00:08:49.290 --> 00:08:50.760 So I can open that up a little bit. 00:08:50.760 --> 00:08:53.670 I'll code app.py, and we'll get you a taste 00:08:53.670 --> 00:08:56.790 of what this is doing for us, which we'll explore in much more depth 00:08:56.790 --> 00:08:57.930 later on. 00:08:57.930 --> 00:09:00.530 OK, this is our basic Flask app. 00:09:00.530 --> 00:09:04.850 Now though, I also have history.db up here. 00:09:04.850 --> 00:09:12.290 And knowing what we know about dot db files, what kind of file is this? 00:09:12.290 --> 00:09:13.850 History.db. 00:09:13.850 --> 00:09:15.020 It's a database, right? 00:09:15.020 --> 00:09:19.670 So we have some application, app.py will write our Flask code, 00:09:19.670 --> 00:09:23.390 and we also have this database called history.db. 00:09:23.390 --> 00:09:26.670 And inside of templates, what do you expect we might find? 00:09:26.670 --> 00:09:31.570 If I were to cd into templates to look inside. 00:09:31.570 --> 00:09:32.200 HTML, right. 00:09:32.200 --> 00:09:34.150 So I could cd templates here. 00:09:34.150 --> 00:09:36.100 I'll type ls, list my files. 00:09:36.100 --> 00:09:42.040 And I'll see two HTML files, index.html and layout.html. 00:09:42.040 --> 00:09:45.410 So let's get a feel for what this is doing for us already. 00:09:45.410 --> 00:09:49.570 So I'll type ls to see my application files here. 00:09:49.570 --> 00:09:53.380 I'll then type Flask run to run this application. 00:09:53.380 --> 00:09:55.690 This is different from HTTP server. 00:09:55.690 --> 00:09:58.630 I want to run this application using Flask. 00:09:58.630 --> 00:10:01.850 So I'll do Flask run, hit Enter. 00:10:01.850 --> 00:10:09.040 And now I should see shortly a URL pop up, or I can open it down below. 00:10:09.040 --> 00:10:12.930 And now I should see this very basic website, Library of Babel 00:10:12.930 --> 00:10:14.890 with a search history down below. 00:10:14.890 --> 00:10:16.770 Now this is not presently done yet. 00:10:16.770 --> 00:10:18.720 For one, there's no text on the screen. 00:10:18.720 --> 00:10:21.660 Ideally, you'd want to have some random string of tax we'd actually 00:10:21.660 --> 00:10:23.730 generate every time we visit this site to see 00:10:23.730 --> 00:10:26.560 if we get any meaningful words from it. 00:10:26.560 --> 00:10:29.670 So if we look at our application here, I'll 00:10:29.670 --> 00:10:33.480 go ahead and open up a new terminal. 00:10:33.480 --> 00:10:38.490 And I will get back to my library folder and I'll 00:10:38.490 --> 00:10:42.190 code app.py to pull up this file. 00:10:42.190 --> 00:10:45.600 So here is our very basic Flask application, 00:10:45.600 --> 00:10:47.220 if y'all can see at this text size. 00:10:47.220 --> 00:10:49.620 Let me know if you can't. 00:10:49.620 --> 00:10:52.850 From lines one through four, what would you say we're doing here? 00:10:52.850 --> 00:10:56.548 If we're going to break this down top to bottom, what are we doing in lines one 00:10:56.548 --> 00:10:57.090 through four? 00:10:57.090 --> 00:11:02.260 What's the purpose of these lines of code, just in general? 00:11:02.260 --> 00:11:04.880 Seeing some imports. 00:11:04.880 --> 00:11:06.850 Other things you might think, too? 00:11:06.850 --> 00:11:09.520 Setting up library access, yes, definitely. 00:11:09.520 --> 00:11:15.140 So here on lines one through four, we're simply telling our application, 00:11:15.140 --> 00:11:19.120 these are the libraries we're going to use in our program. 00:11:19.120 --> 00:11:21.280 Pieces of code somebody else has written for us. 00:11:21.280 --> 00:11:24.280 We'll use these in our application. 00:11:24.280 --> 00:11:28.870 Notice how I'm using the CS50 library here to get something called SQL. 00:11:28.870 --> 00:11:33.070 I'm using the Flask library here to get something called Flask, also, 00:11:33.070 --> 00:11:37.600 and also this render template function, and something called request. 00:11:37.600 --> 00:11:40.930 And I also have from helpers import random strings. 00:11:40.930 --> 00:11:46.060 So notice how I had back in my list of files here, helpers.py. 00:11:46.060 --> 00:11:50.110 Well, I could open up helpers.py here to show you what's inside. 00:11:50.110 --> 00:11:54.260 And I do have this function that I defined called random string. 00:11:54.260 --> 00:11:58.540 And if I give it some variable called len, some argument called len, 00:11:58.540 --> 00:12:03.290 I'll then get back a random string that has that length of characters. 00:12:03.290 --> 00:12:08.860 So if I said random string 500, I would get a string of 500 random characters. 00:12:08.860 --> 00:12:10.180 And I made this myself. 00:12:10.180 --> 00:12:15.540 But instead of putting it inside of my app.py, what I did instead, 00:12:15.540 --> 00:12:18.440 sort of copy and paste this into app.py, is I said, well, 00:12:18.440 --> 00:12:20.290 I want to keep things separate here. 00:12:20.290 --> 00:12:24.160 I'll put this helper function inside of helpers.py. 00:12:24.160 --> 00:12:29.330 Similar to what you'll see this week with the finance problem set over here. 00:12:29.330 --> 00:12:29.830 OK. 00:12:29.830 --> 00:12:32.340 And then finally, we're just importing the random library 00:12:32.340 --> 00:12:34.260 so we can get access to some of its functions. 00:12:34.260 --> 00:12:36.815 We'll see those later on in a bit. 00:12:36.815 --> 00:12:39.190 Now down below is where we get a little more interesting. 00:12:39.190 --> 00:12:42.400 So here on line six as we saw in lecture, 00:12:42.400 --> 00:12:45.210 we're kind of setting up our Flask application to run. 00:12:45.210 --> 00:12:47.790 You could think of this piece of code, right here, 00:12:47.790 --> 00:12:52.410 capital F, Flask, as being this template for a Flask application, 00:12:52.410 --> 00:12:54.570 that comes with some built in functionality, 00:12:54.570 --> 00:12:58.110 like the ability to say what we want to do when we visit a route, for example, 00:12:58.110 --> 00:12:59.010 on our website. 00:12:59.010 --> 00:13:03.240 But here we're saying, let's make a particular Flask application, 00:13:03.240 --> 00:13:07.508 and let's make sure that it corresponds to this current file-- 00:13:07.508 --> 00:13:09.300 that's what dunder name here it's something 00:13:09.300 --> 00:13:12.600 for us-- underscore underscore name, underscore underscore [INAUDIBLE] 00:13:12.600 --> 00:13:18.360 dunder name, is going to say build me a particular Flask app based on this file 00:13:18.360 --> 00:13:19.470 right here. 00:13:19.470 --> 00:13:22.127 And for the rest of this file, let's just call it app. 00:13:22.127 --> 00:13:23.460 We could call it something else. 00:13:23.460 --> 00:13:24.988 We could call it library here. 00:13:24.988 --> 00:13:27.030 But notice how we have to change everything else. 00:13:27.030 --> 00:13:31.170 We have to say library.config or library.route. 00:13:31.170 --> 00:13:34.140 So in the end, it's probably easier to call it app throughout, 00:13:34.140 --> 00:13:37.800 this kind of short name we can use to refer to our own Flask application 00:13:37.800 --> 00:13:40.590 we're building from this file. 00:13:40.590 --> 00:13:43.260 Now down below, we also have some connection to our database 00:13:43.260 --> 00:13:44.310 as we saw in lecture. 00:13:44.310 --> 00:13:47.820 This is saying, give me some variable called db, 00:13:47.820 --> 00:13:52.080 that I can then use to refer to this database called history.db 00:13:52.080 --> 00:13:54.420 that will access using sqlite. 00:13:54.420 --> 00:13:57.120 And then down below, let me just have some configuration 00:13:57.120 --> 00:14:01.090 to say that I want my HTML to auto reload when I change it. 00:14:01.090 --> 00:14:03.240 So if I go to an HTML, make a change, I want 00:14:03.240 --> 00:14:06.900 to see that change kind of automatically in my browser. 00:14:06.900 --> 00:14:09.120 And then finally, this little bit of code down here-- 00:14:09.120 --> 00:14:10.530 at app.route. 00:14:10.530 --> 00:14:13.870 Where have we seen this slash before? 00:14:13.870 --> 00:14:18.750 What does it often correspond to in our applications? 00:14:18.750 --> 00:14:20.205 We saw this just a little bit ago. 00:14:22.730 --> 00:14:26.870 Yeah, so I'm seeing the root folder, the home page. 00:14:26.870 --> 00:14:30.320 Whenever we ask for the slash root of an application, 00:14:30.320 --> 00:14:33.950 we're often asking for that main page-- that home page of the site. 00:14:33.950 --> 00:14:39.200 And so the hint here is that at app.route, if I say slash here, 00:14:39.200 --> 00:14:41.480 that's going to say, well, I'm going to define 00:14:41.480 --> 00:14:44.630 some function I can run whenever the user requests 00:14:44.630 --> 00:14:47.800 the slash root of my application. 00:14:47.800 --> 00:14:51.030 And then down below, notice how I have this function called index. 00:14:51.030 --> 00:14:56.100 I'm going to define, again, some function I can use to-- 00:14:56.100 --> 00:14:59.220 function I can use when the user asks for that slash root, 00:14:59.220 --> 00:15:02.700 I will run this function top to bottom every time they ask for it. 00:15:02.700 --> 00:15:05.310 And in this case, it looks like I'm just returning 00:15:05.310 --> 00:15:09.870 the result of this function, render template index.html. 00:15:09.870 --> 00:15:13.710 So I'm giving back the home page, which is what we saw, again, 00:15:13.710 --> 00:15:15.480 when I went to my slash root here. 00:15:15.480 --> 00:15:21.240 I then see my home page of my site that's inside of index.html. 00:15:21.240 --> 00:15:25.330 So questions on this syntax so far? 00:15:25.330 --> 00:15:27.000 Feel free to ask in the chat. 00:15:27.000 --> 00:15:29.460 This is kind of a lot all at once, but I want 00:15:29.460 --> 00:15:31.830 to make sure we get your questions answered. 00:15:39.610 --> 00:15:40.500 OK. 00:15:40.500 --> 00:15:42.990 So feel free to keep putting questions in the chat. 00:15:42.990 --> 00:15:44.670 I see one coming in. 00:15:44.670 --> 00:15:47.640 Where are the imported libraries actually imported from? 00:15:47.640 --> 00:15:51.960 So presumably, these libraries are somewhere on your computer. 00:15:51.960 --> 00:15:54.960 And in fact, they're probably in some kind of special folder for Python. 00:15:54.960 --> 00:15:57.490 They might be even brought in from the web a little bit. 00:15:57.490 --> 00:15:59.400 I'm actually not quite sure exactly where they are, 00:15:59.400 --> 00:16:00.450 but they are somewhere, right? 00:16:00.450 --> 00:16:02.250 And Python is getting them from someplace. 00:16:02.250 --> 00:16:03.380 So I can't answer your question in particular, 00:16:03.380 --> 00:16:06.255 but you could probably look it up online and figure out where are you 00:16:06.255 --> 00:16:07.500 importing these things from. 00:16:07.500 --> 00:16:09.840 I can tell you, though, that for example, 00:16:09.840 --> 00:16:12.360 from helpers import random string, well, that 00:16:12.360 --> 00:16:16.380 is being imported right from this file called helpers.py, 00:16:16.380 --> 00:16:21.350 that we see is right next to our app.py, right here. 00:16:21.350 --> 00:16:24.620 And a question-- what is dunder name doing, dunder name referring 00:16:24.620 --> 00:16:27.770 to underscore underscore name underscore underscore. 00:16:27.770 --> 00:16:31.640 That is simply a special Python variable name that 00:16:31.640 --> 00:16:35.810 refers to the name of this file app. 00:16:35.810 --> 00:16:40.760 And so this is a way of telling us that, hey, given this template for our Flask 00:16:40.760 --> 00:16:44.570 app that we have, capital F, Flask here, let's go ahead 00:16:44.570 --> 00:16:49.670 and build a particular one that's called app, and we'll do it from this file 00:16:49.670 --> 00:16:50.780 that we're going to call-- 00:16:50.780 --> 00:16:52.430 well that is presently called app. 00:16:52.430 --> 00:16:57.080 So this gives our application access to all the other kind of files and folders 00:16:57.080 --> 00:16:59.150 that matter for our application. 00:17:02.360 --> 00:17:02.860 All right. 00:17:02.860 --> 00:17:04.339 These are good questions. 00:17:04.339 --> 00:17:07.119 So let's keep going on and figuring out how this corresponds 00:17:07.119 --> 00:17:10.150 with our HTML for our program so far. 00:17:10.150 --> 00:17:11.650 So I'll go back to my terminal. 00:17:11.650 --> 00:17:15.670 And all this time code up index.html. 00:17:15.670 --> 00:17:17.290 And why don't I put it-- 00:17:17.290 --> 00:17:21.339 just for the sake of visualizing it-- kind of side by side here. 00:17:21.339 --> 00:17:23.760 Do this. 00:17:23.760 --> 00:17:24.349 Whoops. 00:17:24.349 --> 00:17:26.849 Let me move this over here. 00:17:26.849 --> 00:17:28.210 There we go. 00:17:28.210 --> 00:17:33.930 And now we can see our Python code, right alongside our HTML code. 00:17:33.930 --> 00:17:37.890 And this is helpful because often when we're working with Flask, 00:17:37.890 --> 00:17:41.970 you do want to have some kind of correspondence between our HTML 00:17:41.970 --> 00:17:45.510 and our Python code-- in some cases, variable names will matter. 00:17:45.510 --> 00:17:48.820 And if we're talking about trying to insert some text to our HTML, 00:17:48.820 --> 00:17:51.610 well, it's important to visualize those things side by side. 00:17:51.610 --> 00:17:53.735 So we'll do that from here on out, assuming you all 00:17:53.735 --> 00:17:56.340 can still read the text size here. 00:17:56.340 --> 00:17:59.960 So if we visit our page and I refresh it, 00:17:59.960 --> 00:18:02.960 I don't really see any piece of text. 00:18:02.960 --> 00:18:05.760 But again, our goal was to insert this piece of text 00:18:05.760 --> 00:18:09.560 so we could actually see it come to life and we could regenerate some new text 00:18:09.560 --> 00:18:11.820 every time we visited the page. 00:18:11.820 --> 00:18:16.880 Well, if I wanted to generate just a random string of characters, 00:18:16.880 --> 00:18:20.430 I could do that using my random string function up here. 00:18:20.430 --> 00:18:21.860 So let me try to use that. 00:18:21.860 --> 00:18:25.280 I'll go to index function down here, which, again, is called 00:18:25.280 --> 00:18:27.440 whenever I visit that slash root. 00:18:27.440 --> 00:18:29.540 I'll put this to the side for now. 00:18:29.540 --> 00:18:31.760 I'll come down here and I'll say, I want to get 00:18:31.760 --> 00:18:38.150 a string that is going to get me the result of, in this case, random string. 00:18:38.150 --> 00:18:43.550 And I'll ask for a string of maybe 1,000 characters, right? 00:18:43.550 --> 00:18:48.230 So now if I were to just print string, I should hopefully 00:18:48.230 --> 00:18:52.130 see that I have this random string of text inside my terminal, 00:18:52.130 --> 00:18:54.470 because print here will print to my terminal. 00:18:54.470 --> 00:18:56.090 So open up my terminal. 00:18:56.090 --> 00:18:57.950 I'll go back to my server. 00:18:57.950 --> 00:19:01.770 And let me go ahead and just refresh the page over here. 00:19:01.770 --> 00:19:04.940 I'll hit slash, go to my slash root, hit Enter. 00:19:04.940 --> 00:19:07.220 And now nothing changes on my HTML. 00:19:07.220 --> 00:19:10.400 But if I look inside of my terminal, I do 00:19:10.400 --> 00:19:12.140 see this random piece of text I generated 00:19:12.140 --> 00:19:14.850 right, about 1,000 random characters. 00:19:14.850 --> 00:19:22.260 So how could I then get this string, perhaps, inside of my HTML? 00:19:22.260 --> 00:19:25.980 Any ideas from what we saw from lecture recently? 00:19:30.220 --> 00:19:32.350 We have this variable called string. 00:19:32.350 --> 00:19:38.270 But how should we get it inside of our HTML? 00:19:38.270 --> 00:19:42.448 So I'm seeing using some equals, some maybe braces. 00:19:42.448 --> 00:19:43.990 And so you're all on the right track. 00:19:43.990 --> 00:19:47.860 So notice how here in our index HTML, we do 00:19:47.860 --> 00:19:50.020 have this placeholder already set up for us. 00:19:50.020 --> 00:19:53.940 Let me zoom in on it on the right hand side. 00:19:53.940 --> 00:19:55.880 You can see we have this placeholder here. 00:19:55.880 --> 00:19:59.840 And using what's now Jinja syntax, we can say, 00:19:59.840 --> 00:20:05.330 I want to have a placeholder, some value I want to write in to my HTML. 00:20:05.330 --> 00:20:08.420 And I can denote it with these curly braces on either side-- 00:20:08.420 --> 00:20:10.300 double curly braces. 00:20:10.300 --> 00:20:13.000 And then the inside of these braces, I can 00:20:13.000 --> 00:20:17.140 say what the name I want to-- the name of the placeholder I want to call this. 00:20:17.140 --> 00:20:20.110 Here I'm just calling it placeholder, I could also call it string. 00:20:20.110 --> 00:20:24.300 I can call it really anything, but here I'll just call it placeholder. 00:20:24.300 --> 00:20:30.150 Now if I wanted to pass in string to be kind of interpolated 00:20:30.150 --> 00:20:32.980 or put inside as HTML, I could do this. 00:20:32.980 --> 00:20:36.910 I could say, when I call this function, render template, 00:20:36.910 --> 00:20:42.150 let's go ahead and make sure that placeholder gets the value of string, 00:20:42.150 --> 00:20:45.210 in this case, as somebody in the chat has already noted. 00:20:45.210 --> 00:20:47.740 Placeholder equals string. 00:20:47.740 --> 00:20:52.570 So what I'm doing is taking my Python variable, string, and saying, 00:20:52.570 --> 00:20:56.730 let's put it inside of my HTML in the placeholder that's literally called 00:20:56.730 --> 00:20:57.450 placeholder. 00:20:57.450 --> 00:20:59.310 And I know that it is right here because I 00:20:59.310 --> 00:21:04.450 can see it in double curly braces using Jinja syntax on the right hand side. 00:21:04.450 --> 00:21:08.130 So now if I go back and refresh the page, hit Enter here, 00:21:08.130 --> 00:21:09.990 I do actually see my random string of text. 00:21:09.990 --> 00:21:11.782 And I can actually do this again and again. 00:21:11.782 --> 00:21:13.860 I'll hit refresh to see a new random text. 00:21:13.860 --> 00:21:16.210 Refresh again and refresh again. 00:21:16.210 --> 00:21:18.930 And now I see this piece of text, over, and over, 00:21:18.930 --> 00:21:24.330 and over again, constantly regenerating every time I call the slash root, 00:21:24.330 --> 00:21:28.230 and thus, the index function here. 00:21:28.230 --> 00:21:30.680 So what questions do you have on this so far, 00:21:30.680 --> 00:21:35.270 and how we're interpolating or adding in some of our variables 00:21:35.270 --> 00:21:37.865 from Python to our HTML? 00:21:48.950 --> 00:21:50.620 Yeah, so one piece we haven't seen yet-- 00:21:50.620 --> 00:21:55.400 I see a question in the chat-- is about this methods equals GET. 00:21:55.400 --> 00:22:02.240 So here, when we define a route of our application using Flask, we're saying, 00:22:02.240 --> 00:22:04.610 here's what the user can type in, in the URL, 00:22:04.610 --> 00:22:08.240 to run this function down below, and also, 00:22:08.240 --> 00:22:12.410 here are the methods they can use to access this route. 00:22:12.410 --> 00:22:15.380 So remember how there are two HTTP methods-- 00:22:15.380 --> 00:22:20.480 GET and POST-- where GET simply involves the user asking 00:22:20.480 --> 00:22:22.200 the server for some web page. 00:22:22.200 --> 00:22:26.660 If I say get me this page, it's going to give you back the page I've asked for. 00:22:26.660 --> 00:22:31.160 POST on the other hand, is about sending some data through a form, most likely, 00:22:31.160 --> 00:22:32.510 to your server. 00:22:32.510 --> 00:22:34.710 And the server then does something with that data. 00:22:34.710 --> 00:22:37.100 So here, because we're just asking-- 00:22:37.100 --> 00:22:41.210 because the user is just asking our application for, really, 00:22:41.210 --> 00:22:44.120 a random string, we can safely use GET. 00:22:44.120 --> 00:22:46.430 But as we'll see later on in just a moment here, 00:22:46.430 --> 00:22:48.410 we'll try to make our own form and you can 00:22:48.410 --> 00:22:50.430 POST data or send data to our server. 00:22:50.430 --> 00:22:53.920 So we should use POST in that case, too. 00:22:53.920 --> 00:22:57.470 And I see a question, what is SQLite doing up here? 00:22:57.470 --> 00:23:00.790 So notice how, if you recall from week seven, 00:23:00.790 --> 00:23:03.800 SQLite is this database engine that we use. 00:23:03.800 --> 00:23:07.270 And so this line up here, line eight, db equals SQL, 00:23:07.270 --> 00:23:09.890 SQLite colon slash slash history.db is saying, 00:23:09.890 --> 00:23:16.180 let's build a connection to our database called history.db using SQLite. 00:23:16.180 --> 00:23:21.460 And within Python, let's go ahead and call that connection just db, 00:23:21.460 --> 00:23:22.240 in general. 00:23:22.240 --> 00:23:27.250 And we can use something like db to execute to run queries on our database 00:23:27.250 --> 00:23:31.460 that we'll see later towards the end of section here. 00:23:31.460 --> 00:23:31.960 All right. 00:23:31.960 --> 00:23:34.360 Other questions, too, on this so far? 00:23:42.110 --> 00:23:43.890 All right. 00:23:43.890 --> 00:23:45.890 So let's keep going here. 00:23:45.890 --> 00:23:48.380 And maybe one thing we'd like to do is actually 00:23:48.380 --> 00:23:52.080 have more than one variable inside of our HTML. 00:23:52.080 --> 00:23:55.940 So let's say I went up here and I went down to-- 00:23:55.940 --> 00:23:57.860 I don't want to call it Library of Babel. 00:23:57.860 --> 00:24:02.130 Maybe I just want to just call it Library of some name I can pass in. 00:24:02.130 --> 00:24:06.770 So to update this, what can I do to the end of render template? 00:24:06.770 --> 00:24:10.460 I have this placeholder called name, and it's a placeholder 00:24:10.460 --> 00:24:15.590 because I have braces brace, brace, brace, with name on the inside. 00:24:15.590 --> 00:24:19.180 So how could I then update this here? 00:24:22.568 --> 00:24:23.610 Anyone chime in the chat? 00:24:23.610 --> 00:24:26.280 How could I substitute a name in here? 00:24:29.900 --> 00:24:30.400 Yeah. 00:24:30.400 --> 00:24:31.480 So name equals something. 00:24:31.480 --> 00:24:32.650 I can say colon-- 00:24:32.650 --> 00:24:33.340 or not colon. 00:24:33.340 --> 00:24:37.520 A comma, name equals perhaps Carter. 00:24:37.520 --> 00:24:38.745 Hope you can see that. 00:24:38.745 --> 00:24:41.120 And then I'll go ahead and go over here refresh the page. 00:24:41.120 --> 00:24:42.940 And now I see library of Carter. 00:24:42.940 --> 00:24:46.210 So here's one more example of having multiple different values 00:24:46.210 --> 00:24:48.280 you can pass in to our HTML. 00:24:48.280 --> 00:24:53.280 I could change this also to Joel, hit Enter here. 00:24:53.280 --> 00:24:57.650 And now-- whoops, let me refresh this. 00:24:57.650 --> 00:24:59.380 And now we see a Library of Joel. 00:24:59.380 --> 00:25:02.770 So another way of passing in some data here. 00:25:02.770 --> 00:25:08.120 And now often what you will see is this variable called placeholder. 00:25:08.120 --> 00:25:11.417 Or really, this placeholder called placeholder isn't really 00:25:11.417 --> 00:25:14.000 well named, because if you had to call everything placeholder, 00:25:14.000 --> 00:25:15.708 it would get really messy really quickly. 00:25:15.708 --> 00:25:19.960 So we could just call this also string, in our HTML. 00:25:19.960 --> 00:25:22.960 But then what we'd have to do is go down below here 00:25:22.960 --> 00:25:26.145 and say, string equals string, which is a little confusing if you're 00:25:26.145 --> 00:25:28.270 a beginner, because on the one hand, you're seeing, 00:25:28.270 --> 00:25:30.560 OK, string equals string, we know that. 00:25:30.560 --> 00:25:34.270 But what this is really saying is that string on the left hand side 00:25:34.270 --> 00:25:37.360 is referring to this placeholder string in our HTML, 00:25:37.360 --> 00:25:39.670 and string on the right hand side is referring 00:25:39.670 --> 00:25:42.490 to this actual Python variable called string. 00:25:42.490 --> 00:25:46.510 So often you'll see these two names being the same thing, 00:25:46.510 --> 00:25:50.800 but they refer to different objects or different placeholders or variables 00:25:50.800 --> 00:25:52.660 in our programs. 00:25:52.660 --> 00:25:55.770 So let's go back and call this maybe not placeholder. 00:25:55.770 --> 00:25:58.650 Let's call it maybe a random string over here. 00:25:58.650 --> 00:26:01.080 And I'll do the same over here, random string, 00:26:01.080 --> 00:26:03.630 just so we can keep a good naming system, 00:26:03.630 --> 00:26:12.090 but also try to differentiate the Python variable from the HTML placeholder. 00:26:12.090 --> 00:26:13.890 OK. 00:26:13.890 --> 00:26:17.620 So a question that comes up is, how do we actually get input from the user 00:26:17.620 --> 00:26:18.120 now? 00:26:18.120 --> 00:26:19.328 So this is all fine and good. 00:26:19.328 --> 00:26:21.150 I can go to my URL, I can refresh it. 00:26:21.150 --> 00:26:23.400 And I can see-- oops, let me actually change this. 00:26:23.400 --> 00:26:26.830 Library of Babel. 00:26:26.830 --> 00:26:27.550 Refresh the page. 00:26:27.550 --> 00:26:31.160 And I do see random text over, and over, and over again. 00:26:31.160 --> 00:26:34.270 But what if I wanted the user to pick out a page, 00:26:34.270 --> 00:26:37.120 like they can do in the real version of this website? 00:26:37.120 --> 00:26:39.730 They can go to page 10 or page 410. 00:26:39.730 --> 00:26:42.520 They can see the same thing every time. 00:26:42.520 --> 00:26:47.900 Well, to get input from the user, we'll often want to have a form in HTML. 00:26:47.900 --> 00:26:51.380 So a form is going to look a bit like this, 00:26:51.380 --> 00:26:58.370 where a form is comprised of this open form tag and this closing form tag. 00:26:58.370 --> 00:27:03.570 And any ideas as to what often goes inside of a form? 00:27:03.570 --> 00:27:04.390 This form is blank. 00:27:04.390 --> 00:27:05.730 We don't see anything. 00:27:05.730 --> 00:27:10.010 But what goes inside of a form? 00:27:10.010 --> 00:27:14.930 Could be a table, some input, other things, too. 00:27:14.930 --> 00:27:16.640 A submit. 00:27:16.640 --> 00:27:19.440 What else might go inside of a form? 00:27:19.440 --> 00:27:20.610 A button, a label. 00:27:20.610 --> 00:27:22.950 Yeah, there are lots of things you can add to a form. 00:27:22.950 --> 00:27:26.100 And to add them to our forms, we usually put them inside 00:27:26.100 --> 00:27:28.240 of these opening and closing tags here. 00:27:28.240 --> 00:27:32.470 So form, the opening tag, and slash form the closing tag. 00:27:32.470 --> 00:27:37.350 So what I'll do here is I will add this input of type text 00:27:37.350 --> 00:27:40.350 and this button of type submit. 00:27:40.350 --> 00:27:44.010 Now the default type for input is text, and I 00:27:44.010 --> 00:27:46.620 believe the default type for a button is submit. 00:27:46.620 --> 00:27:49.410 But here, we're just spelling them out deliberately, here. 00:27:49.410 --> 00:27:55.140 Where if I were to render this now-- render this HTML on the left hand side, 00:27:55.140 --> 00:27:59.580 I might first see this input box, and that shows up 00:27:59.580 --> 00:28:01.440 as this input box on the right hand side. 00:28:01.440 --> 00:28:03.480 Some place I can type some text. 00:28:03.480 --> 00:28:07.300 And then, I would also have this Submit button over here. 00:28:07.300 --> 00:28:09.160 It looks a bit like this. 00:28:09.160 --> 00:28:12.820 So together, these pieces are part of my form. 00:28:12.820 --> 00:28:15.090 And when I click this Submit button, what 00:28:15.090 --> 00:28:18.030 will happen is my data will go somewhere-- 00:28:18.030 --> 00:28:21.870 wherever I tell it to, so long as I specified the right things. 00:28:21.870 --> 00:28:25.170 And now what actually is missing from this form? 00:28:25.170 --> 00:28:29.070 We have our input, we have button to submit it. 00:28:29.070 --> 00:28:32.010 But what are we missing, perhaps, in the top form tag? 00:28:35.000 --> 00:28:36.400 I'm seeing an action. 00:28:36.400 --> 00:28:40.720 An action and a method, where if we have some data, perhaps in our input, 00:28:40.720 --> 00:28:43.690 and we click Submit, well, there's really no place 00:28:43.690 --> 00:28:44.902 for that data to go yet. 00:28:44.902 --> 00:28:47.110 So we should really specify where that data is going. 00:28:47.110 --> 00:28:48.190 So I might do this. 00:28:48.190 --> 00:28:55.280 I might say also, make sure this form has particular action and a method. 00:28:55.280 --> 00:28:58.000 So to get our minds on what this action is, 00:28:58.000 --> 00:29:00.200 notice how we see the slash here again. 00:29:00.200 --> 00:29:03.340 So this action is telling us where-- 00:29:03.340 --> 00:29:06.040 which route we want to actually send our data to. 00:29:06.040 --> 00:29:10.450 Is it the slash route, the slash browse route, or a different route altogether? 00:29:10.450 --> 00:29:13.300 And then the second one, the request method 00:29:13.300 --> 00:29:16.060 is saying, well, how do I want to make that request? 00:29:16.060 --> 00:29:19.270 Should I do it via Post or via GET? 00:29:19.270 --> 00:29:23.980 And now what might be one difference between using Post and using 00:29:23.980 --> 00:29:25.810 GET with a form? 00:29:25.810 --> 00:29:27.340 Maybe chime in the chat. 00:29:27.340 --> 00:29:32.530 What might be one difference if we used Post versus GET to submit 00:29:32.530 --> 00:29:34.090 our data via the form? 00:29:39.150 --> 00:29:40.400 So I'm seeing something like-- 00:29:40.400 --> 00:29:45.500 Post sends data and GET gets it, which is a true kind of by convention. 00:29:45.500 --> 00:29:50.340 We can still send data through get, though. 00:29:50.340 --> 00:29:52.860 One is shown in the URL and the other is hidden, 00:29:52.860 --> 00:29:55.400 which is a more apt description here, where 00:29:55.400 --> 00:30:00.260 we're saying, if I send data via Post, that won't show up in the URL. 00:30:00.260 --> 00:30:03.230 But if I send it via get it often-- it will show up 00:30:03.230 --> 00:30:05.690 in the URL using these URL parameters. 00:30:05.690 --> 00:30:09.140 And so Post is good for when we're kind of sending data to the server, 00:30:09.140 --> 00:30:10.975 but we don't want people to see. 00:30:10.975 --> 00:30:13.100 Or even when we don't really care if people see it, 00:30:13.100 --> 00:30:16.770 Post might still be a good method to use. 00:30:16.770 --> 00:30:19.910 So let's try building up our own form here. 00:30:19.910 --> 00:30:25.490 Let's go to our HTML and see how we have a to do here. 00:30:25.490 --> 00:30:29.100 That to do is to implement a search form. 00:30:29.100 --> 00:30:32.400 So if I wanted to make this form, what could I do? 00:30:32.400 --> 00:30:34.580 I can go ahead and do form. 00:30:34.580 --> 00:30:39.020 And then I need to have some kind of text input for the page number 00:30:39.020 --> 00:30:40.430 the user is inputting. 00:30:40.430 --> 00:30:43.940 Let me actually make this over here and make it a little bigger. 00:30:43.940 --> 00:30:47.810 What kind of input element should I make here? 00:30:47.810 --> 00:30:49.190 Any ideas from the chat? 00:30:53.560 --> 00:30:56.455 What kind of input element do I need to get a page number? 00:30:59.160 --> 00:31:00.045 I could use a label. 00:31:03.730 --> 00:31:05.950 Yeah, so I'm seeing something a bit like this. 00:31:05.950 --> 00:31:11.953 Input and the type should be, in this case, let's just stick to type text, 00:31:11.953 --> 00:31:13.620 assuming the user can type in some text. 00:31:13.620 --> 00:31:18.660 We could also, if we wanted to, make this a number. 00:31:18.660 --> 00:31:21.590 But let's stick to text for now. 00:31:21.590 --> 00:31:25.640 And down below, we might also have a button to submit this. 00:31:25.640 --> 00:31:30.020 I'll say button, and the type of this button is a submit button. 00:31:30.020 --> 00:31:33.230 And then on the inside I can say whatever I want the button to say. 00:31:33.230 --> 00:31:36.980 I could say submit or I could say Go to Page. 00:31:36.980 --> 00:31:42.855 And now if I refresh my page, I should see my very own form up above. 00:31:42.855 --> 00:31:43.730 And let's just check. 00:31:43.730 --> 00:31:48.280 I Can change this to maybe number, here. 00:31:48.280 --> 00:31:48.790 Refresh. 00:31:48.790 --> 00:31:52.522 And now I can actually have these up and down arrows for the page number. 00:31:52.522 --> 00:31:54.730 Here, though, we'll actually just stick to text, just 00:31:54.730 --> 00:31:59.240 to keep things a little more simple here. 00:31:59.240 --> 00:32:03.830 And now what am I still missing from this form? 00:32:03.830 --> 00:32:08.130 We have our input and our button. 00:32:08.130 --> 00:32:10.500 What have I maybe missed out on? 00:32:10.500 --> 00:32:11.350 The action. 00:32:11.350 --> 00:32:14.670 So I'll say action equals slash, because I want 00:32:14.670 --> 00:32:17.160 to send this data to the slash root. 00:32:17.160 --> 00:32:20.435 And the method in this case will actually be Post. 00:32:20.435 --> 00:32:21.810 I want to use a different method. 00:32:21.810 --> 00:32:25.860 And notice how in HTML, actually these methods are lowercase 00:32:25.860 --> 00:32:32.370 instead of Get capital or Post capital, we use post lowercase or get lowercase. 00:32:32.370 --> 00:32:33.760 OK. 00:32:33.760 --> 00:32:38.600 So now with this form, I can go over here, refresh the page. 00:32:38.600 --> 00:32:39.880 And I'll go to maybe page 10. 00:32:39.880 --> 00:32:41.010 I'll hit 10 here. 00:32:41.010 --> 00:32:42.340 I'll say, go to page. 00:32:42.340 --> 00:32:44.420 But I get method not allowed. 00:32:44.420 --> 00:32:47.000 So what have I also not done yet? 00:32:47.000 --> 00:32:50.190 I've made my form, it submits via post. 00:32:50.190 --> 00:32:53.800 But what have I not done yet in my Python? 00:33:03.330 --> 00:33:03.830 Yeah. 00:33:03.830 --> 00:33:06.380 So I need to add this POST method here. 00:33:06.380 --> 00:33:12.680 I need to say that in the list of supported methods, POST is one of them. 00:33:12.680 --> 00:33:15.500 And now if I want to do something different when the user 00:33:15.500 --> 00:33:18.270 requests via POST, I could do this. 00:33:18.270 --> 00:33:24.020 I could say, if request.method is POST or equals POST, 00:33:24.020 --> 00:33:27.530 do whatever is inside of here. 00:33:27.530 --> 00:33:31.040 I'll leave it unimplemented for now, but there's presumably something 00:33:31.040 --> 00:33:33.600 that we might do inside of this. 00:33:33.600 --> 00:33:38.870 So if I refresh the page now, I'll hit Enter, and I can do 10 again, 00:33:38.870 --> 00:33:39.890 and 10 again. 00:33:39.890 --> 00:33:42.740 And it seems to work for me. 00:33:42.740 --> 00:33:46.760 But what we haven't really yet done is actually gotten the data 00:33:46.760 --> 00:33:49.130 from the user in our Python code. 00:33:49.130 --> 00:33:51.720 So presumably, the user is submitting via POST. 00:33:51.720 --> 00:33:58.700 And we could confirm this by saying submitted via POST, printing that out. 00:33:58.700 --> 00:34:00.440 I'll open up my terminal. 00:34:00.440 --> 00:34:03.540 I'll go over here, submit my form. 00:34:03.540 --> 00:34:07.080 And I do see submitted via POST, so that seems to work. 00:34:07.080 --> 00:34:11.760 But what we haven't done has actually gotten the data from the form itself. 00:34:11.760 --> 00:34:13.400 So how could we do that? 00:34:13.400 --> 00:34:16.070 If we go back to our slides here, we might 00:34:16.070 --> 00:34:20.900 see that we could actually use this correspondence between our HTML 00:34:20.900 --> 00:34:24.000 and our Python code to get the values we want to get. 00:34:24.000 --> 00:34:28.520 So notice how in addition to a type, which is now omitted up here 00:34:28.520 --> 00:34:32.480 by default. But now we have the name attribute of our input. 00:34:32.480 --> 00:34:34.190 And this one is called page. 00:34:34.190 --> 00:34:37.790 We could reference that very same name in our Python code 00:34:37.790 --> 00:34:41.600 to then get the value that that input holds 00:34:41.600 --> 00:34:43.739 at the time the form is submitted. 00:34:43.739 --> 00:34:48.620 So I could use request.form.get, and then say page to get access 00:34:48.620 --> 00:34:51.139 to the value of that name-- 00:34:51.139 --> 00:34:54.469 or that input called name in my HTML. 00:34:54.469 --> 00:34:58.970 If I submitted via GET instead of POST, I could use request.args.get. 00:34:58.970 --> 00:35:07.080 So again, POST is request.form.get, get is request.args.get. 00:35:07.080 --> 00:35:08.650 So let's try this out. 00:35:08.650 --> 00:35:10.290 Let's go ahead and go back to our HTML. 00:35:10.290 --> 00:35:17.010 And let's actually add a name to our input. 00:35:17.010 --> 00:35:19.290 This one I'll call-- 00:35:19.290 --> 00:35:21.600 this one I'll call page. 00:35:21.600 --> 00:35:28.980 And now how should I get that value inside of my Python code now? 00:35:28.980 --> 00:35:34.525 I have this input named page, but how should I get it in my Python code? 00:35:42.490 --> 00:35:46.510 I can use something like the GET function. 00:35:46.510 --> 00:35:49.810 But more specifically, what kind of line should I write? 00:35:55.990 --> 00:35:58.540 So because I'm submitting via POST, what I should really 00:35:58.540 --> 00:36:04.365 do to get access to this data is I could do request.form.get. 00:36:04.365 --> 00:36:08.770 So from this request, from the form that was submitted, 00:36:08.770 --> 00:36:13.060 get me the value of the input named page. 00:36:13.060 --> 00:36:16.750 And why don't I store this inside some variable called page? 00:36:16.750 --> 00:36:19.770 Let me scroll this to the right. 00:36:19.770 --> 00:36:24.150 And for good measure, I'll print page to be sure I have access to it. 00:36:24.150 --> 00:36:29.760 Now I'll go to my code here, I'll refresh the page, hit 10, go to page. 00:36:29.760 --> 00:36:32.520 Now I'll look in my terminal, and I do actually 00:36:32.520 --> 00:36:35.370 see I have that page number being printed out 00:36:35.370 --> 00:36:39.670 because I told Flask to do so on line 17. 00:36:39.670 --> 00:36:43.050 I could even make it maybe page 50-- go to page. 00:36:43.050 --> 00:36:46.030 And now I see page 50 down below here. 00:36:46.030 --> 00:36:52.250 So I've gotten whatever text is inside of my input named page. 00:36:52.250 --> 00:36:55.910 And this seems to work for now. 00:36:55.910 --> 00:37:00.800 But what if we wanted to update this in some way to actually have some effect? 00:37:00.800 --> 00:37:03.277 Well, it doesn't quite matter for the problems 00:37:03.277 --> 00:37:06.360 that this week or anything else really beyond this particular application. 00:37:06.360 --> 00:37:15.200 But if I wanted to have every page number be set by whatever-- 00:37:15.200 --> 00:37:17.880 if I wanted every random string be set by the page number, 00:37:17.880 --> 00:37:21.050 I could call this function called random.seed. 00:37:21.050 --> 00:37:25.680 And I've gotten the seed function, again, from the random library here. 00:37:25.680 --> 00:37:29.930 And if I say random.seed page, well, later 00:37:29.930 --> 00:37:36.470 on when I generate my random string, if I ask for page 10 and page 10 again, 00:37:36.470 --> 00:37:39.402 I'll get that same random string every time, 00:37:39.402 --> 00:37:41.360 giving me the illusion of having different page 00:37:41.360 --> 00:37:43.420 numbers in my application. 00:37:43.420 --> 00:37:48.620 So for example, I can go to my application over here, hit Refresh. 00:37:48.620 --> 00:37:50.920 I could say page 10. 00:37:50.920 --> 00:37:53.830 And I do see some random string of text over here. 00:37:53.830 --> 00:37:58.840 I'll go to page 10 again and I get that same random string. 00:37:58.840 --> 00:38:02.800 I go to page 11 and I get some new random string. 00:38:02.800 --> 00:38:06.100 Go to page 11 again, and I get that same random string. 00:38:06.100 --> 00:38:11.110 So random seed is a way of specifying how the randomness should work. 00:38:11.110 --> 00:38:13.000 As long as I pass in that same number-- 00:38:13.000 --> 00:38:17.770 10, 11, 20 or so on, I then get that same random string 00:38:17.770 --> 00:38:21.350 later on when I use the random functions here. 00:38:21.350 --> 00:38:25.050 If I don't use POST, though, if I don't run this piece of code, 00:38:25.050 --> 00:38:27.590 well, what I'll do is just get a truly random string 00:38:27.590 --> 00:38:29.780 based on some random seed. 00:38:29.780 --> 00:38:35.600 But beforehand, I could set some seed to account to based on the page to say, 00:38:35.600 --> 00:38:38.030 that if I ask for certain page number, I'll always 00:38:38.030 --> 00:38:42.020 get back the same string in the end. 00:38:42.020 --> 00:38:43.430 OK. 00:38:43.430 --> 00:38:46.290 But what might go wrong with this? 00:38:46.290 --> 00:38:51.442 If you look at this form, what are some bad inputs you could give to this form. 00:38:51.442 --> 00:38:53.150 If we're talking about page numbers, what 00:38:53.150 --> 00:38:54.845 are some bad inputs you could give? 00:38:59.390 --> 00:39:01.580 Negative nine, letters. 00:39:01.580 --> 00:39:05.210 So if I do this, I say, negative nine. 00:39:05.210 --> 00:39:06.420 Well, it still seems to work. 00:39:06.420 --> 00:39:07.820 But I don't really want it to. 00:39:07.820 --> 00:39:13.460 Or if I typed a, a, a, well, that also worked, but not quite the way 00:39:13.460 --> 00:39:15.080 I want it to. 00:39:15.080 --> 00:39:16.680 And so how could we do this? 00:39:16.680 --> 00:39:18.770 I could actually go back to my code space here 00:39:18.770 --> 00:39:21.480 and I could try to update this in some way. 00:39:21.480 --> 00:39:26.060 So ideally, I want to validate the user input as I get it. 00:39:26.060 --> 00:39:28.640 And maybe I have page here. 00:39:28.640 --> 00:39:31.670 But I could ask the question, before I do anything with page, 00:39:31.670 --> 00:39:34.820 is page less than zero? 00:39:34.820 --> 00:39:40.210 And if it is, why don't we return the render template. 00:39:40.210 --> 00:39:46.840 Return index HTML now rendered, but at this point just say some error message 00:39:46.840 --> 00:39:50.680 like, type in a positive number. 00:39:53.260 --> 00:39:56.160 So now my placeholder called random string will actually just 00:39:56.160 --> 00:39:58.720 be this error message, type in a positive number. 00:39:58.720 --> 00:40:03.270 So now I'll go back over here and I'll do refresh the page. 00:40:03.270 --> 00:40:08.070 And I'll type, let's say, negative 10, go to page. 00:40:08.070 --> 00:40:10.930 Oh, but I got an internal server error. 00:40:10.930 --> 00:40:16.360 And if I look at my terminal, I should see type error less than not supported 00:40:16.360 --> 00:40:21.100 between instances of str and int down below. 00:40:21.100 --> 00:40:24.540 So what went wrong do you think? 00:40:24.540 --> 00:40:31.950 If we look at this code on the left hand side. 00:40:31.950 --> 00:40:35.040 What went wrong? 00:40:35.040 --> 00:40:40.410 Yeah, we forgot to put page inside of a-- we 00:40:40.410 --> 00:40:43.452 forget to convert page to be an integer. 00:40:43.452 --> 00:40:44.410 So I forgot to do this. 00:40:44.410 --> 00:40:49.670 I forgot to say that if we can, let's make sure we turn page 00:40:49.670 --> 00:40:52.290 from a string to an integer. 00:40:52.290 --> 00:40:56.270 So whenever you use request.form.get or request.args.get, 00:40:56.270 --> 00:40:58.250 whether you're working with numbers or not, 00:40:58.250 --> 00:41:01.670 you'll always get your input back as a string, and it's up to you 00:41:01.670 --> 00:41:05.130 to convert it to an integer if you want it to be an integer. 00:41:05.130 --> 00:41:07.160 So here I'll convert page to an integer. 00:41:07.160 --> 00:41:08.990 And now I'll try running this. 00:41:08.990 --> 00:41:13.490 I'll go back here and I'll say, slash, to get back to my main page, 00:41:13.490 --> 00:41:14.780 and I'll say negative 10. 00:41:14.780 --> 00:41:15.980 I'll go to page. 00:41:15.980 --> 00:41:18.890 And now I do see, type in a positive number, which is really good. 00:41:18.890 --> 00:41:22.520 I'll do -500, and I see the same thing. 00:41:22.520 --> 00:41:26.450 But what is the other kind of input we could give to this form that 00:41:26.450 --> 00:41:32.253 might make it go wrong? 00:41:32.253 --> 00:41:33.420 We've seen negative numbers. 00:41:33.420 --> 00:41:35.460 What else? 00:41:35.460 --> 00:41:36.550 We can give some text. 00:41:36.550 --> 00:41:41.810 We'd say, ABC, go to page, and we get another internal server error. 00:41:41.810 --> 00:41:43.730 So something's gone wrong again. 00:41:43.730 --> 00:41:48.160 And if we look down in our terminal, we see a value error-- 00:41:48.160 --> 00:41:52.570 invalid literal for int with base 10 ABC. 00:41:52.570 --> 00:41:55.510 And this basically means that I can't convert 00:41:55.510 --> 00:41:58.433 the string, ABC, to be an integer. 00:41:58.433 --> 00:42:00.100 What does it mean for ABC to be integer? 00:42:00.100 --> 00:42:01.090 We don't really know. 00:42:01.090 --> 00:42:07.330 So what I should probably do here is use Python's try and accept syntax 00:42:07.330 --> 00:42:10.247 where in Python, often it's good to simply try something 00:42:10.247 --> 00:42:11.080 that you want to do. 00:42:11.080 --> 00:42:15.040 Like try to, in this case, convert page to an integer. 00:42:15.040 --> 00:42:20.690 And except, maybe except if I do see that value error, 00:42:20.690 --> 00:42:25.560 let me go ahead and actually tell the user another error. 00:42:25.560 --> 00:42:30.380 And this time I'll tell them, just enter a number in general. 00:42:30.380 --> 00:42:34.720 So again, we'll get the page number from our form. 00:42:34.720 --> 00:42:39.020 We'll then try to convert page into an integer. 00:42:39.020 --> 00:42:42.670 And if we get that error, we can't convert some text to an integer, what 00:42:42.670 --> 00:42:48.260 we'll do is we'll say, I want to tell the user to enter a number over here. 00:42:48.260 --> 00:42:51.670 And then finally, as one final check, we'll also ask the question, 00:42:51.670 --> 00:42:53.530 is page less than zero? 00:42:53.530 --> 00:42:57.440 And if it is, we'll tell them to type in a positive number overall. 00:42:57.440 --> 00:43:01.730 So this kind of accesses all the possible combinations of errors here. 00:43:01.730 --> 00:43:04.210 So go back up to our website. 00:43:04.210 --> 00:43:05.560 Go to slash. 00:43:05.560 --> 00:43:08.020 I'll type, in this case, ABC. 00:43:08.020 --> 00:43:08.920 Go to page. 00:43:08.920 --> 00:43:11.158 And I see enter a number, which is good. 00:43:11.158 --> 00:43:12.700 And then I'll type maybe negative 10. 00:43:12.700 --> 00:43:14.380 I'll see enter a positive number. 00:43:14.380 --> 00:43:17.260 And now if I type page 10, well, I seem to get 00:43:17.260 --> 00:43:20.060 the thing I wanted in the first place. 00:43:20.060 --> 00:43:24.520 So questions on this and how we implemented some of this 00:43:24.520 --> 00:43:28.060 getting of data from the form, but also validating user input, 00:43:28.060 --> 00:43:31.100 as you might want to do during this week's problem set? 00:43:46.350 --> 00:43:49.685 OK, seeing-- I'll wait just one minute or so. 00:43:55.450 --> 00:43:57.150 All right. 00:43:57.150 --> 00:44:00.192 What happens, though, actually-- 00:44:00.192 --> 00:44:02.400 maybe there's one more thing we should take care of-- 00:44:02.400 --> 00:44:04.690 if I do this. 00:44:04.690 --> 00:44:09.830 I could go back over here, put in nothing, and type go to page. 00:44:09.830 --> 00:44:13.490 I see enter number, it actually works OK. 00:44:13.490 --> 00:44:14.960 But we could also-- 00:44:14.960 --> 00:44:17.660 well, no, I think we're OK here. 00:44:17.660 --> 00:44:19.970 Let me know if you find other errors, though. 00:44:19.970 --> 00:44:20.883 Symbols, I saw. 00:44:20.883 --> 00:44:21.800 OK, let's try symbols. 00:44:21.800 --> 00:44:24.750 I'll type at exclamation point. 00:44:24.750 --> 00:44:27.070 Seems to work. 00:44:27.070 --> 00:44:31.120 So that seems OK here. 00:44:31.120 --> 00:44:33.400 And particularly for this week's problems set. 00:44:33.400 --> 00:44:36.190 We will be getting numbers and text from the user, 00:44:36.190 --> 00:44:38.980 it's often good to really try to validate the input 00:44:38.980 --> 00:44:41.410 to make sure that they're not being adversarial to you. 00:44:41.410 --> 00:44:44.693 They're not trying to give you some text and mess up your program. 00:44:44.693 --> 00:44:47.110 And you're instead making sure that before you do anything 00:44:47.110 --> 00:44:50.560 with their input, you're making sure it is exactly as you expect. 00:44:50.560 --> 00:44:55.040 And if it's not, maybe giving them some kind of error as we did here. 00:44:55.040 --> 00:44:56.770 So let's keep going now. 00:44:56.770 --> 00:45:00.100 And one of our final to-do's was to not just 00:45:00.100 --> 00:45:03.280 have the user send some input to our database, 00:45:03.280 --> 00:45:06.610 but also to have some search history down below. 00:45:06.610 --> 00:45:10.570 And ideally, if I search for page 10, well, I 00:45:10.570 --> 00:45:12.790 should see that search show up at the bottom 00:45:12.790 --> 00:45:15.760 of my page in this table down below. 00:45:15.760 --> 00:45:16.970 And that's not there yet. 00:45:16.970 --> 00:45:20.680 But to do this, we'll probably need to use some of our SQL 00:45:20.680 --> 00:45:22.100 that we learned from a prior week. 00:45:22.100 --> 00:45:24.260 And so let's take a look at how we could use that. 00:45:24.260 --> 00:45:29.950 So if we think about databases in our program, they're going to store data, 00:45:29.950 --> 00:45:32.210 long-term for our application. 00:45:32.210 --> 00:45:34.480 And if we want it to store like a search history, 00:45:34.480 --> 00:45:37.690 it's a great use case for that, because we can actually persistently 00:45:37.690 --> 00:45:40.400 store search history over time. 00:45:40.400 --> 00:45:43.370 So let's take a look at SQL and how we could do this. 00:45:43.370 --> 00:45:48.670 If we look at history.db, at the beginning of this session, 00:45:48.670 --> 00:45:50.200 I ran this function-- 00:45:50.200 --> 00:45:54.190 I ran this command called Create table history 00:45:54.190 --> 00:45:59.500 with this ID column and this page column, to give me this table of pages 00:45:59.500 --> 00:46:01.750 that I could insert into. 00:46:01.750 --> 00:46:05.810 And just to show you, if I go back to my code space, go over here. 00:46:05.810 --> 00:46:12.850 I could go to my new terminal, type ls, type SQLite3, 00:46:12.850 --> 00:46:15.770 history.db to open this up. 00:46:15.770 --> 00:46:21.220 And now if I full screen it and zoom in, if I type dot schema, 00:46:21.220 --> 00:46:25.270 I see I've ran that command and I have this table called history. 00:46:25.270 --> 00:46:30.710 I could even select everything from history, and I see nothing's there. 00:46:30.710 --> 00:46:36.710 So I have this kind of empty table in my database called history.db. 00:46:36.710 --> 00:46:41.850 So if I were to insert into this table, I could do the following. 00:46:41.850 --> 00:46:45.140 I can run this SQL command called INSERT INTO. 00:46:45.140 --> 00:46:47.360 And the way this works is we type the name 00:46:47.360 --> 00:46:50.600 of the table, so history, and the columns you want to insert into, 00:46:50.600 --> 00:46:52.070 so page in this case. 00:46:52.070 --> 00:46:56.750 So I'll insert page 50 into my table. 00:46:56.750 --> 00:47:00.710 Then I might say, OK, let's insert 100 into my table, 00:47:00.710 --> 00:47:05.120 and let's insert 43 into my table as I go through and make these queries. 00:47:05.120 --> 00:47:09.230 But right now, this is all happening in the SQLite terminal 00:47:09.230 --> 00:47:11.000 and not in my Python program. 00:47:11.000 --> 00:47:16.430 So how could I run Python or run SQL but in my Python code? 00:47:16.430 --> 00:47:18.720 Any ideas in the chat? 00:47:18.720 --> 00:47:20.770 What have we seen so far? 00:47:20.770 --> 00:47:25.140 How can I run these same SQL commands but not in the SQLite terminal, 00:47:25.140 --> 00:47:27.170 actually in my Python program now? 00:47:29.540 --> 00:47:30.040 Yeah. 00:47:30.040 --> 00:47:31.780 I'm seeing db.execute. 00:47:31.780 --> 00:47:35.920 So I can type the very same command, but just inside of Python 00:47:35.920 --> 00:47:39.400 using this db.execute command. 00:47:39.400 --> 00:47:44.920 So db to execute is a way of trying to execute SQL commands inside 00:47:44.920 --> 00:47:47.410 of our application that connects to this database 00:47:47.410 --> 00:47:49.490 and actually runs them on that database. 00:47:49.490 --> 00:47:54.008 So here we can say insert in history the page 43. 00:47:54.008 --> 00:47:56.050 And one kind of handy thing here is we don't even 00:47:56.050 --> 00:47:57.760 need to know the page number originally. 00:47:57.760 --> 00:48:00.890 We could just say, insert some placeholder like this. 00:48:00.890 --> 00:48:04.810 I could say, make a question mark for some value I could insert later on 00:48:04.810 --> 00:48:08.390 and then say comma, the name of the variable I want to insert, 00:48:08.390 --> 00:48:09.320 in this case. 00:48:09.320 --> 00:48:11.420 So let's actually try this out. 00:48:11.420 --> 00:48:14.740 I'll go back to my code. 00:48:14.740 --> 00:48:17.060 And let me pull up-- 00:48:17.060 --> 00:48:25.653 pull up my-- actually, exit from this. 00:48:25.653 --> 00:48:26.570 No, I'll keep that up. 00:48:26.570 --> 00:48:27.980 Let me go back over here. 00:48:27.980 --> 00:48:33.120 I'll code-- oh, cd into library, and I'll code app.py. 00:48:33.120 --> 00:48:37.470 And now I see I'm kind of back in my view over here. 00:48:37.470 --> 00:48:42.420 I want to insert the page number every time I go to the slash root 00:48:42.420 --> 00:48:43.950 and submit the form. 00:48:43.950 --> 00:48:49.170 So ideally, when I'm in this post route, I want to keep track of the pages 00:48:49.170 --> 00:48:51.280 that the user has requested. 00:48:51.280 --> 00:48:55.870 So once I know that I have a valid page number right down in here-- 00:48:55.870 --> 00:48:57.130 let me zoom in a bit-- 00:48:57.130 --> 00:49:03.360 what could I run to insert this page number into my database? 00:49:03.360 --> 00:49:12.120 I know I can do insert into history into the pages column, some values. 00:49:12.120 --> 00:49:17.290 But what do I want to actually type here to run it inside of Python? 00:49:17.290 --> 00:49:19.450 This is not valid Python code yet. 00:49:19.450 --> 00:49:20.725 But how could I make it so? 00:49:29.780 --> 00:49:31.350 Yeah, I can use db to execute. 00:49:31.350 --> 00:49:38.800 So I can say, db to execute and wrap this command with that function. 00:49:38.800 --> 00:49:41.650 And then to fill in this placeholder here, this question mark, 00:49:41.650 --> 00:49:47.840 I could go ahead and say, I want to put in page for that right here. 00:49:47.840 --> 00:49:50.380 So now if I look at this entire command, I'm 00:49:50.380 --> 00:49:56.090 saying, execute on my database, which I defined up here-- 00:49:56.090 --> 00:49:59.870 history.db, using SQLite. 00:49:59.870 --> 00:50:01.940 Execute on that database this command. 00:50:01.940 --> 00:50:06.733 Insert into history, in the pages column, this value here. 00:50:06.733 --> 00:50:07.650 And what is the value? 00:50:07.650 --> 00:50:08.910 What's the value for page? 00:50:08.910 --> 00:50:11.710 And we know, page is a page number the user has submitted. 00:50:11.710 --> 00:50:16.170 So let me go back to my application, refresh the page. 00:50:16.170 --> 00:50:17.880 This time, I will type page 10. 00:50:17.880 --> 00:50:19.480 I'll go to page. 00:50:19.480 --> 00:50:21.630 And if I scroll down, well, I don't see anything. 00:50:21.630 --> 00:50:23.250 And that's because my HTML-- 00:50:23.250 --> 00:50:25.710 I haven't actually rendered this. 00:50:25.710 --> 00:50:28.800 Like I just see search history but really nothing else over here. 00:50:28.800 --> 00:50:34.590 But if I go to my SQLite connection, My SQLite terminal here 00:50:34.590 --> 00:50:39.720 and I type select star from history, what 00:50:39.720 --> 00:50:42.180 do you think I'll see in this case? 00:50:42.180 --> 00:50:43.770 Feel free to type in the chat. 00:50:43.770 --> 00:50:47.310 What do you think I'll see when I type select star from history now? 00:50:52.530 --> 00:50:54.070 I'll see everything in the database. 00:50:54.070 --> 00:50:59.160 And because I submitted this form with the page number 10, 00:50:59.160 --> 00:51:00.660 I should see 10 somewhere. 00:51:00.660 --> 00:51:01.800 And I do see it. 00:51:01.800 --> 00:51:04.720 I see this has an ID and the page is 10. 00:51:04.720 --> 00:51:06.720 And now I can go back and submit the form again. 00:51:06.720 --> 00:51:08.680 I could go back over here. 00:51:08.680 --> 00:51:10.740 Let me search for page 50 now. 00:51:10.740 --> 00:51:13.960 I'll go to that page and then I'll go over here. 00:51:13.960 --> 00:51:16.440 I'll select everything from history and now I 00:51:16.440 --> 00:51:20.160 see both page 10 and page 50 in my history. 00:51:20.160 --> 00:51:24.420 So I'm adding to my table, not by being in this terminal down here, 00:51:24.420 --> 00:51:31.370 but through my own Python code that I wrote up above, right in here. 00:51:31.370 --> 00:51:31.870 OK. 00:51:31.870 --> 00:51:34.672 So questions on this so far? 00:51:34.672 --> 00:51:36.130 How we're inserting into our table? 00:51:39.325 --> 00:51:41.950 I see a question-- how do we see the search history in our HTML 00:51:41.950 --> 00:51:43.450 which we'll get to in just a second. 00:51:43.450 --> 00:51:48.320 But questions on inserting or this db to execute for now? 00:51:58.430 --> 00:51:58.930 All right. 00:51:58.930 --> 00:51:59.972 So let's keep going then. 00:51:59.972 --> 00:52:04.890 And our last step is really to try to show this search history in our HTML. 00:52:04.890 --> 00:52:08.940 And we'll need a bit more advanced syntax, at least 00:52:08.940 --> 00:52:11.260 with Jinja on the right hand side here. 00:52:11.260 --> 00:52:14.730 But for now, let's figure out, how could I get access to the data 00:52:14.730 --> 00:52:18.120 from my database inside of Python, and then 00:52:18.120 --> 00:52:20.588 use Python to pass that data into my HTML? 00:52:20.588 --> 00:52:22.380 So we're going a few different places here. 00:52:22.380 --> 00:52:27.540 We're asking our database, what rows do you have, putting those in Python, 00:52:27.540 --> 00:52:32.230 and then telling Python to send that data to our HTML page. 00:52:32.230 --> 00:52:35.650 So maybe down here when I visit this page, 00:52:35.650 --> 00:52:40.540 let's say I've finished making a request, either via POST or GET. 00:52:40.540 --> 00:52:42.820 And now I've generated a string. 00:52:42.820 --> 00:52:46.870 But I also want to figure out, what is inside of my database? 00:52:46.870 --> 00:52:49.540 Well, I could do db.execute. 00:52:49.540 --> 00:52:53.455 And as we saw before, how could I get everything from my history table? 00:52:57.580 --> 00:52:59.395 What kind of SQL command could I use? 00:53:02.380 --> 00:53:03.120 Yeah, star. 00:53:03.120 --> 00:53:06.830 Select star from history, right? 00:53:06.830 --> 00:53:10.400 And let me actually add the semi-colon up here, just to be sure. 00:53:10.400 --> 00:53:14.650 And now that I've done this, well, I selected everything, 00:53:14.650 --> 00:53:18.900 but I also need a place to store this data so I can use it in Python. 00:53:18.900 --> 00:53:23.670 And it happens to be that db to execute returns to you 00:53:23.670 --> 00:53:27.550 a list of all the rows as dictionaries. 00:53:27.550 --> 00:53:32.190 So for example, I could say rows equals db.execute. 00:53:32.190 --> 00:53:38.490 And I'll get back a list where every row is a dictionary that has the column 00:53:38.490 --> 00:53:40.710 names as its attributes or its keys. 00:53:40.710 --> 00:53:41.850 So just to show you-- 00:53:41.850 --> 00:53:44.520 I could print rows down here, just to my terminal. 00:53:44.520 --> 00:53:47.430 And now I'll go to Library of Babel. 00:53:47.430 --> 00:53:48.780 I'll hit slash now. 00:53:48.780 --> 00:53:50.910 I still don't see anything in my search history 00:53:50.910 --> 00:53:52.952 down below, because I haven't made that part yet. 00:53:52.952 --> 00:53:56.640 But if I go to my terminal, open that up. 00:53:56.640 --> 00:53:58.710 Let me go back over here to my server. 00:53:58.710 --> 00:54:02.160 I see that I ran this command, select star from history, 00:54:02.160 --> 00:54:06.480 and it gave me this list of dictionaries. 00:54:06.480 --> 00:54:11.060 So see, I have one dictionary that has ID and page as keys. 00:54:11.060 --> 00:54:14.090 And the ID is one, the page is 10. 00:54:14.090 --> 00:54:18.380 I have this next dictionary where the ID is two and the page is 50. 00:54:18.380 --> 00:54:20.480 That's another row in my table. 00:54:20.480 --> 00:54:25.080 And together, this is an entire list-- a list of rows. 00:54:25.080 --> 00:54:27.400 So what could I do with this? 00:54:27.400 --> 00:54:29.560 How could I render this in my HTML? 00:54:29.560 --> 00:54:32.790 Well, as we saw maybe a little bit briefly in lecture, 00:54:32.790 --> 00:54:37.840 I could try to pass in this variable-- rows-- 00:54:37.840 --> 00:54:40.910 to my HTML, and render it there. 00:54:40.910 --> 00:54:47.800 So I could say, maybe I have this placeholder called history in my HTML. 00:54:47.800 --> 00:54:53.350 And I'll make sure that that placeholder is filled with the values of rows. 00:54:53.350 --> 00:54:56.200 And let me go over here to my index.html. 00:54:56.200 --> 00:54:58.820 Now, open this part up. 00:54:58.820 --> 00:55:03.740 And maybe in my table body, well, I could just place history like this. 00:55:03.740 --> 00:55:05.810 I'll make this placeholder for history and I'll 00:55:05.810 --> 00:55:09.930 put the value of rows right in there in my table. 00:55:09.930 --> 00:55:15.170 So I'll go back to Library of Babel and I will hit slash to refresh the page. 00:55:15.170 --> 00:55:18.950 And well I don't quite see what I expected. 00:55:18.950 --> 00:55:22.950 This is not an ideal format. 00:55:22.950 --> 00:55:29.520 I've kind of literally interpolated or copy pasted the value of rows 00:55:29.520 --> 00:55:34.050 into my HTML, but it looks kind of wonky and not how I want it to look. 00:55:34.050 --> 00:55:35.580 So there's a better way to do this. 00:55:35.580 --> 00:55:41.280 And actually, in Jinja, instead of just pasting an entire variable, 00:55:41.280 --> 00:55:46.080 we could iterate over a variable but in our HTML. 00:55:46.080 --> 00:55:50.370 And now Jinja has the special syntax we can use to use for loops, 00:55:50.370 --> 00:55:51.947 so what we have in Python. 00:55:51.947 --> 00:55:52.780 So I could say this. 00:55:52.780 --> 00:55:58.890 I could say percent-- or brace percent and then closing brace-- 00:55:58.890 --> 00:56:00.510 closing percent and then brace. 00:56:00.510 --> 00:56:06.790 Let's say for maybe row in history. 00:56:06.790 --> 00:56:09.230 And then end for down here. 00:56:09.230 --> 00:56:12.880 So now I've made this for loop in my HTML 00:56:12.880 --> 00:56:16.240 where history is the list I'm iterating over 00:56:16.240 --> 00:56:20.800 and row is what I want to call everything-- 00:56:20.800 --> 00:56:25.500 every individual thing I'm iterating over on a given iteration. 00:56:25.500 --> 00:56:29.720 So now I can say, I want to, inside of this table, 00:56:29.720 --> 00:56:35.720 make myself a new table row for every row that I have in history. 00:56:35.720 --> 00:56:39.230 And then inside that table row, I want to have some data. 00:56:39.230 --> 00:56:44.920 Again, this tr is our table row tag and this td is our table data tag. 00:56:44.920 --> 00:56:46.400 And now what should go inside here? 00:56:46.400 --> 00:56:52.940 Well, maybe I could actually have this placeholder that is equivalent to row 00:56:52.940 --> 00:56:58.780 and I could borrow some Python syntax here, row bracket page. 00:56:58.780 --> 00:57:01.950 So what do you think we'll see in this case? 00:57:01.950 --> 00:57:03.795 Any ideas in the chat if we do this? 00:57:08.000 --> 00:57:13.580 We're iterating over our history list, a list of rows from our table. 00:57:13.580 --> 00:57:18.420 We're going to call every iteration, row. 00:57:18.420 --> 00:57:22.430 And then we'll say, row, get me the key-- 00:57:22.430 --> 00:57:25.910 give me the value corresponding to the key called page. 00:57:25.910 --> 00:57:30.610 So again, here is our entire list, down below here. 00:57:30.610 --> 00:57:35.330 On the first iteration, this will be row, and we'll get the page value-- 00:57:35.330 --> 00:57:36.370 so 10. 00:57:36.370 --> 00:57:39.700 On the next iteration, this will be row, and then we'll 00:57:39.700 --> 00:57:43.300 get the page value, or 50. 00:57:43.300 --> 00:57:45.520 So let's refresh the page and see what happens now. 00:57:45.520 --> 00:57:46.750 I'll go over here-- 00:57:46.750 --> 00:57:47.410 oops. 00:57:47.410 --> 00:57:47.920 Here. 00:57:47.920 --> 00:57:48.420 Slash. 00:57:48.420 --> 00:57:54.560 And now, I do see my search history, kind of as I intended it to be. 00:57:54.560 --> 00:57:59.860 And if I even go up here and type going to page 100, I'll go to that page, 00:57:59.860 --> 00:58:03.490 scroll down, and I see that added to my history. 00:58:03.490 --> 00:58:05.710 I could go to 100 again. 00:58:05.710 --> 00:58:08.100 I see that same random string like we saw before, 00:58:08.100 --> 00:58:12.330 and now I can see my search history down below. 00:58:12.330 --> 00:58:16.050 So all of this, this kind of syntax here, 00:58:16.050 --> 00:58:20.760 is just a way to print our list of dictionaries 00:58:20.760 --> 00:58:23.520 a little more prettily, a little more in line 00:58:23.520 --> 00:58:25.725 with what we expect to see in our HTML. 00:58:29.070 --> 00:58:30.180 OK. 00:58:30.180 --> 00:58:32.000 So what questions are there on this? 00:58:32.000 --> 00:58:36.450 On how we passed in some list of dictionaries to our code 00:58:36.450 --> 00:58:39.240 and iterated over it to make a table here? 00:58:58.740 --> 00:58:59.610 Same question. 00:58:59.610 --> 00:59:04.350 Showing the back end to the front end is not insecure, how do we hide that? 00:59:04.350 --> 00:59:08.537 So the key thing to remember here is that this app.py 00:59:08.537 --> 00:59:11.370 is kind of like what we call our back end-- something the user never 00:59:11.370 --> 00:59:12.600 really sees. 00:59:12.600 --> 00:59:17.040 And even our HTML page over here is somewhat back end, in the sense 00:59:17.040 --> 00:59:20.443 that if I were to render this-- 00:59:20.443 --> 00:59:21.360 let me look over here. 00:59:21.360 --> 00:59:25.690 If I were to render template, index.html, 00:59:25.690 --> 00:59:30.570 well, I would actually see not this code for row and history 00:59:30.570 --> 00:59:36.720 and for row, bracket, page, I'd actually generate this HTML file 00:59:36.720 --> 00:59:38.290 and then show it to the user. 00:59:38.290 --> 00:59:43.330 And so if I go to my HTML file over here and scroll down, 00:59:43.330 --> 00:59:47.010 notice how I don't actually see any of the Jinja syntax, 00:59:47.010 --> 00:59:50.110 I just see the resulting pieces of it here. 00:59:50.110 --> 00:59:54.760 So I don't see for or the dictionary or anything like that. 00:59:54.760 --> 00:59:57.040 I just see the result of it here. 00:59:57.040 --> 00:59:59.820 And so that is secure enough for us, as we're 00:59:59.820 --> 01:00:04.150 showing our web page to the user on the front end, what they can see up front 01:00:04.150 --> 01:00:04.650 here. 01:00:07.853 --> 01:00:09.520 Question-- how do we get the key values? 01:00:09.520 --> 01:00:13.680 So notice in our HTML. 01:00:13.680 --> 01:00:18.120 We said row with the key of page, but how do we know it was page? 01:00:18.120 --> 01:00:24.160 Well, if I go to my SQL prompt over here, select star from history 01:00:24.160 --> 01:00:25.030 as you did before. 01:00:25.030 --> 01:00:27.550 I have this row called page. 01:00:27.550 --> 01:00:31.210 So it's just in the way we made our table we had this column called page 01:00:31.210 --> 01:00:33.580 on a row, a column called page here. 01:00:37.900 --> 01:00:39.460 OK. 01:00:39.460 --> 01:00:40.435 Other questions here? 01:00:44.315 --> 01:00:46.190 While we're waiting for questions to come in, 01:00:46.190 --> 01:00:49.610 this week will be a lot of doing exactly what we did today, 01:00:49.610 --> 01:00:53.450 of trying to insert some data from Python into HTML, 01:00:53.450 --> 01:00:56.090 trying to render dictionaries, lists of dictionaries 01:00:56.090 --> 01:00:58.370 and so on, and even using some of our helper functions 01:00:58.370 --> 01:01:00.053 that we saw before here. 01:01:00.053 --> 01:01:02.720 I hope you go off and work on this problem set with some of what 01:01:02.720 --> 01:01:04.245 you learned during this section. 01:01:04.245 --> 01:01:06.245 We'll probably officially conclude here, but I'm 01:01:06.245 --> 01:01:09.270 happy to be around to answer any questions that you all have. 01:01:09.270 --> 01:01:13.120 Thank you very much for coming and I hope to see you next time.