1 00:00:00,000 --> 00:00:03,210 2 00:00:03,210 --> 00:00:06,540 CARTER ZENKE: OK, well hello, one and all, and welcome to CS50s week 3 00:00:06,540 --> 00:00:09,720 9 section, this week where a lot of it comes together. 4 00:00:09,720 --> 00:00:10,770 My name is Carter Zenke. 5 00:00:10,770 --> 00:00:12,750 I'm the courses preceptor here on campus. 6 00:00:12,750 --> 00:00:16,140 And the goal of these sections that we host online 7 00:00:16,140 --> 00:00:18,600 is to help you bridge the gap between lecture 8 00:00:18,600 --> 00:00:20,680 and this week's problem you'll be working on. 9 00:00:20,680 --> 00:00:23,550 In this case, you're building our own web application using Flask. 10 00:00:23,550 --> 00:00:26,730 And so today we'll dive into these three topics here. 11 00:00:26,730 --> 00:00:29,910 Flask and Jinja, how we can use forms in our websites, 12 00:00:29,910 --> 00:00:33,390 and how we can work with databases and build more dynamic applications 13 00:00:33,390 --> 00:00:33,970 overall. 14 00:00:33,970 --> 00:00:36,360 So I thought to kick things off, we do what we normally 15 00:00:36,360 --> 00:00:39,685 do and maybe on the count of three, we'll all unmute and say hello, 16 00:00:39,685 --> 00:00:41,560 so a big chorus of hellos to kick things off. 17 00:00:41,560 --> 00:00:42,750 So on the count of three. 18 00:00:42,750 --> 00:00:45,693 We'll do one, two, three. 19 00:00:45,693 --> 00:00:46,360 AUDIENCE: Hello! 20 00:00:46,360 --> 00:00:51,560 21 00:00:51,560 --> 00:00:52,560 CARTER ZENKE: All right. 22 00:00:52,560 --> 00:00:54,600 It's so good to hear all of your voices here together. 23 00:00:54,600 --> 00:00:57,678 And again, our goal will be to go through these three topics right here. 24 00:00:57,678 --> 00:00:59,470 And again, this is going to be interactive. 25 00:00:59,470 --> 00:01:01,900 So if you have questions about these three topics as we work through them, 26 00:01:01,900 --> 00:01:04,140 please feel free to message them in the chat or chime 27 00:01:04,140 --> 00:01:06,600 in when I ask for responses here. 28 00:01:06,600 --> 00:01:08,970 Now we'll dive into Flask and Jinja. 29 00:01:08,970 --> 00:01:13,290 And as we saw in lecture, Flask and Jinja are these two-- 30 00:01:13,290 --> 00:01:15,750 well, Flask is more like a framework we can use 31 00:01:15,750 --> 00:01:19,800 and Jinja is this templating library we can use along with Jinja. 32 00:01:19,800 --> 00:01:23,670 But the goal is to build more dynamic applications than you could 33 00:01:23,670 --> 00:01:27,330 with just HTML, CSS, and JavaScript. 34 00:01:27,330 --> 00:01:29,640 So we saw those three languages-- 35 00:01:29,640 --> 00:01:32,700 HTML, CSS, and JavaScript-- in the prior week, week eight. 36 00:01:32,700 --> 00:01:34,650 But we saw some limitations of them. 37 00:01:34,650 --> 00:01:37,260 Maybe if you've worked on the homepage problem-- 38 00:01:37,260 --> 00:01:39,360 you've been doing a lot of copying and pasting, 39 00:01:39,360 --> 00:01:41,970 or you weren't able to do everything you wanted to do. 40 00:01:41,970 --> 00:01:44,250 Well, Flask comes in to help you build something that 41 00:01:44,250 --> 00:01:46,290 is going to be more dynamic for you. 42 00:01:46,290 --> 00:01:49,410 And one of my favorite examples of this, of a more dynamic website 43 00:01:49,410 --> 00:01:52,320 that Flask can enable us to build is something like this one right 44 00:01:52,320 --> 00:01:55,860 here, libraryofbabel.info. 45 00:01:55,860 --> 00:01:57,990 And you can actually go to this site. 46 00:01:57,990 --> 00:02:02,730 This site is based on the book, Library of Babel by Jorge Luis Borges. 47 00:02:02,730 --> 00:02:06,330 And in this book, this author imagines this library 48 00:02:06,330 --> 00:02:08,370 that has all the possible stories that have ever 49 00:02:08,370 --> 00:02:10,620 been written, the stories have been written before us, 50 00:02:10,620 --> 00:02:14,220 ahead of us, currently right now, because every book contains 51 00:02:14,220 --> 00:02:16,860 these random assortments of the 26 characters. 52 00:02:16,860 --> 00:02:19,110 This is an infinite library with infinite books 53 00:02:19,110 --> 00:02:22,350 and contains all the possible stories that have been written 54 00:02:22,350 --> 00:02:23,610 or could be written. 55 00:02:23,610 --> 00:02:26,115 And we can actually build our own website along the same, 56 00:02:26,115 --> 00:02:27,990 but let's check out this one just to be sure. 57 00:02:27,990 --> 00:02:32,280 So you can go to this you URL right here, libraryofbabel.info. 58 00:02:32,280 --> 00:02:34,680 And I'll do the same over here on my computer. 59 00:02:34,680 --> 00:02:35,830 I'll go over here. 60 00:02:35,830 --> 00:02:38,850 And you might see a home page like this, if I zoom in for you. 61 00:02:38,850 --> 00:02:42,570 And you can see we can browse this library to see what is inside of it. 62 00:02:42,570 --> 00:02:44,130 I'll click browse here. 63 00:02:44,130 --> 00:02:48,450 And maybe I'll choose to go to like the first section of this library. 64 00:02:48,450 --> 00:02:51,030 I'll go to section zero down here. 65 00:02:51,030 --> 00:02:51,870 I'll click on it. 66 00:02:51,870 --> 00:02:54,840 And I see I'm in this room with four walls around me. 67 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, 68 00:02:59,700 --> 00:03:00,270 right? 69 00:03:00,270 --> 00:03:04,080 And I'll look, maybe just at this third shelf, just randomly, now. 70 00:03:04,080 --> 00:03:06,745 And I'll go down to, let's say this book right here. 71 00:03:06,745 --> 00:03:08,370 Let's pick one randomly from the shelf. 72 00:03:08,370 --> 00:03:10,980 And you'll see that I have this page full of just 73 00:03:10,980 --> 00:03:13,080 lots of random bits of text. 74 00:03:13,080 --> 00:03:16,920 But the idea is, there are so many books in this library, 75 00:03:16,920 --> 00:03:20,520 full of so many pieces of random text, that all the stories that could 76 00:03:20,520 --> 00:03:23,133 possibly be made are somewhere in here. 77 00:03:23,133 --> 00:03:25,050 And so if you take my word for it, we actually 78 00:03:25,050 --> 00:03:27,150 go to the search function for this website. 79 00:03:27,150 --> 00:03:31,080 I'll go back to the home page here by going to that slash route. 80 00:03:31,080 --> 00:03:33,180 And I'll go down to search at this point. 81 00:03:33,180 --> 00:03:34,950 Maybe I'll search in this library. 82 00:03:34,950 --> 00:03:37,380 And I can Enter up to a certain number of characters here. 83 00:03:37,380 --> 00:03:41,820 Maybe I'll search for this is CS-- 84 00:03:41,820 --> 00:03:43,110 and I can't type 50. 85 00:03:43,110 --> 00:03:48,930 I'll say this is computer science fifty week nine section. 86 00:03:48,930 --> 00:03:50,710 I'll zoom in so you can see it there. 87 00:03:50,710 --> 00:03:54,300 And I want to find out where is this text in this infinite library of books? 88 00:03:54,300 --> 00:03:57,610 So I'll go down and I'll hit Search. 89 00:03:57,610 --> 00:04:01,840 And I can see down below, it shows up in a few different places. 90 00:04:01,840 --> 00:04:04,610 I can see the places it shows up with random characters around it. 91 00:04:04,610 --> 00:04:08,150 So I'll click this one, it looks like it's on page 61. 92 00:04:08,150 --> 00:04:09,400 I can see it highlighted here. 93 00:04:09,400 --> 00:04:13,030 This is computer science fifty week nine section-- 94 00:04:13,030 --> 00:04:14,590 whoops-- right down in here. 95 00:04:14,590 --> 00:04:18,290 And this is on page 61 of some random book 96 00:04:18,290 --> 00:04:20,282 that we can see the location of down here. 97 00:04:20,282 --> 00:04:21,490 And we can go back over here. 98 00:04:21,490 --> 00:04:22,990 We can search for other places, too. 99 00:04:22,990 --> 00:04:24,710 Maybe with some other English words. 100 00:04:24,710 --> 00:04:28,490 This is another book that it's in right over here. 101 00:04:28,490 --> 00:04:31,210 And so we can look at all of these books and see all the places 102 00:04:31,210 --> 00:04:33,220 that this phrase shows up. 103 00:04:33,220 --> 00:04:36,460 And all this is done just by virtue of taking in some random text 104 00:04:36,460 --> 00:04:40,400 and figuring out what it might make out of the randomness that we have here. 105 00:04:40,400 --> 00:04:43,518 So if we think about how this website is made, let's think about some 106 00:04:43,518 --> 00:04:45,310 of the routes we can go to-- some of places 107 00:04:45,310 --> 00:04:48,080 we can explore at the very basics first here. 108 00:04:48,080 --> 00:04:50,620 So if we go back to our slides over here. 109 00:04:50,620 --> 00:04:53,110 We think of a website often having these routes 110 00:04:53,110 --> 00:04:55,310 we can go to see different parts of it. 111 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. 112 00:04:58,840 --> 00:05:02,800 If I go to libraryofbabel.info and put a slash at the end, 113 00:05:02,800 --> 00:05:05,260 I'm asking for the home page of this site. 114 00:05:05,260 --> 00:05:07,570 Give me the very basic page of this site. 115 00:05:07,570 --> 00:05:10,000 The very initial site I want to see. 116 00:05:10,000 --> 00:05:14,090 But I could also go to, as we saw, slash-- this is the home page here. 117 00:05:14,090 --> 00:05:17,350 I could also go to slash browse.cgi. 118 00:05:17,350 --> 00:05:20,230 And this is just a name that the author of this website 119 00:05:20,230 --> 00:05:24,070 kind of made up browser-- browse.cgi sounded OK for their purposes. 120 00:05:24,070 --> 00:05:27,970 And when I ask for this route, browse.cgi, 121 00:05:27,970 --> 00:05:30,220 we'll all see something different. 122 00:05:30,220 --> 00:05:32,065 I'll go down here and see I-- 123 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. 124 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. 125 00:05:41,963 --> 00:05:45,130 And I ask the server different pieces to give me back different other pieces 126 00:05:45,130 --> 00:05:46,690 of the site I'm looking for. 127 00:05:46,690 --> 00:05:49,690 We could even, if we wanted to, add some parameters to it 128 00:05:49,690 --> 00:05:52,870 and look at particular books, if we wanted to, using something like this, 129 00:05:52,870 --> 00:05:56,560 having parameters and these dot dot dots at the end here. 130 00:05:56,560 --> 00:05:58,360 Now how is this really working? 131 00:05:58,360 --> 00:06:01,480 You can imagine this website is full of these HTML pages look a bit 132 00:06:01,480 --> 00:06:02,410 like this, right? 133 00:06:02,410 --> 00:06:05,067 And maybe if you were working on home page last week, 134 00:06:05,067 --> 00:06:06,400 you could think of it like this. 135 00:06:06,400 --> 00:06:10,060 Or we have maybe trillions of HTML pages full of different text. 136 00:06:10,060 --> 00:06:10,870 And let's see. 137 00:06:10,870 --> 00:06:14,630 So if I were to request a page from this server right here, 138 00:06:14,630 --> 00:06:15,790 I can make an HTTP request. 139 00:06:15,790 --> 00:06:16,840 I might say this. 140 00:06:16,840 --> 00:06:20,890 Give me the slash browse.cgi page. 141 00:06:20,890 --> 00:06:21,710 I'll do this. 142 00:06:21,710 --> 00:06:24,043 You're going to get back a 200 code for everything's OK, 143 00:06:24,043 --> 00:06:26,830 and give me back that page over here. 144 00:06:26,830 --> 00:06:29,370 But now, if I wanted to see the text of this site, 145 00:06:29,370 --> 00:06:31,120 well, I could think of it a bit like this. 146 00:06:31,120 --> 00:06:32,080 Go over here. 147 00:06:32,080 --> 00:06:38,080 I might see on the right hand side, well, some text up here on-- 148 00:06:38,080 --> 00:06:42,320 sorry, the left hand side and then some HTML on the right hand side. 149 00:06:42,320 --> 00:06:44,560 And again, if you're working on a homepage last week, 150 00:06:44,560 --> 00:06:46,477 you might have seen something like this, where 151 00:06:46,477 --> 00:06:49,370 I could actually try to put in the random string of text here. 152 00:06:49,370 --> 00:06:53,230 But how many pages would we need to have all of this kind of text? 153 00:06:53,230 --> 00:06:56,680 If it's all random, it's all a combinations of these 26 characters, 154 00:06:56,680 --> 00:07:00,550 how many HTML pages would we possibly need here if we had so many of these? 155 00:07:00,550 --> 00:07:02,350 Feel free to chime in in the chat. 156 00:07:02,350 --> 00:07:05,920 How many would we really need to have all combinations of these 26 157 00:07:05,920 --> 00:07:06,670 characters? 158 00:07:06,670 --> 00:07:12,090 159 00:07:12,090 --> 00:07:13,890 I'm seeing a lot. 160 00:07:13,890 --> 00:07:16,590 We need a lot of pages, right, for all of these 26 161 00:07:16,590 --> 00:07:18,850 characters, all combinations of them. 162 00:07:18,850 --> 00:07:21,060 And so if we had trillions of these pages, 163 00:07:21,060 --> 00:07:23,180 well, that's not very efficient for us. 164 00:07:23,180 --> 00:07:28,440 We could do, instead, probably better, is we could actually have a single HTML 165 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 166 00:07:33,390 --> 00:07:36,122 using something like Python or Flask, in this case. 167 00:07:36,122 --> 00:07:37,830 So we could do something like this, where 168 00:07:37,830 --> 00:07:40,260 instead of having millions and millions of pages that 169 00:07:40,260 --> 00:07:43,540 have all these random strings of text, we could have one page 170 00:07:43,540 --> 00:07:47,520 and we could use Python to slot in a single random string for us-- 171 00:07:47,520 --> 00:07:50,350 perhaps in this placeholder right over here. 172 00:07:50,350 --> 00:07:52,500 So let's actually explore how we could build 173 00:07:52,500 --> 00:07:55,143 our own mini-version of this website, where 174 00:07:55,143 --> 00:07:57,060 we can generate random strings of text and see 175 00:07:57,060 --> 00:08:01,000 if we find any interesting, useful information from that piece of text. 176 00:08:01,000 --> 00:08:03,990 So I'll go to my code space over here. 177 00:08:03,990 --> 00:08:06,480 And I've already set up this Flask application. 178 00:08:06,480 --> 00:08:07,590 I can zoom in a bit. 179 00:08:07,590 --> 00:08:08,970 And I'll type ls. 180 00:08:08,970 --> 00:08:11,370 And you can see I have these files down below. 181 00:08:11,370 --> 00:08:15,600 I have app.py, I have helpers.py, which is a similar file name 182 00:08:15,600 --> 00:08:17,400 you'll see in this week's problem set. 183 00:08:17,400 --> 00:08:21,060 I have history.db, and I have a templates folder. 184 00:08:21,060 --> 00:08:26,652 And just to refresh our memory, what do you think will go in app.py? 185 00:08:26,652 --> 00:08:29,880 I mean, what language is that written in and what do you 186 00:08:29,880 --> 00:08:32,159 think we'll put inside of it, as we saw in lecture? 187 00:08:32,159 --> 00:08:34,049 Feel free to chime in in the chat. 188 00:08:34,049 --> 00:08:37,926 What will go inside of app.py. 189 00:08:37,926 --> 00:08:39,853 So I'm seeing Python, Flask. 190 00:08:39,853 --> 00:08:42,270 Right, yeah, this is we're going to write some of our code 191 00:08:42,270 --> 00:08:44,940 that will be written in Python, and we'll 192 00:08:44,940 --> 00:08:49,290 use the Flask library inside of app.py. 193 00:08:49,290 --> 00:08:50,760 So I can open that up a little bit. 194 00:08:50,760 --> 00:08:53,670 I'll code app.py, and we'll get you a taste 195 00:08:53,670 --> 00:08:56,790 of what this is doing for us, which we'll explore in much more depth 196 00:08:56,790 --> 00:08:57,930 later on. 197 00:08:57,930 --> 00:09:00,530 OK, this is our basic Flask app. 198 00:09:00,530 --> 00:09:04,850 Now though, I also have history.db up here. 199 00:09:04,850 --> 00:09:12,290 And knowing what we know about dot db files, what kind of file is this? 200 00:09:12,290 --> 00:09:13,850 History.db. 201 00:09:13,850 --> 00:09:15,020 It's a database, right? 202 00:09:15,020 --> 00:09:19,670 So we have some application, app.py will write our Flask code, 203 00:09:19,670 --> 00:09:23,390 and we also have this database called history.db. 204 00:09:23,390 --> 00:09:26,670 And inside of templates, what do you expect we might find? 205 00:09:26,670 --> 00:09:31,570 If I were to cd into templates to look inside. 206 00:09:31,570 --> 00:09:32,200 HTML, right. 207 00:09:32,200 --> 00:09:34,150 So I could cd templates here. 208 00:09:34,150 --> 00:09:36,100 I'll type ls, list my files. 209 00:09:36,100 --> 00:09:42,040 And I'll see two HTML files, index.html and layout.html. 210 00:09:42,040 --> 00:09:45,410 So let's get a feel for what this is doing for us already. 211 00:09:45,410 --> 00:09:49,570 So I'll type ls to see my application files here. 212 00:09:49,570 --> 00:09:53,380 I'll then type Flask run to run this application. 213 00:09:53,380 --> 00:09:55,690 This is different from HTTP server. 214 00:09:55,690 --> 00:09:58,630 I want to run this application using Flask. 215 00:09:58,630 --> 00:10:01,850 So I'll do Flask run, hit Enter. 216 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. 217 00:10:09,040 --> 00:10:12,930 And now I should see this very basic website, Library of Babel 218 00:10:12,930 --> 00:10:14,890 with a search history down below. 219 00:10:14,890 --> 00:10:16,770 Now this is not presently done yet. 220 00:10:16,770 --> 00:10:18,720 For one, there's no text on the screen. 221 00:10:18,720 --> 00:10:21,660 Ideally, you'd want to have some random string of tax we'd actually 222 00:10:21,660 --> 00:10:23,730 generate every time we visit this site to see 223 00:10:23,730 --> 00:10:26,560 if we get any meaningful words from it. 224 00:10:26,560 --> 00:10:29,670 So if we look at our application here, I'll 225 00:10:29,670 --> 00:10:33,480 go ahead and open up a new terminal. 226 00:10:33,480 --> 00:10:38,490 And I will get back to my library folder and I'll 227 00:10:38,490 --> 00:10:42,190 code app.py to pull up this file. 228 00:10:42,190 --> 00:10:45,600 So here is our very basic Flask application, 229 00:10:45,600 --> 00:10:47,220 if y'all can see at this text size. 230 00:10:47,220 --> 00:10:49,620 Let me know if you can't. 231 00:10:49,620 --> 00:10:52,850 From lines one through four, what would you say we're doing here? 232 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 233 00:10:56,548 --> 00:10:57,090 through four? 234 00:10:57,090 --> 00:11:02,260 What's the purpose of these lines of code, just in general? 235 00:11:02,260 --> 00:11:04,880 Seeing some imports. 236 00:11:04,880 --> 00:11:06,850 Other things you might think, too? 237 00:11:06,850 --> 00:11:09,520 Setting up library access, yes, definitely. 238 00:11:09,520 --> 00:11:15,140 So here on lines one through four, we're simply telling our application, 239 00:11:15,140 --> 00:11:19,120 these are the libraries we're going to use in our program. 240 00:11:19,120 --> 00:11:21,280 Pieces of code somebody else has written for us. 241 00:11:21,280 --> 00:11:24,280 We'll use these in our application. 242 00:11:24,280 --> 00:11:28,870 Notice how I'm using the CS50 library here to get something called SQL. 243 00:11:28,870 --> 00:11:33,070 I'm using the Flask library here to get something called Flask, also, 244 00:11:33,070 --> 00:11:37,600 and also this render template function, and something called request. 245 00:11:37,600 --> 00:11:40,930 And I also have from helpers import random strings. 246 00:11:40,930 --> 00:11:46,060 So notice how I had back in my list of files here, helpers.py. 247 00:11:46,060 --> 00:11:50,110 Well, I could open up helpers.py here to show you what's inside. 248 00:11:50,110 --> 00:11:54,260 And I do have this function that I defined called random string. 249 00:11:54,260 --> 00:11:58,540 And if I give it some variable called len, some argument called len, 250 00:11:58,540 --> 00:12:03,290 I'll then get back a random string that has that length of characters. 251 00:12:03,290 --> 00:12:08,860 So if I said random string 500, I would get a string of 500 random characters. 252 00:12:08,860 --> 00:12:10,180 And I made this myself. 253 00:12:10,180 --> 00:12:15,540 But instead of putting it inside of my app.py, what I did instead, 254 00:12:15,540 --> 00:12:18,440 sort of copy and paste this into app.py, is I said, well, 255 00:12:18,440 --> 00:12:20,290 I want to keep things separate here. 256 00:12:20,290 --> 00:12:24,160 I'll put this helper function inside of helpers.py. 257 00:12:24,160 --> 00:12:29,330 Similar to what you'll see this week with the finance problem set over here. 258 00:12:29,330 --> 00:12:29,830 OK. 259 00:12:29,830 --> 00:12:32,340 And then finally, we're just importing the random library 260 00:12:32,340 --> 00:12:34,260 so we can get access to some of its functions. 261 00:12:34,260 --> 00:12:36,815 We'll see those later on in a bit. 262 00:12:36,815 --> 00:12:39,190 Now down below is where we get a little more interesting. 263 00:12:39,190 --> 00:12:42,400 So here on line six as we saw in lecture, 264 00:12:42,400 --> 00:12:45,210 we're kind of setting up our Flask application to run. 265 00:12:45,210 --> 00:12:47,790 You could think of this piece of code, right here, 266 00:12:47,790 --> 00:12:52,410 capital F, Flask, as being this template for a Flask application, 267 00:12:52,410 --> 00:12:54,570 that comes with some built in functionality, 268 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, 269 00:12:58,110 --> 00:12:59,010 on our website. 270 00:12:59,010 --> 00:13:03,240 But here we're saying, let's make a particular Flask application, 271 00:13:03,240 --> 00:13:07,508 and let's make sure that it corresponds to this current file-- 272 00:13:07,508 --> 00:13:09,300 that's what dunder name here it's something 273 00:13:09,300 --> 00:13:12,600 for us-- underscore underscore name, underscore underscore [INAUDIBLE] 274 00:13:12,600 --> 00:13:18,360 dunder name, is going to say build me a particular Flask app based on this file 275 00:13:18,360 --> 00:13:19,470 right here. 276 00:13:19,470 --> 00:13:22,127 And for the rest of this file, let's just call it app. 277 00:13:22,127 --> 00:13:23,460 We could call it something else. 278 00:13:23,460 --> 00:13:24,988 We could call it library here. 279 00:13:24,988 --> 00:13:27,030 But notice how we have to change everything else. 280 00:13:27,030 --> 00:13:31,170 We have to say library.config or library.route. 281 00:13:31,170 --> 00:13:34,140 So in the end, it's probably easier to call it app throughout, 282 00:13:34,140 --> 00:13:37,800 this kind of short name we can use to refer to our own Flask application 283 00:13:37,800 --> 00:13:40,590 we're building from this file. 284 00:13:40,590 --> 00:13:43,260 Now down below, we also have some connection to our database 285 00:13:43,260 --> 00:13:44,310 as we saw in lecture. 286 00:13:44,310 --> 00:13:47,820 This is saying, give me some variable called db, 287 00:13:47,820 --> 00:13:52,080 that I can then use to refer to this database called history.db 288 00:13:52,080 --> 00:13:54,420 that will access using sqlite. 289 00:13:54,420 --> 00:13:57,120 And then down below, let me just have some configuration 290 00:13:57,120 --> 00:14:01,090 to say that I want my HTML to auto reload when I change it. 291 00:14:01,090 --> 00:14:03,240 So if I go to an HTML, make a change, I want 292 00:14:03,240 --> 00:14:06,900 to see that change kind of automatically in my browser. 293 00:14:06,900 --> 00:14:09,120 And then finally, this little bit of code down here-- 294 00:14:09,120 --> 00:14:10,530 at app.route. 295 00:14:10,530 --> 00:14:13,870 Where have we seen this slash before? 296 00:14:13,870 --> 00:14:18,750 What does it often correspond to in our applications? 297 00:14:18,750 --> 00:14:20,205 We saw this just a little bit ago. 298 00:14:20,205 --> 00:14:22,730 299 00:14:22,730 --> 00:14:26,870 Yeah, so I'm seeing the root folder, the home page. 300 00:14:26,870 --> 00:14:30,320 Whenever we ask for the slash root of an application, 301 00:14:30,320 --> 00:14:33,950 we're often asking for that main page-- that home page of the site. 302 00:14:33,950 --> 00:14:39,200 And so the hint here is that at app.route, if I say slash here, 303 00:14:39,200 --> 00:14:41,480 that's going to say, well, I'm going to define 304 00:14:41,480 --> 00:14:44,630 some function I can run whenever the user requests 305 00:14:44,630 --> 00:14:47,800 the slash root of my application. 306 00:14:47,800 --> 00:14:51,030 And then down below, notice how I have this function called index. 307 00:14:51,030 --> 00:14:56,100 I'm going to define, again, some function I can use to-- 308 00:14:56,100 --> 00:14:59,220 function I can use when the user asks for that slash root, 309 00:14:59,220 --> 00:15:02,700 I will run this function top to bottom every time they ask for it. 310 00:15:02,700 --> 00:15:05,310 And in this case, it looks like I'm just returning 311 00:15:05,310 --> 00:15:09,870 the result of this function, render template index.html. 312 00:15:09,870 --> 00:15:13,710 So I'm giving back the home page, which is what we saw, again, 313 00:15:13,710 --> 00:15:15,480 when I went to my slash root here. 314 00:15:15,480 --> 00:15:21,240 I then see my home page of my site that's inside of index.html. 315 00:15:21,240 --> 00:15:25,330 So questions on this syntax so far? 316 00:15:25,330 --> 00:15:27,000 Feel free to ask in the chat. 317 00:15:27,000 --> 00:15:29,460 This is kind of a lot all at once, but I want 318 00:15:29,460 --> 00:15:31,830 to make sure we get your questions answered. 319 00:15:31,830 --> 00:15:39,610 320 00:15:39,610 --> 00:15:40,500 OK. 321 00:15:40,500 --> 00:15:42,990 So feel free to keep putting questions in the chat. 322 00:15:42,990 --> 00:15:44,670 I see one coming in. 323 00:15:44,670 --> 00:15:47,640 Where are the imported libraries actually imported from? 324 00:15:47,640 --> 00:15:51,960 So presumably, these libraries are somewhere on your computer. 325 00:15:51,960 --> 00:15:54,960 And in fact, they're probably in some kind of special folder for Python. 326 00:15:54,960 --> 00:15:57,490 They might be even brought in from the web a little bit. 327 00:15:57,490 --> 00:15:59,400 I'm actually not quite sure exactly where they are, 328 00:15:59,400 --> 00:16:00,450 but they are somewhere, right? 329 00:16:00,450 --> 00:16:02,250 And Python is getting them from someplace. 330 00:16:02,250 --> 00:16:03,380 So I can't answer your question in particular, 331 00:16:03,380 --> 00:16:06,255 but you could probably look it up online and figure out where are you 332 00:16:06,255 --> 00:16:07,500 importing these things from. 333 00:16:07,500 --> 00:16:09,840 I can tell you, though, that for example, 334 00:16:09,840 --> 00:16:12,360 from helpers import random string, well, that 335 00:16:12,360 --> 00:16:16,380 is being imported right from this file called helpers.py, 336 00:16:16,380 --> 00:16:21,350 that we see is right next to our app.py, right here. 337 00:16:21,350 --> 00:16:24,620 And a question-- what is dunder name doing, dunder name referring 338 00:16:24,620 --> 00:16:27,770 to underscore underscore name underscore underscore. 339 00:16:27,770 --> 00:16:31,640 That is simply a special Python variable name that 340 00:16:31,640 --> 00:16:35,810 refers to the name of this file app. 341 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 342 00:16:40,760 --> 00:16:44,570 app that we have, capital F, Flask here, let's go ahead 343 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 344 00:16:49,670 --> 00:16:50,780 that we're going to call-- 345 00:16:50,780 --> 00:16:52,430 well that is presently called app. 346 00:16:52,430 --> 00:16:57,080 So this gives our application access to all the other kind of files and folders 347 00:16:57,080 --> 00:16:59,150 that matter for our application. 348 00:16:59,150 --> 00:17:02,360 349 00:17:02,360 --> 00:17:02,860 All right. 350 00:17:02,860 --> 00:17:04,339 These are good questions. 351 00:17:04,339 --> 00:17:07,119 So let's keep going on and figuring out how this corresponds 352 00:17:07,119 --> 00:17:10,150 with our HTML for our program so far. 353 00:17:10,150 --> 00:17:11,650 So I'll go back to my terminal. 354 00:17:11,650 --> 00:17:15,670 And all this time code up index.html. 355 00:17:15,670 --> 00:17:17,290 And why don't I put it-- 356 00:17:17,290 --> 00:17:21,339 just for the sake of visualizing it-- kind of side by side here. 357 00:17:21,339 --> 00:17:23,760 Do this. 358 00:17:23,760 --> 00:17:24,349 Whoops. 359 00:17:24,349 --> 00:17:26,849 Let me move this over here. 360 00:17:26,849 --> 00:17:28,210 There we go. 361 00:17:28,210 --> 00:17:33,930 And now we can see our Python code, right alongside our HTML code. 362 00:17:33,930 --> 00:17:37,890 And this is helpful because often when we're working with Flask, 363 00:17:37,890 --> 00:17:41,970 you do want to have some kind of correspondence between our HTML 364 00:17:41,970 --> 00:17:45,510 and our Python code-- in some cases, variable names will matter. 365 00:17:45,510 --> 00:17:48,820 And if we're talking about trying to insert some text to our HTML, 366 00:17:48,820 --> 00:17:51,610 well, it's important to visualize those things side by side. 367 00:17:51,610 --> 00:17:53,735 So we'll do that from here on out, assuming you all 368 00:17:53,735 --> 00:17:56,340 can still read the text size here. 369 00:17:56,340 --> 00:17:59,960 So if we visit our page and I refresh it, 370 00:17:59,960 --> 00:18:02,960 I don't really see any piece of text. 371 00:18:02,960 --> 00:18:05,760 But again, our goal was to insert this piece of text 372 00:18:05,760 --> 00:18:09,560 so we could actually see it come to life and we could regenerate some new text 373 00:18:09,560 --> 00:18:11,820 every time we visited the page. 374 00:18:11,820 --> 00:18:16,880 Well, if I wanted to generate just a random string of characters, 375 00:18:16,880 --> 00:18:20,430 I could do that using my random string function up here. 376 00:18:20,430 --> 00:18:21,860 So let me try to use that. 377 00:18:21,860 --> 00:18:25,280 I'll go to index function down here, which, again, is called 378 00:18:25,280 --> 00:18:27,440 whenever I visit that slash root. 379 00:18:27,440 --> 00:18:29,540 I'll put this to the side for now. 380 00:18:29,540 --> 00:18:31,760 I'll come down here and I'll say, I want to get 381 00:18:31,760 --> 00:18:38,150 a string that is going to get me the result of, in this case, random string. 382 00:18:38,150 --> 00:18:43,550 And I'll ask for a string of maybe 1,000 characters, right? 383 00:18:43,550 --> 00:18:48,230 So now if I were to just print string, I should hopefully 384 00:18:48,230 --> 00:18:52,130 see that I have this random string of text inside my terminal, 385 00:18:52,130 --> 00:18:54,470 because print here will print to my terminal. 386 00:18:54,470 --> 00:18:56,090 So open up my terminal. 387 00:18:56,090 --> 00:18:57,950 I'll go back to my server. 388 00:18:57,950 --> 00:19:01,770 And let me go ahead and just refresh the page over here. 389 00:19:01,770 --> 00:19:04,940 I'll hit slash, go to my slash root, hit Enter. 390 00:19:04,940 --> 00:19:07,220 And now nothing changes on my HTML. 391 00:19:07,220 --> 00:19:10,400 But if I look inside of my terminal, I do 392 00:19:10,400 --> 00:19:12,140 see this random piece of text I generated 393 00:19:12,140 --> 00:19:14,850 right, about 1,000 random characters. 394 00:19:14,850 --> 00:19:22,260 So how could I then get this string, perhaps, inside of my HTML? 395 00:19:22,260 --> 00:19:25,980 Any ideas from what we saw from lecture recently? 396 00:19:25,980 --> 00:19:30,220 397 00:19:30,220 --> 00:19:32,350 We have this variable called string. 398 00:19:32,350 --> 00:19:38,270 But how should we get it inside of our HTML? 399 00:19:38,270 --> 00:19:42,448 So I'm seeing using some equals, some maybe braces. 400 00:19:42,448 --> 00:19:43,990 And so you're all on the right track. 401 00:19:43,990 --> 00:19:47,860 So notice how here in our index HTML, we do 402 00:19:47,860 --> 00:19:50,020 have this placeholder already set up for us. 403 00:19:50,020 --> 00:19:53,940 Let me zoom in on it on the right hand side. 404 00:19:53,940 --> 00:19:55,880 You can see we have this placeholder here. 405 00:19:55,880 --> 00:19:59,840 And using what's now Jinja syntax, we can say, 406 00:19:59,840 --> 00:20:05,330 I want to have a placeholder, some value I want to write in to my HTML. 407 00:20:05,330 --> 00:20:08,420 And I can denote it with these curly braces on either side-- 408 00:20:08,420 --> 00:20:10,300 double curly braces. 409 00:20:10,300 --> 00:20:13,000 And then the inside of these braces, I can 410 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. 411 00:20:17,140 --> 00:20:20,110 Here I'm just calling it placeholder, I could also call it string. 412 00:20:20,110 --> 00:20:24,300 I can call it really anything, but here I'll just call it placeholder. 413 00:20:24,300 --> 00:20:30,150 Now if I wanted to pass in string to be kind of interpolated 414 00:20:30,150 --> 00:20:32,980 or put inside as HTML, I could do this. 415 00:20:32,980 --> 00:20:36,910 I could say, when I call this function, render template, 416 00:20:36,910 --> 00:20:42,150 let's go ahead and make sure that placeholder gets the value of string, 417 00:20:42,150 --> 00:20:45,210 in this case, as somebody in the chat has already noted. 418 00:20:45,210 --> 00:20:47,740 Placeholder equals string. 419 00:20:47,740 --> 00:20:52,570 So what I'm doing is taking my Python variable, string, and saying, 420 00:20:52,570 --> 00:20:56,730 let's put it inside of my HTML in the placeholder that's literally called 421 00:20:56,730 --> 00:20:57,450 placeholder. 422 00:20:57,450 --> 00:20:59,310 And I know that it is right here because I 423 00:20:59,310 --> 00:21:04,450 can see it in double curly braces using Jinja syntax on the right hand side. 424 00:21:04,450 --> 00:21:08,130 So now if I go back and refresh the page, hit Enter here, 425 00:21:08,130 --> 00:21:09,990 I do actually see my random string of text. 426 00:21:09,990 --> 00:21:11,782 And I can actually do this again and again. 427 00:21:11,782 --> 00:21:13,860 I'll hit refresh to see a new random text. 428 00:21:13,860 --> 00:21:16,210 Refresh again and refresh again. 429 00:21:16,210 --> 00:21:18,930 And now I see this piece of text, over, and over, 430 00:21:18,930 --> 00:21:24,330 and over again, constantly regenerating every time I call the slash root, 431 00:21:24,330 --> 00:21:28,230 and thus, the index function here. 432 00:21:28,230 --> 00:21:30,680 So what questions do you have on this so far, 433 00:21:30,680 --> 00:21:35,270 and how we're interpolating or adding in some of our variables 434 00:21:35,270 --> 00:21:37,865 from Python to our HTML? 435 00:21:37,865 --> 00:21:48,950 436 00:21:48,950 --> 00:21:50,620 Yeah, so one piece we haven't seen yet-- 437 00:21:50,620 --> 00:21:55,400 I see a question in the chat-- is about this methods equals GET. 438 00:21:55,400 --> 00:22:02,240 So here, when we define a route of our application using Flask, we're saying, 439 00:22:02,240 --> 00:22:04,610 here's what the user can type in, in the URL, 440 00:22:04,610 --> 00:22:08,240 to run this function down below, and also, 441 00:22:08,240 --> 00:22:12,410 here are the methods they can use to access this route. 442 00:22:12,410 --> 00:22:15,380 So remember how there are two HTTP methods-- 443 00:22:15,380 --> 00:22:20,480 GET and POST-- where GET simply involves the user asking 444 00:22:20,480 --> 00:22:22,200 the server for some web page. 445 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. 446 00:22:26,660 --> 00:22:31,160 POST on the other hand, is about sending some data through a form, most likely, 447 00:22:31,160 --> 00:22:32,510 to your server. 448 00:22:32,510 --> 00:22:34,710 And the server then does something with that data. 449 00:22:34,710 --> 00:22:37,100 So here, because we're just asking-- 450 00:22:37,100 --> 00:22:41,210 because the user is just asking our application for, really, 451 00:22:41,210 --> 00:22:44,120 a random string, we can safely use GET. 452 00:22:44,120 --> 00:22:46,430 But as we'll see later on in just a moment here, 453 00:22:46,430 --> 00:22:48,410 we'll try to make our own form and you can 454 00:22:48,410 --> 00:22:50,430 POST data or send data to our server. 455 00:22:50,430 --> 00:22:53,920 So we should use POST in that case, too. 456 00:22:53,920 --> 00:22:57,470 And I see a question, what is SQLite doing up here? 457 00:22:57,470 --> 00:23:00,790 So notice how, if you recall from week seven, 458 00:23:00,790 --> 00:23:03,800 SQLite is this database engine that we use. 459 00:23:03,800 --> 00:23:07,270 And so this line up here, line eight, db equals SQL, 460 00:23:07,270 --> 00:23:09,890 SQLite colon slash slash history.db is saying, 461 00:23:09,890 --> 00:23:16,180 let's build a connection to our database called history.db using SQLite. 462 00:23:16,180 --> 00:23:21,460 And within Python, let's go ahead and call that connection just db, 463 00:23:21,460 --> 00:23:22,240 in general. 464 00:23:22,240 --> 00:23:27,250 And we can use something like db to execute to run queries on our database 465 00:23:27,250 --> 00:23:31,460 that we'll see later towards the end of section here. 466 00:23:31,460 --> 00:23:31,960 All right. 467 00:23:31,960 --> 00:23:34,360 Other questions, too, on this so far? 468 00:23:34,360 --> 00:23:42,110 469 00:23:42,110 --> 00:23:43,890 All right. 470 00:23:43,890 --> 00:23:45,890 So let's keep going here. 471 00:23:45,890 --> 00:23:48,380 And maybe one thing we'd like to do is actually 472 00:23:48,380 --> 00:23:52,080 have more than one variable inside of our HTML. 473 00:23:52,080 --> 00:23:55,940 So let's say I went up here and I went down to-- 474 00:23:55,940 --> 00:23:57,860 I don't want to call it Library of Babel. 475 00:23:57,860 --> 00:24:02,130 Maybe I just want to just call it Library of some name I can pass in. 476 00:24:02,130 --> 00:24:06,770 So to update this, what can I do to the end of render template? 477 00:24:06,770 --> 00:24:10,460 I have this placeholder called name, and it's a placeholder 478 00:24:10,460 --> 00:24:15,590 because I have braces brace, brace, brace, with name on the inside. 479 00:24:15,590 --> 00:24:19,180 So how could I then update this here? 480 00:24:19,180 --> 00:24:22,568 481 00:24:22,568 --> 00:24:23,610 Anyone chime in the chat? 482 00:24:23,610 --> 00:24:26,280 How could I substitute a name in here? 483 00:24:26,280 --> 00:24:29,900 484 00:24:29,900 --> 00:24:30,400 Yeah. 485 00:24:30,400 --> 00:24:31,480 So name equals something. 486 00:24:31,480 --> 00:24:32,650 I can say colon-- 487 00:24:32,650 --> 00:24:33,340 or not colon. 488 00:24:33,340 --> 00:24:37,520 A comma, name equals perhaps Carter. 489 00:24:37,520 --> 00:24:38,745 Hope you can see that. 490 00:24:38,745 --> 00:24:41,120 And then I'll go ahead and go over here refresh the page. 491 00:24:41,120 --> 00:24:42,940 And now I see library of Carter. 492 00:24:42,940 --> 00:24:46,210 So here's one more example of having multiple different values 493 00:24:46,210 --> 00:24:48,280 you can pass in to our HTML. 494 00:24:48,280 --> 00:24:53,280 I could change this also to Joel, hit Enter here. 495 00:24:53,280 --> 00:24:57,650 And now-- whoops, let me refresh this. 496 00:24:57,650 --> 00:24:59,380 And now we see a Library of Joel. 497 00:24:59,380 --> 00:25:02,770 So another way of passing in some data here. 498 00:25:02,770 --> 00:25:08,120 And now often what you will see is this variable called placeholder. 499 00:25:08,120 --> 00:25:11,417 Or really, this placeholder called placeholder isn't really 500 00:25:11,417 --> 00:25:14,000 well named, because if you had to call everything placeholder, 501 00:25:14,000 --> 00:25:15,708 it would get really messy really quickly. 502 00:25:15,708 --> 00:25:19,960 So we could just call this also string, in our HTML. 503 00:25:19,960 --> 00:25:22,960 But then what we'd have to do is go down below here 504 00:25:22,960 --> 00:25:26,145 and say, string equals string, which is a little confusing if you're 505 00:25:26,145 --> 00:25:28,270 a beginner, because on the one hand, you're seeing, 506 00:25:28,270 --> 00:25:30,560 OK, string equals string, we know that. 507 00:25:30,560 --> 00:25:34,270 But what this is really saying is that string on the left hand side 508 00:25:34,270 --> 00:25:37,360 is referring to this placeholder string in our HTML, 509 00:25:37,360 --> 00:25:39,670 and string on the right hand side is referring 510 00:25:39,670 --> 00:25:42,490 to this actual Python variable called string. 511 00:25:42,490 --> 00:25:46,510 So often you'll see these two names being the same thing, 512 00:25:46,510 --> 00:25:50,800 but they refer to different objects or different placeholders or variables 513 00:25:50,800 --> 00:25:52,660 in our programs. 514 00:25:52,660 --> 00:25:55,770 So let's go back and call this maybe not placeholder. 515 00:25:55,770 --> 00:25:58,650 Let's call it maybe a random string over here. 516 00:25:58,650 --> 00:26:01,080 And I'll do the same over here, random string, 517 00:26:01,080 --> 00:26:03,630 just so we can keep a good naming system, 518 00:26:03,630 --> 00:26:12,090 but also try to differentiate the Python variable from the HTML placeholder. 519 00:26:12,090 --> 00:26:13,890 OK. 520 00:26:13,890 --> 00:26:17,620 So a question that comes up is, how do we actually get input from the user 521 00:26:17,620 --> 00:26:18,120 now? 522 00:26:18,120 --> 00:26:19,328 So this is all fine and good. 523 00:26:19,328 --> 00:26:21,150 I can go to my URL, I can refresh it. 524 00:26:21,150 --> 00:26:23,400 And I can see-- oops, let me actually change this. 525 00:26:23,400 --> 00:26:26,830 Library of Babel. 526 00:26:26,830 --> 00:26:27,550 Refresh the page. 527 00:26:27,550 --> 00:26:31,160 And I do see random text over, and over, and over again. 528 00:26:31,160 --> 00:26:34,270 But what if I wanted the user to pick out a page, 529 00:26:34,270 --> 00:26:37,120 like they can do in the real version of this website? 530 00:26:37,120 --> 00:26:39,730 They can go to page 10 or page 410. 531 00:26:39,730 --> 00:26:42,520 They can see the same thing every time. 532 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. 533 00:26:47,900 --> 00:26:51,380 So a form is going to look a bit like this, 534 00:26:51,380 --> 00:26:58,370 where a form is comprised of this open form tag and this closing form tag. 535 00:26:58,370 --> 00:27:03,570 And any ideas as to what often goes inside of a form? 536 00:27:03,570 --> 00:27:04,390 This form is blank. 537 00:27:04,390 --> 00:27:05,730 We don't see anything. 538 00:27:05,730 --> 00:27:10,010 But what goes inside of a form? 539 00:27:10,010 --> 00:27:14,930 Could be a table, some input, other things, too. 540 00:27:14,930 --> 00:27:16,640 A submit. 541 00:27:16,640 --> 00:27:19,440 What else might go inside of a form? 542 00:27:19,440 --> 00:27:20,610 A button, a label. 543 00:27:20,610 --> 00:27:22,950 Yeah, there are lots of things you can add to a form. 544 00:27:22,950 --> 00:27:26,100 And to add them to our forms, we usually put them inside 545 00:27:26,100 --> 00:27:28,240 of these opening and closing tags here. 546 00:27:28,240 --> 00:27:32,470 So form, the opening tag, and slash form the closing tag. 547 00:27:32,470 --> 00:27:37,350 So what I'll do here is I will add this input of type text 548 00:27:37,350 --> 00:27:40,350 and this button of type submit. 549 00:27:40,350 --> 00:27:44,010 Now the default type for input is text, and I 550 00:27:44,010 --> 00:27:46,620 believe the default type for a button is submit. 551 00:27:46,620 --> 00:27:49,410 But here, we're just spelling them out deliberately, here. 552 00:27:49,410 --> 00:27:55,140 Where if I were to render this now-- render this HTML on the left hand side, 553 00:27:55,140 --> 00:27:59,580 I might first see this input box, and that shows up 554 00:27:59,580 --> 00:28:01,440 as this input box on the right hand side. 555 00:28:01,440 --> 00:28:03,480 Some place I can type some text. 556 00:28:03,480 --> 00:28:07,300 And then, I would also have this Submit button over here. 557 00:28:07,300 --> 00:28:09,160 It looks a bit like this. 558 00:28:09,160 --> 00:28:12,820 So together, these pieces are part of my form. 559 00:28:12,820 --> 00:28:15,090 And when I click this Submit button, what 560 00:28:15,090 --> 00:28:18,030 will happen is my data will go somewhere-- 561 00:28:18,030 --> 00:28:21,870 wherever I tell it to, so long as I specified the right things. 562 00:28:21,870 --> 00:28:25,170 And now what actually is missing from this form? 563 00:28:25,170 --> 00:28:29,070 We have our input, we have button to submit it. 564 00:28:29,070 --> 00:28:32,010 But what are we missing, perhaps, in the top form tag? 565 00:28:32,010 --> 00:28:35,000 566 00:28:35,000 --> 00:28:36,400 I'm seeing an action. 567 00:28:36,400 --> 00:28:40,720 An action and a method, where if we have some data, perhaps in our input, 568 00:28:40,720 --> 00:28:43,690 and we click Submit, well, there's really no place 569 00:28:43,690 --> 00:28:44,902 for that data to go yet. 570 00:28:44,902 --> 00:28:47,110 So we should really specify where that data is going. 571 00:28:47,110 --> 00:28:48,190 So I might do this. 572 00:28:48,190 --> 00:28:55,280 I might say also, make sure this form has particular action and a method. 573 00:28:55,280 --> 00:28:58,000 So to get our minds on what this action is, 574 00:28:58,000 --> 00:29:00,200 notice how we see the slash here again. 575 00:29:00,200 --> 00:29:03,340 So this action is telling us where-- 576 00:29:03,340 --> 00:29:06,040 which route we want to actually send our data to. 577 00:29:06,040 --> 00:29:10,450 Is it the slash route, the slash browse route, or a different route altogether? 578 00:29:10,450 --> 00:29:13,300 And then the second one, the request method 579 00:29:13,300 --> 00:29:16,060 is saying, well, how do I want to make that request? 580 00:29:16,060 --> 00:29:19,270 Should I do it via Post or via GET? 581 00:29:19,270 --> 00:29:23,980 And now what might be one difference between using Post and using 582 00:29:23,980 --> 00:29:25,810 GET with a form? 583 00:29:25,810 --> 00:29:27,340 Maybe chime in the chat. 584 00:29:27,340 --> 00:29:32,530 What might be one difference if we used Post versus GET to submit 585 00:29:32,530 --> 00:29:34,090 our data via the form? 586 00:29:34,090 --> 00:29:39,150 587 00:29:39,150 --> 00:29:40,400 So I'm seeing something like-- 588 00:29:40,400 --> 00:29:45,500 Post sends data and GET gets it, which is a true kind of by convention. 589 00:29:45,500 --> 00:29:50,340 We can still send data through get, though. 590 00:29:50,340 --> 00:29:52,860 One is shown in the URL and the other is hidden, 591 00:29:52,860 --> 00:29:55,400 which is a more apt description here, where 592 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. 593 00:30:00,260 --> 00:30:03,230 But if I send it via get it often-- it will show up 594 00:30:03,230 --> 00:30:05,690 in the URL using these URL parameters. 595 00:30:05,690 --> 00:30:09,140 And so Post is good for when we're kind of sending data to the server, 596 00:30:09,140 --> 00:30:10,975 but we don't want people to see. 597 00:30:10,975 --> 00:30:13,100 Or even when we don't really care if people see it, 598 00:30:13,100 --> 00:30:16,770 Post might still be a good method to use. 599 00:30:16,770 --> 00:30:19,910 So let's try building up our own form here. 600 00:30:19,910 --> 00:30:25,490 Let's go to our HTML and see how we have a to do here. 601 00:30:25,490 --> 00:30:29,100 That to do is to implement a search form. 602 00:30:29,100 --> 00:30:32,400 So if I wanted to make this form, what could I do? 603 00:30:32,400 --> 00:30:34,580 I can go ahead and do form. 604 00:30:34,580 --> 00:30:39,020 And then I need to have some kind of text input for the page number 605 00:30:39,020 --> 00:30:40,430 the user is inputting. 606 00:30:40,430 --> 00:30:43,940 Let me actually make this over here and make it a little bigger. 607 00:30:43,940 --> 00:30:47,810 What kind of input element should I make here? 608 00:30:47,810 --> 00:30:49,190 Any ideas from the chat? 609 00:30:49,190 --> 00:30:53,560 610 00:30:53,560 --> 00:30:56,455 What kind of input element do I need to get a page number? 611 00:30:56,455 --> 00:30:59,160 612 00:30:59,160 --> 00:31:00,045 I could use a label. 613 00:31:00,045 --> 00:31:03,730 614 00:31:03,730 --> 00:31:05,950 Yeah, so I'm seeing something a bit like this. 615 00:31:05,950 --> 00:31:11,953 Input and the type should be, in this case, let's just stick to type text, 616 00:31:11,953 --> 00:31:13,620 assuming the user can type in some text. 617 00:31:13,620 --> 00:31:18,660 We could also, if we wanted to, make this a number. 618 00:31:18,660 --> 00:31:21,590 But let's stick to text for now. 619 00:31:21,590 --> 00:31:25,640 And down below, we might also have a button to submit this. 620 00:31:25,640 --> 00:31:30,020 I'll say button, and the type of this button is a submit button. 621 00:31:30,020 --> 00:31:33,230 And then on the inside I can say whatever I want the button to say. 622 00:31:33,230 --> 00:31:36,980 I could say submit or I could say Go to Page. 623 00:31:36,980 --> 00:31:42,855 And now if I refresh my page, I should see my very own form up above. 624 00:31:42,855 --> 00:31:43,730 And let's just check. 625 00:31:43,730 --> 00:31:48,280 I Can change this to maybe number, here. 626 00:31:48,280 --> 00:31:48,790 Refresh. 627 00:31:48,790 --> 00:31:52,522 And now I can actually have these up and down arrows for the page number. 628 00:31:52,522 --> 00:31:54,730 Here, though, we'll actually just stick to text, just 629 00:31:54,730 --> 00:31:59,240 to keep things a little more simple here. 630 00:31:59,240 --> 00:32:03,830 And now what am I still missing from this form? 631 00:32:03,830 --> 00:32:08,130 We have our input and our button. 632 00:32:08,130 --> 00:32:10,500 What have I maybe missed out on? 633 00:32:10,500 --> 00:32:11,350 The action. 634 00:32:11,350 --> 00:32:14,670 So I'll say action equals slash, because I want 635 00:32:14,670 --> 00:32:17,160 to send this data to the slash root. 636 00:32:17,160 --> 00:32:20,435 And the method in this case will actually be Post. 637 00:32:20,435 --> 00:32:21,810 I want to use a different method. 638 00:32:21,810 --> 00:32:25,860 And notice how in HTML, actually these methods are lowercase 639 00:32:25,860 --> 00:32:32,370 instead of Get capital or Post capital, we use post lowercase or get lowercase. 640 00:32:32,370 --> 00:32:33,760 OK. 641 00:32:33,760 --> 00:32:38,600 So now with this form, I can go over here, refresh the page. 642 00:32:38,600 --> 00:32:39,880 And I'll go to maybe page 10. 643 00:32:39,880 --> 00:32:41,010 I'll hit 10 here. 644 00:32:41,010 --> 00:32:42,340 I'll say, go to page. 645 00:32:42,340 --> 00:32:44,420 But I get method not allowed. 646 00:32:44,420 --> 00:32:47,000 So what have I also not done yet? 647 00:32:47,000 --> 00:32:50,190 I've made my form, it submits via post. 648 00:32:50,190 --> 00:32:53,800 But what have I not done yet in my Python? 649 00:32:53,800 --> 00:33:03,330 650 00:33:03,330 --> 00:33:03,830 Yeah. 651 00:33:03,830 --> 00:33:06,380 So I need to add this POST method here. 652 00:33:06,380 --> 00:33:12,680 I need to say that in the list of supported methods, POST is one of them. 653 00:33:12,680 --> 00:33:15,500 And now if I want to do something different when the user 654 00:33:15,500 --> 00:33:18,270 requests via POST, I could do this. 655 00:33:18,270 --> 00:33:24,020 I could say, if request.method is POST or equals POST, 656 00:33:24,020 --> 00:33:27,530 do whatever is inside of here. 657 00:33:27,530 --> 00:33:31,040 I'll leave it unimplemented for now, but there's presumably something 658 00:33:31,040 --> 00:33:33,600 that we might do inside of this. 659 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, 660 00:33:38,870 --> 00:33:39,890 and 10 again. 661 00:33:39,890 --> 00:33:42,740 And it seems to work for me. 662 00:33:42,740 --> 00:33:46,760 But what we haven't really yet done is actually gotten the data 663 00:33:46,760 --> 00:33:49,130 from the user in our Python code. 664 00:33:49,130 --> 00:33:51,720 So presumably, the user is submitting via POST. 665 00:33:51,720 --> 00:33:58,700 And we could confirm this by saying submitted via POST, printing that out. 666 00:33:58,700 --> 00:34:00,440 I'll open up my terminal. 667 00:34:00,440 --> 00:34:03,540 I'll go over here, submit my form. 668 00:34:03,540 --> 00:34:07,080 And I do see submitted via POST, so that seems to work. 669 00:34:07,080 --> 00:34:11,760 But what we haven't done has actually gotten the data from the form itself. 670 00:34:11,760 --> 00:34:13,400 So how could we do that? 671 00:34:13,400 --> 00:34:16,070 If we go back to our slides here, we might 672 00:34:16,070 --> 00:34:20,900 see that we could actually use this correspondence between our HTML 673 00:34:20,900 --> 00:34:24,000 and our Python code to get the values we want to get. 674 00:34:24,000 --> 00:34:28,520 So notice how in addition to a type, which is now omitted up here 675 00:34:28,520 --> 00:34:32,480 by default. But now we have the name attribute of our input. 676 00:34:32,480 --> 00:34:34,190 And this one is called page. 677 00:34:34,190 --> 00:34:37,790 We could reference that very same name in our Python code 678 00:34:37,790 --> 00:34:41,600 to then get the value that that input holds 679 00:34:41,600 --> 00:34:43,739 at the time the form is submitted. 680 00:34:43,739 --> 00:34:48,620 So I could use request.form.get, and then say page to get access 681 00:34:48,620 --> 00:34:51,139 to the value of that name-- 682 00:34:51,139 --> 00:34:54,469 or that input called name in my HTML. 683 00:34:54,469 --> 00:34:58,970 If I submitted via GET instead of POST, I could use request.args.get. 684 00:34:58,970 --> 00:35:07,080 So again, POST is request.form.get, get is request.args.get. 685 00:35:07,080 --> 00:35:08,650 So let's try this out. 686 00:35:08,650 --> 00:35:10,290 Let's go ahead and go back to our HTML. 687 00:35:10,290 --> 00:35:17,010 And let's actually add a name to our input. 688 00:35:17,010 --> 00:35:19,290 This one I'll call-- 689 00:35:19,290 --> 00:35:21,600 this one I'll call page. 690 00:35:21,600 --> 00:35:28,980 And now how should I get that value inside of my Python code now? 691 00:35:28,980 --> 00:35:34,525 I have this input named page, but how should I get it in my Python code? 692 00:35:34,525 --> 00:35:42,490 693 00:35:42,490 --> 00:35:46,510 I can use something like the GET function. 694 00:35:46,510 --> 00:35:49,810 But more specifically, what kind of line should I write? 695 00:35:49,810 --> 00:35:55,990 696 00:35:55,990 --> 00:35:58,540 So because I'm submitting via POST, what I should really 697 00:35:58,540 --> 00:36:04,365 do to get access to this data is I could do request.form.get. 698 00:36:04,365 --> 00:36:08,770 So from this request, from the form that was submitted, 699 00:36:08,770 --> 00:36:13,060 get me the value of the input named page. 700 00:36:13,060 --> 00:36:16,750 And why don't I store this inside some variable called page? 701 00:36:16,750 --> 00:36:19,770 Let me scroll this to the right. 702 00:36:19,770 --> 00:36:24,150 And for good measure, I'll print page to be sure I have access to it. 703 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. 704 00:36:29,760 --> 00:36:32,520 Now I'll look in my terminal, and I do actually 705 00:36:32,520 --> 00:36:35,370 see I have that page number being printed out 706 00:36:35,370 --> 00:36:39,670 because I told Flask to do so on line 17. 707 00:36:39,670 --> 00:36:43,050 I could even make it maybe page 50-- go to page. 708 00:36:43,050 --> 00:36:46,030 And now I see page 50 down below here. 709 00:36:46,030 --> 00:36:52,250 So I've gotten whatever text is inside of my input named page. 710 00:36:52,250 --> 00:36:55,910 And this seems to work for now. 711 00:36:55,910 --> 00:37:00,800 But what if we wanted to update this in some way to actually have some effect? 712 00:37:00,800 --> 00:37:03,277 Well, it doesn't quite matter for the problems 713 00:37:03,277 --> 00:37:06,360 that this week or anything else really beyond this particular application. 714 00:37:06,360 --> 00:37:15,200 But if I wanted to have every page number be set by whatever-- 715 00:37:15,200 --> 00:37:17,880 if I wanted every random string be set by the page number, 716 00:37:17,880 --> 00:37:21,050 I could call this function called random.seed. 717 00:37:21,050 --> 00:37:25,680 And I've gotten the seed function, again, from the random library here. 718 00:37:25,680 --> 00:37:29,930 And if I say random.seed page, well, later 719 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, 720 00:37:36,470 --> 00:37:39,402 I'll get that same random string every time, 721 00:37:39,402 --> 00:37:41,360 giving me the illusion of having different page 722 00:37:41,360 --> 00:37:43,420 numbers in my application. 723 00:37:43,420 --> 00:37:48,620 So for example, I can go to my application over here, hit Refresh. 724 00:37:48,620 --> 00:37:50,920 I could say page 10. 725 00:37:50,920 --> 00:37:53,830 And I do see some random string of text over here. 726 00:37:53,830 --> 00:37:58,840 I'll go to page 10 again and I get that same random string. 727 00:37:58,840 --> 00:38:02,800 I go to page 11 and I get some new random string. 728 00:38:02,800 --> 00:38:06,100 Go to page 11 again, and I get that same random string. 729 00:38:06,100 --> 00:38:11,110 So random seed is a way of specifying how the randomness should work. 730 00:38:11,110 --> 00:38:13,000 As long as I pass in that same number-- 731 00:38:13,000 --> 00:38:17,770 10, 11, 20 or so on, I then get that same random string 732 00:38:17,770 --> 00:38:21,350 later on when I use the random functions here. 733 00:38:21,350 --> 00:38:25,050 If I don't use POST, though, if I don't run this piece of code, 734 00:38:25,050 --> 00:38:27,590 well, what I'll do is just get a truly random string 735 00:38:27,590 --> 00:38:29,780 based on some random seed. 736 00:38:29,780 --> 00:38:35,600 But beforehand, I could set some seed to account to based on the page to say, 737 00:38:35,600 --> 00:38:38,030 that if I ask for certain page number, I'll always 738 00:38:38,030 --> 00:38:42,020 get back the same string in the end. 739 00:38:42,020 --> 00:38:43,430 OK. 740 00:38:43,430 --> 00:38:46,290 But what might go wrong with this? 741 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. 742 00:38:51,442 --> 00:38:53,150 If we're talking about page numbers, what 743 00:38:53,150 --> 00:38:54,845 are some bad inputs you could give? 744 00:38:54,845 --> 00:38:59,390 745 00:38:59,390 --> 00:39:01,580 Negative nine, letters. 746 00:39:01,580 --> 00:39:05,210 So if I do this, I say, negative nine. 747 00:39:05,210 --> 00:39:06,420 Well, it still seems to work. 748 00:39:06,420 --> 00:39:07,820 But I don't really want it to. 749 00:39:07,820 --> 00:39:13,460 Or if I typed a, a, a, well, that also worked, but not quite the way 750 00:39:13,460 --> 00:39:15,080 I want it to. 751 00:39:15,080 --> 00:39:16,680 And so how could we do this? 752 00:39:16,680 --> 00:39:18,770 I could actually go back to my code space here 753 00:39:18,770 --> 00:39:21,480 and I could try to update this in some way. 754 00:39:21,480 --> 00:39:26,060 So ideally, I want to validate the user input as I get it. 755 00:39:26,060 --> 00:39:28,640 And maybe I have page here. 756 00:39:28,640 --> 00:39:31,670 But I could ask the question, before I do anything with page, 757 00:39:31,670 --> 00:39:34,820 is page less than zero? 758 00:39:34,820 --> 00:39:40,210 And if it is, why don't we return the render template. 759 00:39:40,210 --> 00:39:46,840 Return index HTML now rendered, but at this point just say some error message 760 00:39:46,840 --> 00:39:50,680 like, type in a positive number. 761 00:39:50,680 --> 00:39:53,260 762 00:39:53,260 --> 00:39:56,160 So now my placeholder called random string will actually just 763 00:39:56,160 --> 00:39:58,720 be this error message, type in a positive number. 764 00:39:58,720 --> 00:40:03,270 So now I'll go back over here and I'll do refresh the page. 765 00:40:03,270 --> 00:40:08,070 And I'll type, let's say, negative 10, go to page. 766 00:40:08,070 --> 00:40:10,930 Oh, but I got an internal server error. 767 00:40:10,930 --> 00:40:16,360 And if I look at my terminal, I should see type error less than not supported 768 00:40:16,360 --> 00:40:21,100 between instances of str and int down below. 769 00:40:21,100 --> 00:40:24,540 So what went wrong do you think? 770 00:40:24,540 --> 00:40:31,950 If we look at this code on the left hand side. 771 00:40:31,950 --> 00:40:35,040 What went wrong? 772 00:40:35,040 --> 00:40:40,410 Yeah, we forgot to put page inside of a-- we 773 00:40:40,410 --> 00:40:43,452 forget to convert page to be an integer. 774 00:40:43,452 --> 00:40:44,410 So I forgot to do this. 775 00:40:44,410 --> 00:40:49,670 I forgot to say that if we can, let's make sure we turn page 776 00:40:49,670 --> 00:40:52,290 from a string to an integer. 777 00:40:52,290 --> 00:40:56,270 So whenever you use request.form.get or request.args.get, 778 00:40:56,270 --> 00:40:58,250 whether you're working with numbers or not, 779 00:40:58,250 --> 00:41:01,670 you'll always get your input back as a string, and it's up to you 780 00:41:01,670 --> 00:41:05,130 to convert it to an integer if you want it to be an integer. 781 00:41:05,130 --> 00:41:07,160 So here I'll convert page to an integer. 782 00:41:07,160 --> 00:41:08,990 And now I'll try running this. 783 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, 784 00:41:13,490 --> 00:41:14,780 and I'll say negative 10. 785 00:41:14,780 --> 00:41:15,980 I'll go to page. 786 00:41:15,980 --> 00:41:18,890 And now I do see, type in a positive number, which is really good. 787 00:41:18,890 --> 00:41:22,520 I'll do -500, and I see the same thing. 788 00:41:22,520 --> 00:41:26,450 But what is the other kind of input we could give to this form that 789 00:41:26,450 --> 00:41:32,253 might make it go wrong? 790 00:41:32,253 --> 00:41:33,420 We've seen negative numbers. 791 00:41:33,420 --> 00:41:35,460 What else? 792 00:41:35,460 --> 00:41:36,550 We can give some text. 793 00:41:36,550 --> 00:41:41,810 We'd say, ABC, go to page, and we get another internal server error. 794 00:41:41,810 --> 00:41:43,730 So something's gone wrong again. 795 00:41:43,730 --> 00:41:48,160 And if we look down in our terminal, we see a value error-- 796 00:41:48,160 --> 00:41:52,570 invalid literal for int with base 10 ABC. 797 00:41:52,570 --> 00:41:55,510 And this basically means that I can't convert 798 00:41:55,510 --> 00:41:58,433 the string, ABC, to be an integer. 799 00:41:58,433 --> 00:42:00,100 What does it mean for ABC to be integer? 800 00:42:00,100 --> 00:42:01,090 We don't really know. 801 00:42:01,090 --> 00:42:07,330 So what I should probably do here is use Python's try and accept syntax 802 00:42:07,330 --> 00:42:10,247 where in Python, often it's good to simply try something 803 00:42:10,247 --> 00:42:11,080 that you want to do. 804 00:42:11,080 --> 00:42:15,040 Like try to, in this case, convert page to an integer. 805 00:42:15,040 --> 00:42:20,690 And except, maybe except if I do see that value error, 806 00:42:20,690 --> 00:42:25,560 let me go ahead and actually tell the user another error. 807 00:42:25,560 --> 00:42:30,380 And this time I'll tell them, just enter a number in general. 808 00:42:30,380 --> 00:42:34,720 So again, we'll get the page number from our form. 809 00:42:34,720 --> 00:42:39,020 We'll then try to convert page into an integer. 810 00:42:39,020 --> 00:42:42,670 And if we get that error, we can't convert some text to an integer, what 811 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. 812 00:42:48,260 --> 00:42:51,670 And then finally, as one final check, we'll also ask the question, 813 00:42:51,670 --> 00:42:53,530 is page less than zero? 814 00:42:53,530 --> 00:42:57,440 And if it is, we'll tell them to type in a positive number overall. 815 00:42:57,440 --> 00:43:01,730 So this kind of accesses all the possible combinations of errors here. 816 00:43:01,730 --> 00:43:04,210 So go back up to our website. 817 00:43:04,210 --> 00:43:05,560 Go to slash. 818 00:43:05,560 --> 00:43:08,020 I'll type, in this case, ABC. 819 00:43:08,020 --> 00:43:08,920 Go to page. 820 00:43:08,920 --> 00:43:11,158 And I see enter a number, which is good. 821 00:43:11,158 --> 00:43:12,700 And then I'll type maybe negative 10. 822 00:43:12,700 --> 00:43:14,380 I'll see enter a positive number. 823 00:43:14,380 --> 00:43:17,260 And now if I type page 10, well, I seem to get 824 00:43:17,260 --> 00:43:20,060 the thing I wanted in the first place. 825 00:43:20,060 --> 00:43:24,520 So questions on this and how we implemented some of this 826 00:43:24,520 --> 00:43:28,060 getting of data from the form, but also validating user input, 827 00:43:28,060 --> 00:43:31,100 as you might want to do during this week's problem set? 828 00:43:31,100 --> 00:43:46,350 829 00:43:46,350 --> 00:43:49,685 OK, seeing-- I'll wait just one minute or so. 830 00:43:49,685 --> 00:43:55,450 831 00:43:55,450 --> 00:43:57,150 All right. 832 00:43:57,150 --> 00:44:00,192 What happens, though, actually-- 833 00:44:00,192 --> 00:44:02,400 maybe there's one more thing we should take care of-- 834 00:44:02,400 --> 00:44:04,690 if I do this. 835 00:44:04,690 --> 00:44:09,830 I could go back over here, put in nothing, and type go to page. 836 00:44:09,830 --> 00:44:13,490 I see enter number, it actually works OK. 837 00:44:13,490 --> 00:44:14,960 But we could also-- 838 00:44:14,960 --> 00:44:17,660 well, no, I think we're OK here. 839 00:44:17,660 --> 00:44:19,970 Let me know if you find other errors, though. 840 00:44:19,970 --> 00:44:20,883 Symbols, I saw. 841 00:44:20,883 --> 00:44:21,800 OK, let's try symbols. 842 00:44:21,800 --> 00:44:24,750 I'll type at exclamation point. 843 00:44:24,750 --> 00:44:27,070 Seems to work. 844 00:44:27,070 --> 00:44:31,120 So that seems OK here. 845 00:44:31,120 --> 00:44:33,400 And particularly for this week's problems set. 846 00:44:33,400 --> 00:44:36,190 We will be getting numbers and text from the user, 847 00:44:36,190 --> 00:44:38,980 it's often good to really try to validate the input 848 00:44:38,980 --> 00:44:41,410 to make sure that they're not being adversarial to you. 849 00:44:41,410 --> 00:44:44,693 They're not trying to give you some text and mess up your program. 850 00:44:44,693 --> 00:44:47,110 And you're instead making sure that before you do anything 851 00:44:47,110 --> 00:44:50,560 with their input, you're making sure it is exactly as you expect. 852 00:44:50,560 --> 00:44:55,040 And if it's not, maybe giving them some kind of error as we did here. 853 00:44:55,040 --> 00:44:56,770 So let's keep going now. 854 00:44:56,770 --> 00:45:00,100 And one of our final to-do's was to not just 855 00:45:00,100 --> 00:45:03,280 have the user send some input to our database, 856 00:45:03,280 --> 00:45:06,610 but also to have some search history down below. 857 00:45:06,610 --> 00:45:10,570 And ideally, if I search for page 10, well, I 858 00:45:10,570 --> 00:45:12,790 should see that search show up at the bottom 859 00:45:12,790 --> 00:45:15,760 of my page in this table down below. 860 00:45:15,760 --> 00:45:16,970 And that's not there yet. 861 00:45:16,970 --> 00:45:20,680 But to do this, we'll probably need to use some of our SQL 862 00:45:20,680 --> 00:45:22,100 that we learned from a prior week. 863 00:45:22,100 --> 00:45:24,260 And so let's take a look at how we could use that. 864 00:45:24,260 --> 00:45:29,950 So if we think about databases in our program, they're going to store data, 865 00:45:29,950 --> 00:45:32,210 long-term for our application. 866 00:45:32,210 --> 00:45:34,480 And if we want it to store like a search history, 867 00:45:34,480 --> 00:45:37,690 it's a great use case for that, because we can actually persistently 868 00:45:37,690 --> 00:45:40,400 store search history over time. 869 00:45:40,400 --> 00:45:43,370 So let's take a look at SQL and how we could do this. 870 00:45:43,370 --> 00:45:48,670 If we look at history.db, at the beginning of this session, 871 00:45:48,670 --> 00:45:50,200 I ran this function-- 872 00:45:50,200 --> 00:45:54,190 I ran this command called Create table history 873 00:45:54,190 --> 00:45:59,500 with this ID column and this page column, to give me this table of pages 874 00:45:59,500 --> 00:46:01,750 that I could insert into. 875 00:46:01,750 --> 00:46:05,810 And just to show you, if I go back to my code space, go over here. 876 00:46:05,810 --> 00:46:12,850 I could go to my new terminal, type ls, type SQLite3, 877 00:46:12,850 --> 00:46:15,770 history.db to open this up. 878 00:46:15,770 --> 00:46:21,220 And now if I full screen it and zoom in, if I type dot schema, 879 00:46:21,220 --> 00:46:25,270 I see I've ran that command and I have this table called history. 880 00:46:25,270 --> 00:46:30,710 I could even select everything from history, and I see nothing's there. 881 00:46:30,710 --> 00:46:36,710 So I have this kind of empty table in my database called history.db. 882 00:46:36,710 --> 00:46:41,850 So if I were to insert into this table, I could do the following. 883 00:46:41,850 --> 00:46:45,140 I can run this SQL command called INSERT INTO. 884 00:46:45,140 --> 00:46:47,360 And the way this works is we type the name 885 00:46:47,360 --> 00:46:50,600 of the table, so history, and the columns you want to insert into, 886 00:46:50,600 --> 00:46:52,070 so page in this case. 887 00:46:52,070 --> 00:46:56,750 So I'll insert page 50 into my table. 888 00:46:56,750 --> 00:47:00,710 Then I might say, OK, let's insert 100 into my table, 889 00:47:00,710 --> 00:47:05,120 and let's insert 43 into my table as I go through and make these queries. 890 00:47:05,120 --> 00:47:09,230 But right now, this is all happening in the SQLite terminal 891 00:47:09,230 --> 00:47:11,000 and not in my Python program. 892 00:47:11,000 --> 00:47:16,430 So how could I run Python or run SQL but in my Python code? 893 00:47:16,430 --> 00:47:18,720 Any ideas in the chat? 894 00:47:18,720 --> 00:47:20,770 What have we seen so far? 895 00:47:20,770 --> 00:47:25,140 How can I run these same SQL commands but not in the SQLite terminal, 896 00:47:25,140 --> 00:47:27,170 actually in my Python program now? 897 00:47:27,170 --> 00:47:29,540 898 00:47:29,540 --> 00:47:30,040 Yeah. 899 00:47:30,040 --> 00:47:31,780 I'm seeing db.execute. 900 00:47:31,780 --> 00:47:35,920 So I can type the very same command, but just inside of Python 901 00:47:35,920 --> 00:47:39,400 using this db.execute command. 902 00:47:39,400 --> 00:47:44,920 So db to execute is a way of trying to execute SQL commands inside 903 00:47:44,920 --> 00:47:47,410 of our application that connects to this database 904 00:47:47,410 --> 00:47:49,490 and actually runs them on that database. 905 00:47:49,490 --> 00:47:54,008 So here we can say insert in history the page 43. 906 00:47:54,008 --> 00:47:56,050 And one kind of handy thing here is we don't even 907 00:47:56,050 --> 00:47:57,760 need to know the page number originally. 908 00:47:57,760 --> 00:48:00,890 We could just say, insert some placeholder like this. 909 00:48:00,890 --> 00:48:04,810 I could say, make a question mark for some value I could insert later on 910 00:48:04,810 --> 00:48:08,390 and then say comma, the name of the variable I want to insert, 911 00:48:08,390 --> 00:48:09,320 in this case. 912 00:48:09,320 --> 00:48:11,420 So let's actually try this out. 913 00:48:11,420 --> 00:48:14,740 I'll go back to my code. 914 00:48:14,740 --> 00:48:17,060 And let me pull up-- 915 00:48:17,060 --> 00:48:25,653 pull up my-- actually, exit from this. 916 00:48:25,653 --> 00:48:26,570 No, I'll keep that up. 917 00:48:26,570 --> 00:48:27,980 Let me go back over here. 918 00:48:27,980 --> 00:48:33,120 I'll code-- oh, cd into library, and I'll code app.py. 919 00:48:33,120 --> 00:48:37,470 And now I see I'm kind of back in my view over here. 920 00:48:37,470 --> 00:48:42,420 I want to insert the page number every time I go to the slash root 921 00:48:42,420 --> 00:48:43,950 and submit the form. 922 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 923 00:48:49,170 --> 00:48:51,280 that the user has requested. 924 00:48:51,280 --> 00:48:55,870 So once I know that I have a valid page number right down in here-- 925 00:48:55,870 --> 00:48:57,130 let me zoom in a bit-- 926 00:48:57,130 --> 00:49:03,360 what could I run to insert this page number into my database? 927 00:49:03,360 --> 00:49:12,120 I know I can do insert into history into the pages column, some values. 928 00:49:12,120 --> 00:49:17,290 But what do I want to actually type here to run it inside of Python? 929 00:49:17,290 --> 00:49:19,450 This is not valid Python code yet. 930 00:49:19,450 --> 00:49:20,725 But how could I make it so? 931 00:49:20,725 --> 00:49:29,780 932 00:49:29,780 --> 00:49:31,350 Yeah, I can use db to execute. 933 00:49:31,350 --> 00:49:38,800 So I can say, db to execute and wrap this command with that function. 934 00:49:38,800 --> 00:49:41,650 And then to fill in this placeholder here, this question mark, 935 00:49:41,650 --> 00:49:47,840 I could go ahead and say, I want to put in page for that right here. 936 00:49:47,840 --> 00:49:50,380 So now if I look at this entire command, I'm 937 00:49:50,380 --> 00:49:56,090 saying, execute on my database, which I defined up here-- 938 00:49:56,090 --> 00:49:59,870 history.db, using SQLite. 939 00:49:59,870 --> 00:50:01,940 Execute on that database this command. 940 00:50:01,940 --> 00:50:06,733 Insert into history, in the pages column, this value here. 941 00:50:06,733 --> 00:50:07,650 And what is the value? 942 00:50:07,650 --> 00:50:08,910 What's the value for page? 943 00:50:08,910 --> 00:50:11,710 And we know, page is a page number the user has submitted. 944 00:50:11,710 --> 00:50:16,170 So let me go back to my application, refresh the page. 945 00:50:16,170 --> 00:50:17,880 This time, I will type page 10. 946 00:50:17,880 --> 00:50:19,480 I'll go to page. 947 00:50:19,480 --> 00:50:21,630 And if I scroll down, well, I don't see anything. 948 00:50:21,630 --> 00:50:23,250 And that's because my HTML-- 949 00:50:23,250 --> 00:50:25,710 I haven't actually rendered this. 950 00:50:25,710 --> 00:50:28,800 Like I just see search history but really nothing else over here. 951 00:50:28,800 --> 00:50:34,590 But if I go to my SQLite connection, My SQLite terminal here 952 00:50:34,590 --> 00:50:39,720 and I type select star from history, what 953 00:50:39,720 --> 00:50:42,180 do you think I'll see in this case? 954 00:50:42,180 --> 00:50:43,770 Feel free to type in the chat. 955 00:50:43,770 --> 00:50:47,310 What do you think I'll see when I type select star from history now? 956 00:50:47,310 --> 00:50:52,530 957 00:50:52,530 --> 00:50:54,070 I'll see everything in the database. 958 00:50:54,070 --> 00:50:59,160 And because I submitted this form with the page number 10, 959 00:50:59,160 --> 00:51:00,660 I should see 10 somewhere. 960 00:51:00,660 --> 00:51:01,800 And I do see it. 961 00:51:01,800 --> 00:51:04,720 I see this has an ID and the page is 10. 962 00:51:04,720 --> 00:51:06,720 And now I can go back and submit the form again. 963 00:51:06,720 --> 00:51:08,680 I could go back over here. 964 00:51:08,680 --> 00:51:10,740 Let me search for page 50 now. 965 00:51:10,740 --> 00:51:13,960 I'll go to that page and then I'll go over here. 966 00:51:13,960 --> 00:51:16,440 I'll select everything from history and now I 967 00:51:16,440 --> 00:51:20,160 see both page 10 and page 50 in my history. 968 00:51:20,160 --> 00:51:24,420 So I'm adding to my table, not by being in this terminal down here, 969 00:51:24,420 --> 00:51:31,370 but through my own Python code that I wrote up above, right in here. 970 00:51:31,370 --> 00:51:31,870 OK. 971 00:51:31,870 --> 00:51:34,672 So questions on this so far? 972 00:51:34,672 --> 00:51:36,130 How we're inserting into our table? 973 00:51:36,130 --> 00:51:39,325 974 00:51:39,325 --> 00:51:41,950 I see a question-- how do we see the search history in our HTML 975 00:51:41,950 --> 00:51:43,450 which we'll get to in just a second. 976 00:51:43,450 --> 00:51:48,320 But questions on inserting or this db to execute for now? 977 00:51:48,320 --> 00:51:58,430 978 00:51:58,430 --> 00:51:58,930 All right. 979 00:51:58,930 --> 00:51:59,972 So let's keep going then. 980 00:51:59,972 --> 00:52:04,890 And our last step is really to try to show this search history in our HTML. 981 00:52:04,890 --> 00:52:08,940 And we'll need a bit more advanced syntax, at least 982 00:52:08,940 --> 00:52:11,260 with Jinja on the right hand side here. 983 00:52:11,260 --> 00:52:14,730 But for now, let's figure out, how could I get access to the data 984 00:52:14,730 --> 00:52:18,120 from my database inside of Python, and then 985 00:52:18,120 --> 00:52:20,588 use Python to pass that data into my HTML? 986 00:52:20,588 --> 00:52:22,380 So we're going a few different places here. 987 00:52:22,380 --> 00:52:27,540 We're asking our database, what rows do you have, putting those in Python, 988 00:52:27,540 --> 00:52:32,230 and then telling Python to send that data to our HTML page. 989 00:52:32,230 --> 00:52:35,650 So maybe down here when I visit this page, 990 00:52:35,650 --> 00:52:40,540 let's say I've finished making a request, either via POST or GET. 991 00:52:40,540 --> 00:52:42,820 And now I've generated a string. 992 00:52:42,820 --> 00:52:46,870 But I also want to figure out, what is inside of my database? 993 00:52:46,870 --> 00:52:49,540 Well, I could do db.execute. 994 00:52:49,540 --> 00:52:53,455 And as we saw before, how could I get everything from my history table? 995 00:52:53,455 --> 00:52:57,580 996 00:52:57,580 --> 00:52:59,395 What kind of SQL command could I use? 997 00:52:59,395 --> 00:53:02,380 998 00:53:02,380 --> 00:53:03,120 Yeah, star. 999 00:53:03,120 --> 00:53:06,830 Select star from history, right? 1000 00:53:06,830 --> 00:53:10,400 And let me actually add the semi-colon up here, just to be sure. 1001 00:53:10,400 --> 00:53:14,650 And now that I've done this, well, I selected everything, 1002 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. 1003 00:53:18,900 --> 00:53:23,670 And it happens to be that db to execute returns to you 1004 00:53:23,670 --> 00:53:27,550 a list of all the rows as dictionaries. 1005 00:53:27,550 --> 00:53:32,190 So for example, I could say rows equals db.execute. 1006 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 1007 00:53:38,490 --> 00:53:40,710 names as its attributes or its keys. 1008 00:53:40,710 --> 00:53:41,850 So just to show you-- 1009 00:53:41,850 --> 00:53:44,520 I could print rows down here, just to my terminal. 1010 00:53:44,520 --> 00:53:47,430 And now I'll go to Library of Babel. 1011 00:53:47,430 --> 00:53:48,780 I'll hit slash now. 1012 00:53:48,780 --> 00:53:50,910 I still don't see anything in my search history 1013 00:53:50,910 --> 00:53:52,952 down below, because I haven't made that part yet. 1014 00:53:52,952 --> 00:53:56,640 But if I go to my terminal, open that up. 1015 00:53:56,640 --> 00:53:58,710 Let me go back over here to my server. 1016 00:53:58,710 --> 00:54:02,160 I see that I ran this command, select star from history, 1017 00:54:02,160 --> 00:54:06,480 and it gave me this list of dictionaries. 1018 00:54:06,480 --> 00:54:11,060 So see, I have one dictionary that has ID and page as keys. 1019 00:54:11,060 --> 00:54:14,090 And the ID is one, the page is 10. 1020 00:54:14,090 --> 00:54:18,380 I have this next dictionary where the ID is two and the page is 50. 1021 00:54:18,380 --> 00:54:20,480 That's another row in my table. 1022 00:54:20,480 --> 00:54:25,080 And together, this is an entire list-- a list of rows. 1023 00:54:25,080 --> 00:54:27,400 So what could I do with this? 1024 00:54:27,400 --> 00:54:29,560 How could I render this in my HTML? 1025 00:54:29,560 --> 00:54:32,790 Well, as we saw maybe a little bit briefly in lecture, 1026 00:54:32,790 --> 00:54:37,840 I could try to pass in this variable-- rows-- 1027 00:54:37,840 --> 00:54:40,910 to my HTML, and render it there. 1028 00:54:40,910 --> 00:54:47,800 So I could say, maybe I have this placeholder called history in my HTML. 1029 00:54:47,800 --> 00:54:53,350 And I'll make sure that that placeholder is filled with the values of rows. 1030 00:54:53,350 --> 00:54:56,200 And let me go over here to my index.html. 1031 00:54:56,200 --> 00:54:58,820 Now, open this part up. 1032 00:54:58,820 --> 00:55:03,740 And maybe in my table body, well, I could just place history like this. 1033 00:55:03,740 --> 00:55:05,810 I'll make this placeholder for history and I'll 1034 00:55:05,810 --> 00:55:09,930 put the value of rows right in there in my table. 1035 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. 1036 00:55:15,170 --> 00:55:18,950 And well I don't quite see what I expected. 1037 00:55:18,950 --> 00:55:22,950 This is not an ideal format. 1038 00:55:22,950 --> 00:55:29,520 I've kind of literally interpolated or copy pasted the value of rows 1039 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. 1040 00:55:34,050 --> 00:55:35,580 So there's a better way to do this. 1041 00:55:35,580 --> 00:55:41,280 And actually, in Jinja, instead of just pasting an entire variable, 1042 00:55:41,280 --> 00:55:46,080 we could iterate over a variable but in our HTML. 1043 00:55:46,080 --> 00:55:50,370 And now Jinja has the special syntax we can use to use for loops, 1044 00:55:50,370 --> 00:55:51,947 so what we have in Python. 1045 00:55:51,947 --> 00:55:52,780 So I could say this. 1046 00:55:52,780 --> 00:55:58,890 I could say percent-- or brace percent and then closing brace-- 1047 00:55:58,890 --> 00:56:00,510 closing percent and then brace. 1048 00:56:00,510 --> 00:56:06,790 Let's say for maybe row in history. 1049 00:56:06,790 --> 00:56:09,230 And then end for down here. 1050 00:56:09,230 --> 00:56:12,880 So now I've made this for loop in my HTML 1051 00:56:12,880 --> 00:56:16,240 where history is the list I'm iterating over 1052 00:56:16,240 --> 00:56:20,800 and row is what I want to call everything-- 1053 00:56:20,800 --> 00:56:25,500 every individual thing I'm iterating over on a given iteration. 1054 00:56:25,500 --> 00:56:29,720 So now I can say, I want to, inside of this table, 1055 00:56:29,720 --> 00:56:35,720 make myself a new table row for every row that I have in history. 1056 00:56:35,720 --> 00:56:39,230 And then inside that table row, I want to have some data. 1057 00:56:39,230 --> 00:56:44,920 Again, this tr is our table row tag and this td is our table data tag. 1058 00:56:44,920 --> 00:56:46,400 And now what should go inside here? 1059 00:56:46,400 --> 00:56:52,940 Well, maybe I could actually have this placeholder that is equivalent to row 1060 00:56:52,940 --> 00:56:58,780 and I could borrow some Python syntax here, row bracket page. 1061 00:56:58,780 --> 00:57:01,950 So what do you think we'll see in this case? 1062 00:57:01,950 --> 00:57:03,795 Any ideas in the chat if we do this? 1063 00:57:03,795 --> 00:57:08,000 1064 00:57:08,000 --> 00:57:13,580 We're iterating over our history list, a list of rows from our table. 1065 00:57:13,580 --> 00:57:18,420 We're going to call every iteration, row. 1066 00:57:18,420 --> 00:57:22,430 And then we'll say, row, get me the key-- 1067 00:57:22,430 --> 00:57:25,910 give me the value corresponding to the key called page. 1068 00:57:25,910 --> 00:57:30,610 So again, here is our entire list, down below here. 1069 00:57:30,610 --> 00:57:35,330 On the first iteration, this will be row, and we'll get the page value-- 1070 00:57:35,330 --> 00:57:36,370 so 10. 1071 00:57:36,370 --> 00:57:39,700 On the next iteration, this will be row, and then we'll 1072 00:57:39,700 --> 00:57:43,300 get the page value, or 50. 1073 00:57:43,300 --> 00:57:45,520 So let's refresh the page and see what happens now. 1074 00:57:45,520 --> 00:57:46,750 I'll go over here-- 1075 00:57:46,750 --> 00:57:47,410 oops. 1076 00:57:47,410 --> 00:57:47,920 Here. 1077 00:57:47,920 --> 00:57:48,420 Slash. 1078 00:57:48,420 --> 00:57:54,560 And now, I do see my search history, kind of as I intended it to be. 1079 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, 1080 00:57:59,860 --> 00:58:03,490 scroll down, and I see that added to my history. 1081 00:58:03,490 --> 00:58:05,710 I could go to 100 again. 1082 00:58:05,710 --> 00:58:08,100 I see that same random string like we saw before, 1083 00:58:08,100 --> 00:58:12,330 and now I can see my search history down below. 1084 00:58:12,330 --> 00:58:16,050 So all of this, this kind of syntax here, 1085 00:58:16,050 --> 00:58:20,760 is just a way to print our list of dictionaries 1086 00:58:20,760 --> 00:58:23,520 a little more prettily, a little more in line 1087 00:58:23,520 --> 00:58:25,725 with what we expect to see in our HTML. 1088 00:58:25,725 --> 00:58:29,070 1089 00:58:29,070 --> 00:58:30,180 OK. 1090 00:58:30,180 --> 00:58:32,000 So what questions are there on this? 1091 00:58:32,000 --> 00:58:36,450 On how we passed in some list of dictionaries to our code 1092 00:58:36,450 --> 00:58:39,240 and iterated over it to make a table here? 1093 00:58:39,240 --> 00:58:58,740 1094 00:58:58,740 --> 00:58:59,610 Same question. 1095 00:58:59,610 --> 00:59:04,350 Showing the back end to the front end is not insecure, how do we hide that? 1096 00:59:04,350 --> 00:59:08,537 So the key thing to remember here is that this app.py 1097 00:59:08,537 --> 00:59:11,370 is kind of like what we call our back end-- something the user never 1098 00:59:11,370 --> 00:59:12,600 really sees. 1099 00:59:12,600 --> 00:59:17,040 And even our HTML page over here is somewhat back end, in the sense 1100 00:59:17,040 --> 00:59:20,443 that if I were to render this-- 1101 00:59:20,443 --> 00:59:21,360 let me look over here. 1102 00:59:21,360 --> 00:59:25,690 If I were to render template, index.html, 1103 00:59:25,690 --> 00:59:30,570 well, I would actually see not this code for row and history 1104 00:59:30,570 --> 00:59:36,720 and for row, bracket, page, I'd actually generate this HTML file 1105 00:59:36,720 --> 00:59:38,290 and then show it to the user. 1106 00:59:38,290 --> 00:59:43,330 And so if I go to my HTML file over here and scroll down, 1107 00:59:43,330 --> 00:59:47,010 notice how I don't actually see any of the Jinja syntax, 1108 00:59:47,010 --> 00:59:50,110 I just see the resulting pieces of it here. 1109 00:59:50,110 --> 00:59:54,760 So I don't see for or the dictionary or anything like that. 1110 00:59:54,760 --> 00:59:57,040 I just see the result of it here. 1111 00:59:57,040 --> 00:59:59,820 And so that is secure enough for us, as we're 1112 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 1113 01:00:04,150 --> 01:00:04,650 here. 1114 01:00:04,650 --> 01:00:07,853 1115 01:00:07,853 --> 01:00:09,520 Question-- how do we get the key values? 1116 01:00:09,520 --> 01:00:13,680 So notice in our HTML. 1117 01:00:13,680 --> 01:00:18,120 We said row with the key of page, but how do we know it was page? 1118 01:00:18,120 --> 01:00:24,160 Well, if I go to my SQL prompt over here, select star from history 1119 01:00:24,160 --> 01:00:25,030 as you did before. 1120 01:00:25,030 --> 01:00:27,550 I have this row called page. 1121 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 1122 01:00:31,210 --> 01:00:33,580 on a row, a column called page here. 1123 01:00:33,580 --> 01:00:37,900 1124 01:00:37,900 --> 01:00:39,460 OK. 1125 01:00:39,460 --> 01:00:40,435 Other questions here? 1126 01:00:40,435 --> 01:00:44,315 1127 01:00:44,315 --> 01:00:46,190 While we're waiting for questions to come in, 1128 01:00:46,190 --> 01:00:49,610 this week will be a lot of doing exactly what we did today, 1129 01:00:49,610 --> 01:00:53,450 of trying to insert some data from Python into HTML, 1130 01:00:53,450 --> 01:00:56,090 trying to render dictionaries, lists of dictionaries 1131 01:00:56,090 --> 01:00:58,370 and so on, and even using some of our helper functions 1132 01:00:58,370 --> 01:01:00,053 that we saw before here. 1133 01:01:00,053 --> 01:01:02,720 I hope you go off and work on this problem set with some of what 1134 01:01:02,720 --> 01:01:04,245 you learned during this section. 1135 01:01:04,245 --> 01:01:06,245 We'll probably officially conclude here, but I'm 1136 01:01:06,245 --> 01:01:09,270 happy to be around to answer any questions that you all have. 1137 01:01:09,270 --> 01:01:13,120 Thank you very much for coming and I hope to see you next time. 1138 01:01:13,120 --> 01:01:16,000