Placeholder Image

字幕列表 影片播放

  • COLTON OGDEN: All right.

  • Hello, world.

  • This is CS50 on Twitch.

  • My name is Colton Ogden.

  • I'm joined today by--

  • KAREEM ZIDANE: Kareem Zidane.

  • COLTON OGDEN: So apologies if you've been watching in the live chat.

  • It took us a little bit to get online.

  • We're having some difficulties with a brand new setup.

  • But it looks so far to my eye that everything is currently Livestreaming

  • and looks excellent.

  • Let me go ahead and make sure I'm muting everything here on my laptop

  • that the audio is coming from.

  • So what are you here to talk with us about?

  • You're a regular.

  • You've been in a couple of times.

  • We did like a Travis stream.

  • We did some other stuff.

  • KAREEM ZIDANE: Yup.

  • I think this would be my third stream.

  • Yes.

  • COLTON OGDEN: Nice, you're a regular, a veteran at this point.

  • KAREEM ZIDANE: Yeah, I guess so.

  • COLTON OGDEN: What are you talking about today?

  • KAREEM ZIDANE: We're going to talk a little bit about Flask today, which

  • is a micro web framework.

  • It's used.

  • It's very popular.

  • It's a Python framework.

  • And it's used in a lot of web applications.

  • COLTON OGDEN: Nice, nice.

  • So a lot of people in the chat may have programmed in Python before, but maybe

  • not necessarily in the context of web.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: So this is kind of like a nice entry level sort of way

  • to get into server side programming with Python would you say--

  • KAREEM ZIDANE: Yup.

  • Yup.

  • COLTON OGDEN: --as opposed to maybe like something like Django

  • would be another technology that folks might have heard about.

  • KAREEM ZIDANE: You might say that Django is similar in spirit.

  • It's just, I guess, heavier.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: But I'm not an expert in Django.

  • But, I mean, yeah, it's pretty much the same thing.

  • The job of a web framework in general is,

  • you know, facilitating the process of actually developing

  • a web app or a dynamic web app.

  • COLTON OGDEN: Sure.

  • And this would be server side as opposed to like maybe

  • JavaScript, CSS, HTML, stuff that the web browser actually deals with.

  • KAREEM ZIDANE: We're going to see a little bit of HTML and CSS as well.

  • We're not going to see JavaScript, but you

  • could use JavaScript if you wanted to.

  • Yeah.

  • I mean, I thought I'd make this as simple as possible and as focused

  • as possible.

  • So, yeah, we're going to be focused more on the server side of things today

  • as well as some templating with Jinja.

  • COLTON OGDEN: Cool.

  • Awesome.

  • I can't wait.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: I'm very excited.

  • We have a few new followers here in the stream,

  • so I'm going to give some shout outs to them.

  • So thank you very much to AFMM01, Negative_Nancy, baffoon9,

  • ZombieRaccoon, [? COBOL ?] [? 2070, ?] [? Hussam ?] [? Farag, ?]

  • and [? Igor ?] [? Voltaic. ?] Thank you so much for following today.

  • KAREEM ZIDANE: Thank you.

  • COLTON OGDEN: I'll transition to your laptop

  • here so we can see what we're working with here today.

  • Yeah.

  • Why don't you get us started here?

  • KAREEM ZIDANE: Cool.

  • So I am inside of my container, yup.

  • And I thought I would start by talking about a little bit of the concepts that

  • were actually a little bit difficult for me to sort of grasp at first

  • when I first started learning about with programming.

  • And some of these concepts is, like, what's a server?

  • What's a client?

  • COLTON OGDEN: Sure, sure.

  • KAREEM ZIDANE: Like how do they communicate with each other?

  • And the basic idea is that a server is a piece of software that is just running,

  • listening for web requests.

  • At once it receives a web request, it parses it, processes it.

  • And then if everything's OK, it responds with some responses we'll soon see.

  • COLTON OGDEN: So some program on somebody's computer somewhere,

  • it's listening for network traffic sort of like bits of data

  • that are sent to it.

  • It processes them and then sends back a response.

  • KAREEM ZIDANE: Exactly, yes.

  • So, yeah, exactly as explained.

  • A client, on the other hand, might be something like a browser

  • which actually initiates or makes a web request

  • and expects a response back from the server and then, you know,

  • does something with that response whether it's, for example, showing

  • some web page and so on.

  • And so we're going to actually see an example of this right now.

  • So let's actually get started.

  • So before we actually start, I just want to explain something

  • about the protocol that's being used in this case.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: It's the HTTP protocol.

  • And it's an example of an application protocol.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And we'll see what that means.

  • But for two pieces of software to communicate with each other,

  • they need to be speaking the same language, right?

  • COLTON OGDEN: Right, yeah.

  • I guess, yeah.

  • KAREEM ZIDANE: Because, you know, if some server's listening

  • for some network traffic or some requests,

  • it expects to receive some data, right?

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: You know, if this data is arbitrary,

  • it's not going to be easy for the server to sort of make sense of it,

  • because it's not a human.

  • COLTON OGDEN: If someone's speaking French and someone's speaking German--

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: --it's highly unlikely they're going to understand each other

  • if they don't know the other language.

  • KAREEM ZIDANE: And so, yeah, there's an agreed upon language

  • that they both speak.

  • And this language is in the form of the protocol that is called HTTP.

  • And just to be clear, this is not a programming language.

  • COLTON OGDEN: Right.

  • Right, just sort of a standardized way of sending--

  • basically just communication standard protocol like you said.

  • KAREEM ZIDANE: Exactly.

  • And let's actually see exactly an example of this right now.

  • So I have just one file here called index HTML.

  • And these are the contents.

  • Let me zoom this in a little bit so we can see better.

  • And these are actually the contents of my index HTML, just a simple HTML--

  • COLTON OGDEN: Right OK.

  • KAREEM ZIDANE: --file.

  • And then I'm going to start an HTTP server to serve this file for me.

  • And then I'm going to make a request.

  • And I'm going to see what I'm sending and what I'm getting back.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • COLTON OGDEN: Cool.

  • So HTTP server, what kind of program is that?

  • Does that comes stock on Linux?

  • KAREEM ZIDANE: No, HTTP server is actually a node package.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: You can install it.

  • If you have node installed and NPM installed,

  • you can install it using npm install -g http server.

  • COLTON OGDEN: Ah, OK.

  • KAREEM ZIDANE: And it doesn't have to be the HTTP server.

  • It can be any other static web server.

  • But this tool is also actually installed already

  • on labs, and on the sandbox environment, and also on the CS50 IDE.

  • COLTON OGDEN: Can people watching right now

  • get access to one of those sandboxes and mess around with Flask themselves?

  • KAREEM ZIDANE: Definitely.

  • Yeah.

  • If you go to sandbox.cs50.io, you can choose Flask from here.

  • COLTON OGDEN: I plugged it in the chat, everybody, the sandbox.cs50.io link.

  • If you want to mess around with Flask, but not

  • actually have to install it on your physical machine,

  • definitely check that out.

  • Also, lethalshotgg, mdobra71, and [? mansonjai, ?]

  • thank you very much for following.

  • KAREEM ZIDANE: Yup.

  • COLTON OGDEN: We'll have to come back to the chat in just a second.

  • I think maybe once we've gotten started we can read up all the messages.

  • We have a few.

  • We a little bit of a backlog to catch up to.

  • KAREEM ZIDANE: Yup.

  • COLTON OGDEN: But, anyway, you were saying?

  • So we have HTTP server.

  • You set that up using the node package HTTP server.

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: So now it's running on your machine.

  • So it's kind of listening forever, right, for network traffic?

  • KAREEM ZIDANE: Correct.

  • Yeah.

  • And for it to be listening, it has to be listening for on some port.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: And you can you can think of--

  • like people often use an analogy for this I think.

  • You know, different ports correspond to sort of different apartment numbers

  • in a building somewhere.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: So different ports are used for different services.

  • And by convention, you know, HTTP servers listen

  • for it should be traffic on port 80, or HTTPS traffic on port 443,

  • or SSH traffic on port 22, and so on.

  • COLTON OGDEN: So Jerry makes pizzas in room 80.

  • And if somebody wants a smoothie, they're

  • going to go to Tom's apartment--

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: --in room 81.

  • Or I guess, what's the HTTPS?

  • KAREEM ZIDANE: HTTPS 443?

  • COLTON OGDEN: Yeah, they'd go to room 443 instead of room 80 I guess.

  • KAREEM ZIDANE: Yeah, exactly.

  • So, yes, you would be able to send some data to some port whether it's open

  • or not.

  • Maybe you'd get an error if it's not open.

  • If it is open and some other server is listening

  • on that port for different kind of traffic,

  • it's maybe going to give you a bad response, or ignore you at all,

  • or it does whatever it wants to do.

  • COLTON OGDEN: Right.

  • OK.

  • So different ports are reserved for different purposes.

  • KAREEM ZIDANE: Yes.

  • And by default, here HTTP server actually listens on port 8080,

  • as we can see, right?

  • So we're expected to go to whatever IP address of our machine is,

  • [? code ?] [INAUDIBLE] port.

  • COLTON OGDEN: Right.

  • And 127.0.0.1 is usually shorthand for my own computer--

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: --local host.

  • KAREEM ZIDANE: It's a loopback IP address.

  • It's local host.

  • Yes, it refers to your computer.

  • COLTON OGDEN: Right.

  • I'm actually not as familiar with 172.17.0.2.

  • KAREEM ZIDANE: So it's a little bit complicated.

  • There are multiple IP addresses, because the Docker container that I'm using

  • has a different IP address.

  • COLTON OGDEN: I see.

  • OK.

  • KAREEM ZIDANE: And so right now, it listens on all IP addresses

  • that this container has, which is the local host IP address and the Docker

  • container's IP address.

  • COLTON OGDEN: I see, OK.

  • That's pretty cool.

  • So it makes it accessible from both your computer and Docker?

  • KAREEM ZIDANE: Yes.

  • Yes.

  • COLTON OGDEN: Nice.

  • KAREEM ZIDANE: Kind of.

  • COLTON OGDEN: OK.

  • So you have the server up right now.

  • So it says hit control C to stop it.

  • KAREEM ZIDANE: Yup.

  • COLTON OGDEN: So it's just a regular program, a CLI program.

  • And then now what you're trying to do is test actually

  • getting a response from the server.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: So that's where you're using Curl.

  • KAREEM ZIDANE: Yeah.

  • I'm just going to make a request to that server.

  • And I'm expecting to get a response from the server.

  • And I don't have to use Curl for this.

  • You can use your web browser.

  • I'm going to show how to do this in your web browser.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: But for now, just for the sake of simplicity,

  • I'm just going to try Curl.

  • And let me resize just a little bit.

  • OK.

  • So local host we said, and then :8080

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And then hit Enter.

  • And if you notice up here, the server actually got something, right?

  • COLTON OGDEN: Right, yeah.

  • KAREEM ZIDANE: It appears to have gotten a--

  • COLTON OGDEN: Different colored text, too.

  • KAREEM ZIDANE: Exactly.

  • Yeah, get request forward slash, we'll explain what that means in a moment.

  • Let's crawl back up here a little bit and see what our tool actually did.

  • So the first thing that our tool did is open the connection to the server.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: Right?

  • And then--

  • COLTON OGDEN: Curl is kind of like a command line

  • version of using a web browser to go to a you URL

  • almost in a very limited sense?

  • KAREEM ZIDANE: Yeah.

  • Curl is, essentially, a tool that you can use to make--

  • COLTON OGDEN: Network request--

  • KAREEM ZIDANE: Requests, yeah.

  • COLTON OGDEN: --generally speaking?

  • KAREEM ZIDANE: Yeah.

  • Let me actually highlight this so that we can see it better.

  • So all of the greater than sign something, this is what is being

  • or what has been sent already.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And everything that follows

  • that's prefixed with a less than sign is actually the response

  • that we got from the server.

  • COLTON OGDEN: Oh, that's cool.

  • OK.

  • Cool.

  • KAREEM ZIDANE: Right?

  • COLTON OGDEN: You can see the direction of the traffic.

  • KAREEM ZIDANE: Exactly.

  • So I highlighted the request parse, so that it's easier for us

  • to see hopefully.

  • And after Curl made a connection to the server,

  • it actually sent these lines that we're seeing right here.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: So first line is, you know, get/http/1.1.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And what that means-- so there

  • are different kinds of HTTP requests.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: We're going to use a couple of them today, get and post.

  • Get is generally used to sort of retrieve resources or retrieve

  • information from a server.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And in this case, we--

  • COLTON OGDEN: We're getting some information from the server.

  • KAREEM ZIDANE: Exactly, yes.

  • Literally, yeah, getting some information from server.

  • And in this case, by default, since we didn't specify any path after

  • the 8080/, it's going to try to get index.html.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • Or the server is going to try to serve us index HTML by default.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: So this says, hey, we're making a get request.

  • And we're requesting the slash resource in this case.

  • Right?

  • COLTON OGDEN: OK.

  • So it's like the route.

  • It's kind of like the beginning of your hard drive almost,

  • but in an abstract sense also related to websites that might have multiple URLs,

  • like facebook.com/users/comments.

  • But this would just be like facebook.com.

  • KAREEM ZIDANE: You may think of it as a path

  • in some structure on your computer.

  • But it's not always the case that this is a path.

  • It can be something arbitrary [? that's ?] mapped

  • for something else behind the scenes.

  • COLTON OGDEN: Yeah.

  • Yeah, with the routing and stuff like that.

  • KAREEM ZIDANE: Exactly, yes.

  • And so the next bit is HTTP/1.1.

  • And what this means is that Curl tries to inform the server that,

  • hey, I'm speaking HTTP version 1.1 just to make sure that they both understand

  • the same version HTTP in this case.

  • COLTON OGDEN: Not a whole lot of versions of HTTP.

  • It looks like they've had a fairly limited number of versions.

  • KAREEM ZIDANE: That's fair, but for the future maybe, like if this changes.

  • COLTON OGDEN: Yeah.

  • Yeah.

  • KAREEM ZIDANE: If some client, or Curl, or browser, or something else--

  • COLTON OGDEN: Aren't they coming out with HTTP/2?

  • Isn't that a thing?

  • KAREEM ZIDANE: I think it is.

  • I don't know much about that.

  • [INAUDIBLE]

  • COLTON OGDEN: I thought I heard about that at some point, maybe not.

  • KAREEM ZIDANE: Yeah.

  • I don't know much about it unfortunately.

  • I don't know about the differences.

  • So maybe I should look this up after and see.

  • But, anyway, the point is that this sort of

  • tries to ensure that they're both speaking the same version of HTTP,

  • because different versions can have different sort of, I don't know,

  • system of actions, or statements, or sentences

  • that they might not understand.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: And so this just tries to make sure

  • that they're both speaking the same version.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: The second line here host:local host 8080,

  • and this is what's called a request header, right?

  • It's additional data or additional metadata sent as part of the request.

  • And it can be useful for some contexts.

  • And the context here is that it's not always the case

  • that you can just have one server running on one machine,

  • on the same machine.

  • In other words, you can have more than one server running on the same machine.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: And this just tries to make sure

  • that, hey, I am looking for the server that's a local host for 8080

  • specifically.

  • Because there could be another HTTP server listening on 8081 OR 8082

  • or whatever, right?

  • COLTON OGDEN: Makes sense, yeah.

  • KAREEM ZIDANE: OK.

  • COLTON OGDEN: Like email servers, too.

  • KAREEM ZIDANE: Email servers.

  • COLTON OGDEN: HTTP servers.

  • KAREEM ZIDANE: Usually, you look on port 25 I believe.

  • COLTON OGDEN: Yeah.

  • I think that's right.

  • Yeah.

  • KAREEM ZIDANE: But, yeah, so this tries to make it clear that, hey, I am

  • requesting from this particular server.

  • There's also the context of virtual server.

  • And this is, you know, you can run more than one server on the same machine.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: They're called virtual servers.

  • COLTON OGDEN: Makes sense.

  • KAREEM ZIDANE: Because there's also the physical server, the actual hardware

  • server, the computer that it's running.

  • COLTON OGDEN: Like vhosts to with PHP back in the day?

  • KAREEM ZIDANE: Yeah.

  • Exactly.

  • I think the vhost and virtual servers mean the same thing actually.

  • COLTON OGDEN: Yeah, I think they're the same thing.

  • Yeah.

  • KAREEM ZIDANE: The next line here is a user agent.

  • And this is also other request header.

  • And this is just Curl trying to let the server know that, hey, I'm

  • Curl that's making this request, not Chrome, not Firefox, not Safari, not

  • Opera.

  • It's Curl version whatever, 761 whatever if that makes sense.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: OK.

  • Although, I mean, you can technically sort of change these headers

  • if you want with some custom options if you want.

  • So this doesn't guarantee that the entity or the software that's

  • making the request is actually Curl.

  • I can trick the server into thinking that what's making the [INAUDIBLE]

  • is actually Chrome, or Firefox, or something.

  • COLTON OGDEN: Kind of like how Verizon injected

  • into like mobile traffic its, like, special headers--

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: --which David talked about it in lecture I think at one point.

  • KAREEM ZIDANE: I'm not sure about Verizon,

  • but I know some internet providers do that as well, like inject

  • some data in the headers sometimes.

  • COLTON OGDEN: Which makes sense.

  • And [INAUDIBLE] is actually asking, "are you guys doing a lecture

  • on Django in the future?"

  • And that's a good question.

  • Maybe in the future.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: Maybe some Django if people want some Django.

  • [INAUDIBLE] is saying, "Who's teaching who-- the guy on the right asking

  • all the questions."

  • Yeah, I'm very curious about all that Kareem has to teach us today.

  • All right.

  • KAREEM ZIDANE: I'm sure we're all going to learn something today.

  • COLTON OGDEN: Oh, yeah.

  • I'm sure I'm going to learn a lot.

  • So that was all of the request information.

  • And so what's below that is the response information, right?

  • KAREEM ZIDANE: There's actually one more header--

  • COLTON OGDEN: Oh, I see.

  • KAREEM ZIDANE: --or request [INAUDIBLE]----

  • COLTON OGDEN: OK, right.

  • KAREEM ZIDANE: --which is the except star slash star.

  • And this means that, hey, in the response that you're sending,

  • I'm expecting anything that you send back pretty much.

  • So a server can send back HTML.

  • It can send back, you know, JSON data.

  • It can send back some other binary data.

  • You know, we can specify, hey, I'm just expecting HTML.

  • I'm just expecting JSON.

  • And in this case, Curl is expecting pretty much anything.

  • COLTON OGDEN: OK.

  • Kind of acts like a filter almost a little bit?

  • Will it get rid of MIME types that don't satisfy that pattern?

  • KAREEM ZIDANE: So the server actually should handle this.

  • The server should see this except header, like look into your header

  • and see what you're asking for.

  • And if the server is able to provide this kind of response, it should.

  • Otherwise, it should provide you with some sort of error

  • that indicates that I don't have this kind of resource available.

  • COLTON OGDEN: Makes sense.

  • OWLYone, ghostwake, dotmido, and vivek_chauhan,

  • thank you very much for the following, appreciate it.

  • KAREEM ZIDANE: Thank you.

  • All right, so these are the defaults, request headers

  • that Curl seems to be sending by default.

  • There are a bunch of others if you want to look at the documentation.

  • There are so many other requests headers that we can use.

  • And the next part here is the response that we got back from the server.

  • And so the first line says, HTTP/1.1.

  • And this is just the server saying back that, hey, I

  • speak the same HTTP version.

  • COLTON OGDEN: So we know they're speaking

  • the same language at this point.

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: They're both saying essentially same thing.

  • KAREEM ZIDANE: Yes.

  • The server also adds 200 OK in this case.

  • And 200 is what's known as an HTTP status code.

  • And it's just a numeric code that indicates

  • the status of this request or response, whether it was successful or not.

  • COLTON OGDEN: Everybody in the chat, the status

  • code that you're most familiar with, go ahead and plug that.

  • And we won't spoil it.

  • But I'm sure many of the people in the chat

  • have seen a HTTP status code of a particular variety

  • many times on the web and have just not--

  • oh, actually, [? Barrack ?] said 503.

  • That's true.

  • 503's fairly common.

  • It's not as common--

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: --as another very, very common one right now.

  • KAREEM ZIDANE: Lots of people are mentioning it right now.

  • COLTON OGDEN: Yeah, let everybody know this.

  • KAREEM ZIDANE: It's not a secret really.

  • It's 404.

  • COLTON OGDEN: Yeah, there we go.

  • 404.

  • Someone says 401 though.

  • Someone's got 401 a few times, 403 as well.

  • [? Barrack, ?] OK, that was sarcasm.

  • OK.

  • I've definitely seen 503 a handful of times.

  • But there we go, 418.

  • That's the troll.

  • I'm a teapot.

  • It is a real one, but it's not a very common one.

  • KAREEM ZIDANE: One of them was--

  • I think was it that one was an April's fool at some point I think?

  • COLTON OGDEN: Yup, by the creators of a HTTP--

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: --or the maintainers.

  • And then [? Dement, ?] 301, yeah, that's actually a redirect [INAUDIBLE]..

  • KAREEM ZIDANE: That's also--

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: --fairly common as well, a redirect.

  • I think that would be permanent redirection.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: OK.

  • So we have a bunch of others.

  • People are very familiar with different HTTP status codes here.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: So I'm not going to spend much time.

  • COLTON OGDEN: You're preaching to the choir.

  • KAREEM ZIDANE: Yeah, exactly.

  • COLTON OGDEN: Everybody already knows everything you're talking about.

  • [INAUDIBLE], Kareem.

  • KAREEM ZIDANE: Yeah, I'm not going to [INAUDIBLE] end up.

  • I guess there's not nothing to talk about.

  • [LAUGHTER]

  • OK.

  • COLTON OGDEN: They're actually going to teach you Flask today.

  • KAREEM ZIDANE: Yeah, I would actually be very

  • interesting to learn more about this.

  • OK.

  • So it says 200 OK.

  • Hey, your request was OK.

  • Here's a response.

  • It also sends a server response header.

  • And what this actually says is, hey, you know, the kind of server that's running

  • is actually this weird name, ecstatic.

  • COLTON OGDEN: It's a very happy, ecstatic server.

  • KAREEM ZIDANE: Yeah, 330.

  • And actually for security reasons, some actual servers or some people

  • choose to configure the servers to not send that particular header.

  • COLTON OGDEN: [INAUDIBLE].

  • Because then they know if you have a particular version

  • of a particular server that has a security vulnerability.

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: You've kind of expressed that to the world.

  • KAREEM ZIDANE: Yeah, making the chances higher of someone,

  • you know, exploiting that.

  • The next header here is cache control.

  • And this is a header that says the server is trying

  • to say to the client, hey, you can cache this response

  • for this many seconds, which is 3,600, which is like an hour.

  • So the server is essentially saying, hey,

  • don't ask me about the same thing within an hour, right?

  • And this can be useful, of course, to sort of reduce traffic on our servers

  • if browsers can cache this data.

  • You know, a bunch of other headers-- last modified.

  • Content length is the actually the size of the file

  • that the server is sending back.

  • COLTON OGDEN: In bytes, correct?

  • KAREEM ZIDANE: In bytes, yes.

  • Here's the MIME type that you talked about.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: There's the content type header, which includes a MIME type.

  • In this case, the type of data that we're sending back is text/html.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: There are a bunch of others,

  • too, if you want to check them out, and a couple other

  • headers that we won't actually dive into,

  • but you're free to read more on them or other headers online.

  • And following that, following all the headers that we got,

  • there's actually the data, which is the body of response.

  • COLTON OGDEN: The stuff that we actually really care about.

  • KAREEM ZIDANE: The stuff that we actually care about.

  • COLTON OGDEN: Ultimately, yeah.

  • KAREEM ZIDANE: So you can imagine like this

  • is what actually happens when you try to make a request through the same server

  • in your browser.

  • It sends these requests headers.

  • It gets back--

  • COLTON OGDEN: You don't get all of that stuff.

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: As the end user, you see that, but rendered in a visual format.

  • KAREEM ZIDANE: Exactly.

  • So the browser takes care of all that, parses all the headers,

  • parses the body of the response, and then

  • translates it into the sort of page that you see or whatever.

  • COLTON OGDEN: Images and text and whatnot--

  • KAREEM ZIDANE: Yeah, whatever resource.

  • COLTON OGDEN: --that you end up seeing ultimately.

  • KAREEM ZIDANE: Exactly.

  • That's exactly right.

  • COLTON OGDEN: "Do you know when Professor David will

  • do the next Livestream?"

  • This is [? Oncu255. ?] And then [? In The ?] [? Ready ?] kindly said,

  • "he'll be on Friday on the stream for the code review," which is correct.

  • We are indeed having a code review.

  • So anybody that's here in the chat that's not aware,

  • if you go to bitly/cs50/codereview here, we're

  • accepting source code on GitHub or Gist.

  • And if you want us to review it on stream on Friday

  • with David, David and myself, definitely go ahead and toss us your repos.

  • And it's going to be a style slash design review.

  • It's not going to be bug testing or anything like that.

  • So don't, ideally, send us broken code.

  • Send us working code.

  • And this is more catered also towards beginner to intermediate programmers

  • students who want just a little bit of help with their style,

  • much in the same way that we do sort of CS50 Harvard students style grading.

  • Ideally, don't send us CS50 pset repos, just so

  • that we don't have to spoil solutions for students online.

  • But send us all of your repos that are not CS50, ideally, pset related.

  • And we will take a look at it.

  • KAREEM ZIDANE: Yeah.

  • That should be so much fun.

  • COLTON OGDEN: Yeah, I'm excited.

  • We have quite a few people that have already submitted.

  • And you know, if it does well, we might do more than one episode.

  • But this Friday will be our very first version

  • of that sort of side series for this channel.

  • So I'm very excited to take a look at that.

  • KAREEM ZIDANE: Cool.

  • All right, so I'm just quickly going to show the same thing in the browser.

  • So if you visit local host, call 8080 in the browser,

  • you should see if you open your developer tools by right clicking,

  • and then Inspect, and then choosing the Networks tab,

  • you should be able to see different information

  • about the request and the response, pretty much the same information.

  • Maybe Chrome includes a couple more request headers,

  • a couple different values for them.

  • But it should be essentially the same thing.

  • COLTON OGDEN: Right, OK.

  • KAREEM ZIDANE: And of course, on top of that,

  • you get the page rendered as you expect, which [INAUDIBLE]..

  • COLTON OGDEN: You get access to all the same information,

  • just in a more user-friendly way [INAUDIBLE]..

  • KAREEM ZIDANE: Yeah, exactly.

  • Cool.

  • All right, so now that we've demonstrated this,

  • another thing that I want to talk about is

  • the difference between a static website and a dynamic website.

  • COLTON OGDEN: Sure.

  • OK.

  • KAREEM ZIDANE: And what do you think a static website is?

  • COLTON OGDEN: A static website to me means a website

  • that, if we go to that page as many times as we want,

  • it's going to show us the exact same content every time.

  • KAREEM ZIDANE: Exactly.

  • I mean, also to add to that, if you go to that page or I go to that page,

  • we should technically see the same content.

  • It doesn't change--

  • COLTON OGDEN: Correct.

  • KAREEM ZIDANE: --if the user changes.

  • And technically, some websites could use JavaScript and some external APIs

  • to change their contents maybe per user, maybe different use cases.

  • So we're not going to worry about that for now.

  • I think they would still be static websites

  • since there is no back end that's handling something here.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: A dynamic website, on the other hand--

  • so a static website, actually as an example,

  • would be the documentation for our pset specifications, right?

  • So if Colton goes to pset 0 specifications,

  • he will see the same thing as I'm seeing right now.

  • COLTON OGDEN: Yup.

  • KAREEM ZIDANE: Right?

  • A dynamic website, on the other hand, will be something like Facebook,

  • or Twitter, or Reddit, whatever social network.

  • COLTON OGDEN: Yeah.

  • It changes every time you refresh.

  • You have all your friends and their posts, all the comments, all the likes.

  • The like number could change.

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: The profile pictures of your friends could change.

  • KAREEM ZIDANE: Yeah.

  • Different people see different things.

  • You know, I see my name on the top right.

  • You see your name on the top right.

  • People who are not logged in see completely different things and so on.

  • And so that's often referred to as a dynamic website.

  • A dynamic website also has a back end that's

  • up and running handling different requests as we'll

  • have one today and demonstrate and go through something.

  • All right, so let me get out of this and start with actually

  • our first Flask related example.

  • COLTON OGDEN: [? Dmsmtp ?] and saltyglowstick,

  • thank you very much for the follows as well.

  • KAREEM ZIDANE: Thank you.

  • All right, so the first thing that we need to have to work with this

  • is have Python installed.

  • COLTON OGDEN: Sure.

  • That's going to be important if we're programming

  • in Python, anything in Python.

  • KAREEM ZIDANE: I'm not going to provide instructions on that.

  • But if you go to python.org or whatever the URL is, it should be--

  • COLTON OGDEN: I think it's by the node.

  • KAREEM ZIDANE: --there for [INAUDIBLE].

  • COLTON OGDEN: I'll plug it.

  • Everybody let me know if that's the correct link.

  • And also, shout out to the regulars, [? Nawanda, ?] [? Bella, ?]

  • [? Bavik, ?] [? Andre, ?] [? Whipstreak, ?] there were multiple

  • other ones that we saw up above.

  • We have some new ones [? Oncu, ?] [? Dement, ?] In The Ready,

  • which we've mentioned before, [? mkloppenburg, ?] who left early

  • unfortunately, but thanks for popping, [? Varani, ?] and then all of the other

  • folks I've mentioned so far.

  • Apologies if I did not catch your name, but thank

  • you very much to all the people that are tuning in right now

  • and have been tuning in so far.

  • KAREEM ZIDANE: All right, so I have Python already installed.

  • In this case, I have Python 3.7.

  • I think Python 3 in general should work.

  • And the first thing we need to do to install Flask is pip3 install flask,

  • right?

  • And of course, pip3 is not found, because I need to install pip3.

  • COLTON OGDEN: Yup So pip3 is a package manager for Python, right?

  • KAREEM ZIDANE: Correct, yes.

  • It's a software that allows you to install a package, remove packages.

  • COLTON OGDEN: And apt-get is kind of like that, but that's

  • for use for Linux.

  • KAREEM ZIDANE: For Ubuntu and [INAUDIBLE]..

  • COLTON OGDEN: Oh, for Ubuntu Linux.

  • Right, because fedora could be for--

  • KAREEM ZIDANE: It's also in a bunch of other distributions.

  • COLTON OGDEN: [INAUDIBLE] or whatever.

  • KAREEM ZIDANE: But Ubuntu, I guess, is the most popular one.

  • So I'm right now installing [? pip3, ?] as you can see.

  • COLTON OGDEN: It's a massive installation.

  • KAREEM ZIDANE: Yeah.

  • And hopefully, that should work this time, pip install flask.

  • And all good.

  • OK.

  • So we now have Flask installed.

  • To verify that, you can run Flask [INAUDIBLE] version.

  • And it should output something.

  • COLTON OGDEN: Outputs an error.

  • KAREEM ZIDANE: OK, outputs an error.

  • I mean, ideally, this wouldn't show up on your computer.

  • But it's actually showing me what to do to fix this error here.

  • So I'm just going to follow this instruction and try again maybe.

  • Hopefully, it won't break this time.

  • OK.

  • COLTON OGDEN: Nice.

  • KAREEM ZIDANE: So I just needed to export

  • a couple of environment variables.

  • It's showing me what to do here.

  • So I did it, and it worked.

  • This is what you should see when you run Flask [INAUDIBLE] version

  • to verify that it was installed correctly.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: All right, so I'm going to dive

  • into the first example of the day.

  • And the goal of this example is to sort of visit the same URL that we visited

  • a few seconds ago, a few minutes ago, and sort of

  • see simply hello as a response--

  • COLTON OGDEN: OK, sure.

  • KAREEM ZIDANE: --so nothing fancy.

  • And the way to do that would be, first of all,

  • we need to import Flask with a capital F from flask, the lowercase.

  • COLTON OGDEN: Yup.

  • KAREEM ZIDANE: And we need to create an app, instantiate an app.

  • And this app needs to be passed some string that sort of identifies

  • that app.

  • I mean, usually at the beginning, you shouldn't really

  • worry too much about this.

  • Most people just pass __name__.

  • Yup.

  • So don't worry about this for now.

  • Just instantiate the app the way it is right now.

  • And the next thing that we see here is an app.route/, forward slash.

  • And what do you think?

  • Do you know anything about the @ in Python?

  • COLTON OGDEN: I know it's a decorator.

  • So it's kind of like a higher order function in Python a little bit.

  • That's kind of a generalization for it.

  • Basically, [? wraps, ?] another function,

  • does some information either before or after it and returns that function,

  • that [? wrapped ?] function.

  • KAREEM ZIDANE: Correct.

  • So in Python, functions are what they call first class objects I think.

  • COLTON OGDEN: First class objects, yeah.

  • KAREEM ZIDANE: Yes.

  • And so a function can be passed to another function as an argument,

  • can be returned from another function as an argument.

  • And a decorator simply is a function that

  • takes another function as an argument or takes a function as an argument

  • and returns a function.

  • COLTON OGDEN: Yup, exactly.

  • KAREEM ZIDANE: Right?

  • So if you had to guess, what does this do

  • in this case, what does this decorator do in this case?

  • COLTON OGDEN: Well, in this case, it looks

  • like it's making whatever the function below it does do some operation,

  • some logic, when they get directed to the string that's passed into route.

  • KAREEM ZIDANE: Correct.

  • So Flask actually handles of ton of stuff for us for free.

  • And as you mentioned, the way to apply a decorator to a function

  • is using the @ decorator and then pass it any arguments that it needs.

  • And then right after that, you should just define your function normally.

  • And the way this works when this program runs, what's actually going to happen

  • is that this function index is actually going to be passed as an argument

  • to the decorator.

  • And another function is to be returned.

  • Presumably, that other function has some other logic

  • that wraps around lots of complicated stuff

  • that we hopefully don't want to go through.

  • COLTON OGDEN: All the magic.

  • KAREEM ZIDANE: Exactly.

  • And part of the magic in this case is route handling as you mentioned.

  • So in this case, if I receive a request on slash, right--

  • COLTON OGDEN: You probably have some global object, too,

  • that manages all the routing.

  • And then this adds that information to that global object

  • or whatever could be defined the function.

  • Yeah.

  • KAREEM ZIDANE: Yeah.

  • That would be my guess.

  • So in this case, if I receive a request on slash, what should we do?

  • We should return hello.

  • COLTON OGDEN: Right.

  • And the name of the function itself doesn't really matter.

  • Because all Flask is really doing, I'm guessing,

  • internally is keeping a reference to those function names

  • and managing that on its own.

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: It's saying, if the user goes to slash, call index, right?

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: Because it's mapping it probably

  • just having a direct reference to the function.

  • Because, like you said, it's first class.

  • So it just really needs to refer to its symbol, and it can call it.

  • KAREEM ZIDANE: I can't remember exactly, but I believe the name of the function

  • only matters if you use the URL underscore 4 functionality.

  • COLTON OGDEN: I think yeah.

  • I think so yeah.

  • KAREEM ZIDANE: We're not going to be using that today.

  • But just for now for simplicity, this name can be anything you want.

  • It can be foo.

  • It can be bar.

  • It can be anything you want.

  • What actually matters is the decorator that's before it.

  • COLTON OGDEN: Correct.

  • KAREEM ZIDANE: If you have a route [? on ?] slash,

  • the following function is going to be run when you visit that route.

  • COLTON OGDEN: Let's answer a couple of questions from the chat.

  • So [INAUDIBLE] says, "why does mail from the SMTP library go into spam?"

  • Do you happen to know offhand?

  • KAREEM ZIDANE: I mean, I don't really know much about this.

  • But usually sort of mail servers have some ways

  • of verifying whether the party that has sent this email is actually legitimate

  • or not.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: Like, for example, if you use your own web server, your own mail

  • server, to send people some emails, other mail servers

  • upon receiving this email don't really know who this server belongs to

  • or whether it's malicious or not.

  • So they usually filter it as spam by default.

  • COLTON OGDEN: Make sense.

  • I can imagine that happening, too, if you

  • say that I'm sending email from some messages not

  • actually what the from sender is.

  • You know, if you say I'm sending this from coltonoscopy@gmail.com,

  • which is my email address, but my Flask server isn't going from gmail.com,

  • it's coming from some random server somewhere--

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: --that's probably an indicator

  • to Gmail or some other service that this is probably illegitimate.

  • KAREEM ZIDANE: Yeah.

  • As you mentioned, you can spoof email addresses,

  • the phony email addresses, and make it seem

  • like someone else is sending an email.

  • But, you know, again, some web servers do

  • have ways to handle this whether by filtering it as spam

  • or showing you some icon that says this might be a malicious email.

  • But, yeah, this should be possible.

  • COLTON OGDEN: [? Dement0 ?] says, "first time joining your Livestream.

  • The earlier ones you did-- watched on YouTube.

  • This time decided to join the steam to say hi, Colton and Kareem."

  • KAREEM ZIDANE: All right, hi there.

  • COLTON OGDEN: Awesome.

  • Thank you so much, [? Dement, ?] really appreciate it.

  • Thanks for tuning in live, really appreciate it.

  • [? Andre's ?] clarifying about the Debian Linux package manager apt-get

  • in Ubuntu and other [INAUDIBLE] use it.

  • [? Varani ?] says, "this looks very similar to Express.js."

  • It's been a little while since I've used express actually.

  • But I mean a lot of these sort of micro-- these frameworks, back end

  • frameworks kind of look similar.

  • The routing kind of looks very similar.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: It's a common paradigm.

  • And Laravel, I think, for its PHP framework, adopts a similar convention.

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: "Which course do Harvard students do after CS50?"

  • Generally, CS51 is the next go to.

  • And that's that kind of an object-oriented functional programming

  • course.

  • And there's operating systems, and algorithms, data structures.

  • A discrete math course that you took, the extension version of it,

  • students will take something like that.

  • Which course?

  • What number was that?

  • Do you remember?

  • KAREEM ZIDANE: The discrete math course?

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: I think it was CS20 or something.

  • COLTON OGDEN: Oh.

  • Yeah, yeah.

  • CS20.

  • So yeah.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: It doesn't necessarily go higher number than CS50, but, yeah,

  • there's a bunch, whole bunch of different ones.

  • "All the CS50 team is doing an amazing job

  • to make these technologies easy to learn and follow thank you very much.

  • Please keep doing what you do."

  • Hey, that's a nice compliment.

  • KAREEM ZIDANE: Yeah, thank you.

  • COLTON OGDEN: Thank you very much, [? Dement, ?] really appreciate it.

  • "I also need a CS50 hoodie and T-shirt," says [INAUDIBLE]..

  • Yeah, well, if you teach CS50, you can have one of these awesome hoodies.

  • But you got it to become a staff member.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: "It's a dream learning from CS50."

  • Also, protip, when spoofing an email, make

  • sure you're not auto-appending your signature.

  • Probably.

  • KAREEM ZIDANE: OK.

  • COLTON OGDEN: That's probably something you don't want to do.

  • KAREEM ZIDANE: All right, so let's actually test this in action.

  • So the way to run this would be by navigating

  • to the folder where your [INAUDIBLE] in this case and then run Flask run,

  • and then optionally, -p, and then the port number that you want to listen on.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: By default, Flask listens on port 5,000.

  • I prefer using 8080.

  • There's no real difference here except that I

  • have this exposed from my container.

  • So I'm just going to listen on port 8080.

  • And when you do this, Flask has a built-in server.

  • It's actually from another framework.

  • But it has a server that starts up and starts expecting information

  • on this particular port.

  • I think this is going to fail.

  • Let me see why.

  • COLTON OGDEN: Very optimistic of you.

  • KAREEM ZIDANE: Yeah.

  • I mean, I noticed something that I need to--

  • OK.

  • Well, is that correct?

  • Did we expect that?

  • COLTON OGDEN: Oh, because that says hello.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: And the message said, hello there in the web browser.

  • KAREEM ZIDANE: It might be listening on some--

  • there has to be another server that's listening on this.

  • Let's see.

  • OK.

  • That's weird.

  • COLTON OGDEN: Well, weren't you just using the HTTP server

  • in your Docker container?

  • KAREEM ZIDANE: OK.

  • Now, it works as expected.

  • COLTON OGDEN: Oh, was a caching it?

  • KAREEM ZIDANE: I think it was caching it, yes.

  • COLTON OGDEN: Oh, OK.

  • Interesting.

  • KAREEM ZIDANE: All right, so this doesn't work,

  • because I'm listening on IP address 127.0.0.1.

  • And I'm inside the container.

  • So it's a little bit confusing.

  • For my host, 127.0.0.1 is the host itself, not the container.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: So what I want to do is listen for actually all IP addresses

  • inside of this container.

  • Again, if you're running this on your host

  • directly, if you're not using Docker, don't worry about this.

  • You shouldn't need this argument.

  • But I'm going to do this for now.

  • And I get what I expect to get, which is hello.

  • COLTON OGDEN: Nice, OK.

  • KAREEM ZIDANE: All right, so very simple, very easy.

  • Let's switch to the second example that we have today.

  • And this example would essentially expect

  • some piece of data that can be different from request to request.

  • And then it returns a response that's different based on that piece of data.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: So in this case, I'm expecting a name get parameter.

  • As we mentioned earlier, we can send get requests, we can post requests.

  • And we can parametrize these requests in the sense

  • that we can include variables or parameters with different values

  • each time.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: Right?

  • So in this case, I'm expecting a parameter called name with a name name,

  • literally, and with a value presumably the name of the person who's

  • making the request.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • So the way to make a request with a get parameter like this would be as

  • follows.

  • Let's just make sure the server's running first.

  • So let's run the server on the same port.

  • And now the way to do this would be to append a question

  • mark to the end of your URL and then mention the name of the variable

  • or the name of your parameter equals its value.

  • So in this case, I'm going to say my name.

  • COLTON OGDEN: The key value pairs?

  • KAREEM ZIDANE: Exactly.

  • So name of the parameter equals the value of the parameter, right?

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And hit Enter.

  • And I get hello, Kareem.

  • COLTON OGDEN: Nice, works very splendidly.

  • So if you did name equals nothing?

  • KAREEM ZIDANE: [? Correct. ?] Well, that's a good point.

  • If I don't include this parameter at all, that's a little buggy.

  • COLTON OGDEN: Hello, [? none. ?] Nice.

  • KAREEM ZIDANE: Right?

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And that's because the default value of this parameter

  • is none.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: Or the default value that's requested

  • are-- so get returns here is actually not for this parameter.

  • COLTON OGDEN: What if you did hello equals, and then nothing

  • after the equals?

  • KAREEM ZIDANE: I think it would be the same thing.

  • Would it be an empty string?

  • COLTON OGDEN: Let's try it.

  • KAREEM ZIDANE: It would be an empty string I think.

  • COLTON OGDEN: Let's try it.

  • KAREEM ZIDANE: So let me actually get this running somewhere else.

  • COLTON OGDEN: And, also, thank you very much to [INAUDIBLE] and [INAUDIBLE]..

  • I apologize if I butchered that.

  • Thank you both very much for following.

  • 8880.

  • all right, let me see.

  • Oh, I have to be in the same shell.

  • OK.

  • All right, I didn't think about this before this [? seam. ?]

  • But, anyway, if we did name equals this, it's going to be [INAUDIBLE]..

  • COLTON OGDEN: Nice.

  • OK, so a different behavior.

  • OK.

  • KAREEM ZIDANE: Right?

  • So this is a different value technically.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: In the first case, in the case where the name is not present

  • at all, the parameter is not present at all.

  • And so the default value that get returns here is none.

  • COLTON OGDEN: Correct.

  • KAREEM ZIDANE: But in this case, actually the parameter is present.

  • And there is a value for it.

  • And this value is empty, right?

  • So it just returns the empty string

  • COLTON OGDEN: Nice.

  • KAREEM ZIDANE: Right?

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: So there are ways where we can handle this.

  • We're not going to worry too much about this right now.

  • The second thing that I wanted to mention about this

  • is that if I have more than one parameter, more than one key value

  • pairs, they are separated with an ampersand.

  • So if I have name equals Colton and email equals colton@cs50.harvard.edu,

  • this is how this would be read.

  • COLTON OGDEN: Right, OK.

  • KAREEM ZIDANE: That's [INAUDIBLE].

  • COLTON OGDEN: And then you could get more than one variable

  • inside your route just by grabbing the request.args.get email in this case.

  • KAREEM ZIDANE: Correct.

  • Yeah.

  • So this is the way that we get the value of a get parameter

  • called name, request.args.get name.

  • And notice that we have to import request from Flask up here as well.

  • COLTON OGDEN: Nice.

  • OK.

  • We have a couple questions in the chat, too.

  • KAREEM ZIDANE: OK.

  • COLTON OGDEN: [? Webstreak ?] is asking, "quick question,

  • does there happen to be message input into the rendered template function,"

  • which you haven't gotten to yet.

  • KAREEM ZIDANE: We haven't gone to that part yet.

  • I don't know off the top of my head.

  • I don't think I've used it before.

  • But let's actually check the documentation.

  • Let's see.

  • So there is the render template function.

  • I don't see a message parameter here.

  • So I don't think it has one.

  • COLTON OGDEN: Yeah.

  • And I think in this case wouldn't you just pass in whatever variables

  • you want and then have the templating thing sort of take care of?

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: And there's also flash messaging, which

  • I think you can integrate into Jinja, can't you?

  • KAREEM ZIDANE: We're actually going to demonstrate both of these today.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: We're going to demonstrate passing data to a template

  • and then flashing some messages.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: So if you're curious, stay tuned.

  • COLTON OGDEN: Cool, cool.

  • Next question, "how would you pass data from the client side,

  • e.g. a JPEG image, to Python Flask server and then return results?"

  • KAREEM ZIDANE: OK.

  • That's a different way of doing it.

  • Usually, when the data is binary like this,

  • it's the case that we make a POST request which

  • is the same kind of request that we're going to talk about.

  • And essentially, the data of this image or whatever

  • file you're trying to upload is sort of encoded as part of the request

  • when the browser makes that POST request.

  • We're not going to demonstrate uploading files today.

  • But it wouldn't be a part of the URL as is the case with get parameters here.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • It wouldn't be [INAUDIBLE].

  • COLTON OGDEN: Yeah, because that's part of the query stream, the get stuff.

  • And that's also stuff that you can't really put into--

  • I mean, you can binary encode information

  • and put that into a UTF encode information and put that into the URL.

  • But that's not typically how you see especially large data.

  • It's usually done through POST requests.

  • KAREEM ZIDANE: Yeah, I think URLs also have a maximum length.

  • COLTON OGDEN: Yeah, I would imagine.

  • Yeah.

  • KAREEM ZIDANE: So if you have a file that's

  • big enough, though, even if you encoded it,

  • it would be a problem to send as part of the URL.

  • POST requests might be handy in this case.

  • COLTON OGDEN: "Can we override routes," says [? Bavik ?] [? Knight. ?]

  • KAREEM ZIDANE: Can we overwrite routes?

  • In which sense?

  • We can have multiple routes.

  • I don't think we can have different functions for the same route,

  • because at this point that would be confusing for Flask, which function do

  • you want to run in this case.

  • So I can't have another function with the same route here.

  • COLTON OGDEN: And if you did, I would imagine

  • it'd be the bottom one that would take over, that would take precedence.

  • KAREEM ZIDANE: It could be.

  • Because it would overriding it in this case.

  • But in this case, it would be useless to have the first function

  • [? in the first place. ?]

  • COLTON OGDEN: It would.

  • It would.

  • It would.

  • [? Frame ?] [? of ?] [? Ref ?] says, "just to clarify,

  • is the request library part of Python or Flask?"

  • KAREEM ZIDANE: Yes, the request module is part of Flask in this case.

  • It's not a different, not a separate library or anything.

  • I just installed Flask up to this point.

  • All right, and the last thing that I wanted

  • to mention before leaving this example is this notion over here.

  • And this is actually part of the Python 3.6 syntax, which is a format string.

  • Notice, we have an F here, right?

  • And then this is the way I'm sort of injecting the value of the name

  • variable into my response.

  • COLTON OGDEN: The format string, one of my favorite Python 3.6 features.

  • KAREEM ZIDANE: Yeah, indeed.

  • COLTON OGDEN: Probably my favorite 3.6 feature.

  • I don't remember what else 3.6 added that I thought was really great.

  • KAREEM ZIDANE: It's really quite handy.

  • We're going to see a fairly similar syntax when we go into templating,

  • which I think starts the next example.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: Right.

  • Do we have any more questions so far?

  • COLTON OGDEN: We do.

  • So [? NACL ?] [? Eric ?] is asking, "is it possible to make an HTTP request

  • from a GUI, like Postman, if your app is being hosted on a Docker container?"

  • KAREEM ZIDANE: Yes.

  • And we're not going to dive into details about how Docker works in this case.

  • But, essentially, you can map ports from the Docker container into the host.

  • And it would be like the client wouldn't really care

  • where the app is hosted in this case.

  • COLTON OGDEN: As far as where it could be a server somewhere else?

  • KAREEM ZIDANE: Yeah, exactly.

  • COLTON OGDEN: Just a virtual server?

  • KAREEM ZIDANE: Exactly.

  • COLTON OGDEN: And then [? Aldu ?] is asking, "is there

  • a schedule somewhere of what you are going

  • to cover in the upcoming streams?"

  • We keep all of them as Facebook Events.

  • But, yeah, in the near future, we are going

  • to start integrating I think a schedule into Twitch itself.

  • But you can go to facebook.com/cs50.

  • And that's where we post all the events for all of our upcoming streams.

  • We also post them to our Reddit and our Twitter account,

  • facebook.com/cs50 and then reddit.com/r/cs50 if I'm not mistaken--

  • yeah, /r/cs50-- and then twitter.com/--

  • whoops.

  • There we go.

  • twitter.com/cs50, let me make sure that that is indeed accurate.

  • But the simplest way to do it is just to go to Facebook for now, facebook.com--

  • I can't type-- /cs50.

  • All of our [INAUDIBLE] are there.

  • All right, cool.

  • KAREEM ZIDANE: All right, that's great.

  • So the next example that we're going to dive into involves some templating.

  • Flask, by default, has as part of it a templating engine called Jinja.

  • And we're going to explore a little bit of the syntax for Jinja today.

  • So this following example is a little bit more complicated

  • than the previous one.

  • The first thing that we have here is our routes on slash that's

  • handled by rendering a template apparently called index.html.

  • COLTON OGDEN: And this is what Nate was referring to, Nate

  • being [? whipstreet23 ?] when he asked about render template

  • taking a message parameter.

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: In this case, rendered template

  • looks like a URL or an actual HTML page that we

  • might have they we want to serve people, but also takes

  • in some other information.

  • KAREEM ZIDANE: Yeah.

  • And let we actually clarify why templating would be useful in this case

  • or in general.

  • So if you have a website of some sort and you have a bunch of pages,

  • every HTML page ideally should start by-- let's open a sample one here.

  • It should start by something like doc type, html, you know,

  • whoops, html, and then html closing tag.

  • And then we have a head.

  • And you'll have a body.

  • And you'll have a bunch of other things inside of the head maybe and so on.

  • And so it'd be really boring to sort of keep copying and pasting this

  • into every page that you have.

  • Another thing is that if you want to change something,

  • if you want to add a script or if you want

  • to add a link, a CSS somewhere, or rather in all of them,

  • you'd have to copy and paste that into every page that you have.

  • And so templating sort of solves this problem

  • by essentially allowing you to have one base

  • file that you sort of inherit from and sort of plug in certain parts

  • as we'll see.

  • COLTON OGDEN: It's kind of a common paradigm in, I think,

  • software development in general--

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: --composable parts, inheritance,

  • like these sort of concepts I think.

  • We even use this in the game streams, for example.

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: State machines, we did that

  • with state machine example with a base state

  • that other states can inherit from to get functions that they don't

  • have to override themselves, right?

  • They just copy the functions from other states.

  • KAREEM ZIDANE: Yeah.

  • I mean, inheritance in the context of object-oriented programming

  • is a little bit different here.

  • Because you can think of it the same way that you think of a pre-processor,

  • a C preprocessor.

  • It just literally, you know, pastes your stuff from the base file

  • and then plugs into the stuff that's [INAUDIBLE]..

  • COLTON OGDEN: Yeah, definitely a simpler implementation here, but yeah.

  • KAREEM ZIDANE: All right, so by default, Flask

  • expects all of our templates to be inside of the templates folder.

  • So I'm going to go into that folder.

  • And I'm going to open the base HTML file that I have.

  • And it looks like this.

  • It's called the layout.html.

  • And it looks like this, has all the parts that we need for any HTML file

  • in general, the doc type, the HTML, the head, the body, and so on.

  • And it also has this sort of curly brace curly brace notation.

  • And this is actually a Jinja specific syntax.

  • This actually says, you know, if there is a keyword argument passed

  • into render a template whose name is title,

  • replace its value here, or plug in its value here.

  • And so let me go back up here.

  • And I'm not sure if that's--

  • can I make this a little bit smaller, so that we can see?

  • Maybe put it up?

  • COLTON OGDEN: Oh, yeah.

  • We can probably mess with the chat and make it a little smaller.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: We can do that.

  • Whoa.

  • Hey, there.

  • KAREEM ZIDANE: All right.

  • COLTON OGDEN: It's just briefly, make it small just briefly.

  • KAREEM ZIDANE: So in the render template call here that I called,

  • I passed in a keyword argument called title.

  • And I passed in the value Homepage in this case.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: So this essentially says that, hey,

  • if there is a keyword argument called title

  • passed to render template, replace its value here, or plug in its value

  • at this very same location.

  • And this location happens to be the title of our page in its case.

  • COLTON OGDEN: So this is like the precursor to really getting us

  • into a more dynamic sort of web content.

  • KAREEM ZIDANE: Correct.

  • Yes.

  • And so as you can imagine, different calls to render a template,

  • as you mentioned, can receive different values for the title parameter.

  • COLTON OGDEN: Even if it takes in a name, hello Kareem versus hello Colton,

  • that's technically a dynamic webpage.

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: To answer a couple questions in the chat, too, also--

  • [? Giban3 ?] said, "I used to do the same thing with PHP,

  • making a header and footer and then having the PHP call it in."

  • Yeah, that's kind of what we're doing here.

  • KAREEM ZIDANE: [INAUDIBLE]

  • COLTON OGDEN: Well, I mean, it's an idea of what we're doing.

  • Because it's sort of what we're leading to, right, having a header and a footer

  • that we can inherit from template?

  • KAREEM ZIDANE: Oh, yeah.

  • Yeah, yeah.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: [INAUDIBLE]

  • KAREEM ZIDANE: Yeah, you can pretty much do that as well.

  • COLTON OGDEN: And then [? Andre ?] was saying, "templating

  • is closer to generic programming."

  • So templating in C++ is not the same thing as templating templates in Jinja

  • or Flask.

  • In this case, these are just kind of like pre-created documents

  • that we inject variables into.

  • Templating in Java or-- it's called generics in Java-- templating in C++,

  • those are functions that can take very adic arguments of different types.

  • And they get compiled into multiple different--

  • how do I want to describe this?

  • They get compiled into multiple versions of the same function that

  • can take multiple data types.

  • And this is done at compile time.

  • And then template meta programming is related to that,

  • that same thing in C++ where you can, at compile time,

  • basically generate a compute table or a lookup table for a series of functions

  • and their outputs, and then get insane performance boost that way,

  • especially in games programming where you're calling a function maybe

  • hundreds of times or rather not hundreds of times a second--

  • well, I guess hundreds of the times a second.

  • No, I guess you couldn't be doing hundreds of times in a second.

  • Hundreds of times in a loop maybe over the course of a couple of frames

  • or whatever, this is kind of where you'd use templating.

  • But it's, yeah, completely separate I think from this domain,

  • but the same name templating.

  • Not--

  • KAREEM ZIDANE: Can be [INAUDIBLE].

  • COLTON OGDEN: --synonymous, but very, very different use cases, same word.

  • And [? Belacures ?] is asking, "if we don't mention any methods in the route,

  • will Flask answer only to a get request?"

  • KAREEM ZIDANE: That is correct.

  • And we're going to explore the methods parameter to the decorator here.

  • But, yeah, if I just say app.routes/, this is expecting only get requests.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And so what this means, if I

  • try to send another kind of request or if the browser tries

  • to send another kind of request, the server

  • is going to hopefully respond with some error code.

  • In this case, I think it's 405, method not allowed or something.

  • COLTON OGDEN: Makes sense.

  • And lastly, [? Adam ?] [? Fighter ?] says,

  • "templates in Jinja2 are like Python format strings on steroids."

  • KAREEM ZIDANE: Yes, kind of.

  • They're a little bit fancy, a little bit more complicated,

  • because they involve some sort of logic in them that we'll see.

  • COLTON OGDEN: True.

  • KAREEM ZIDANE: But the idea is the same, that you have some base.

  • And then it has some variables that you can sort of plug into,

  • and it just becomes different.

  • All right, the next interesting piece here, or snippet I should say,

  • is the block some word end block in that very same syntax, so curly brace, %,

  • block, name, %, and so on.

  • And so what this does is actually says that, hey,

  • the templates that are going to extend or inherit from this base

  • can essentially define a block.

  • And the contents of this block are going to be inserted here.

  • So let's actually take a look at one of these templates.

  • So let's take a look at index.html.

  • And the first line in index.html is that it extends layout.html,

  • the file that we just looked at.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • COLTON OGDEN: So it's going to inject the body block sort

  • of into that-- layout.html is kind like a template

  • that we're saying, we're going to put our own block,

  • our own custom block, into this place holder for a block, right?

  • So in this case, block body and then the actual layout

  • defines body and then gets injected into it, right?

  • KAREEM ZIDANE: Yup, exactly.

  • COLTON OGDEN: Or index.html.

  • KAREEM ZIDANE: In this case, everything from layout.html

  • is going to be included in index.html.

  • And the place where this line over here is

  • going to be replaced with the contents of this--

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: --which is this line over there.

  • COLTON OGDEN: It's pretty cool.

  • We don't have to write all the HTML head, title, all that stuff--

  • KAREEM ZIDANE: Nope.

  • COLTON OGDEN: --in index.html.

  • We're only literally just writing what the body is that we care about.

  • KAREEM ZIDANE: Yeah.

  • And that's the beauty of templating.

  • It makes this stuff really easy.

  • COLTON OGDEN: "Completely unrelated," says

  • [? Webstreak, ?] "how do you check if a text box in HTML

  • is empty using JavaScript?"

  • I pulled it up here, because I didn't recall offhand.

  • But it looks like with JavaScript you can do it

  • pretty easily just by checking if an element's value dot

  • length is equal to zero.

  • to see exactly.

  • Oh, would it be document.get element by ID and then the input or whatever?

  • I'm trying to find an actual robust thing here.

  • Yeah.

  • KAREEM ZIDANE: Definitely do google this stuff, though.

  • It can be really handy when you run into a question like this.

  • Don't block yourself.

  • COLTON OGDEN: Yeah.

  • Yeah.

  • Like what I did was I typed into Google.

  • I just basically typed in "check text box html empty."

  • And using something like document.get element by ID or using jQuery.

  • You might have seen the $ library using whatever selector for your text box.

  • So if you get an ID of text box, you can check it by the ID

  • by passing in the string with a hash symbol.

  • And then you can basically check to see if value dot length

  • on that is equal to zero.

  • And that will mean that it has no characters typed into it, in which case

  • it's empty.

  • KAREEM ZIDANE: All right.

  • OK.

  • So let's actually take a look at how this looks.

  • So let me run my server again.

  • It's Flask, right?

  • Flask, OK.

  • So let me reload this page.

  • And this is what I see.

  • And just to be clear, let's get back to--

  • what is it--

  • Flask stream bash.

  • And let me go into Flask stream.

  • I think we're an app2.

  • So this is what I have in my template at the bottom here, right?

  • This is not really interesting.

  • So let's-- yeah.

  • OK.

  • So this is what I have here, same thing.

  • All right, so the idea of this--

  • COLTON OGDEN: Very sophisticated, by the way.

  • KAREEM ZIDANE: Yeah, thanks.

  • The idea of this simple web app is that it should

  • allow us to sort of register users.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • Ideally, databases are used for this.

  • We're not going to use a database today.

  • Maybe in a future stream we can talk more about database.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: I believe David had a SQL streams sometimes?

  • COLTON OGDEN: Yeah.

  • We had like a SQL basics kind of stream where we just

  • kind of talked about the syntax.

  • And SQLite, I believe, is what we used.

  • But doing something like Mongo or MySQL in the future would be pretty cool.

  • KAREEM ZIDANE: Yeah.

  • So in this case today, we're not really going to dive into any database stuff

  • just to make it simple.

  • And what we're going to use instead is a CSV file.

  • And a CSV file is essentially a simple text file with comma separated values.

  • So I can have a file called users.csv in this case.

  • I can say that, hey, the first column is going to be the user name.

  • The second column is going to be the password.

  • And so I can have something like your username.

  • Is that correct?

  • Is that correct?

  • COLTON OGDEN: Yeah, cogden.

  • Yeah.

  • KAREEM ZIDANE: OK.

  • All right?

  • And then your password is 123.

  • COLTON OGDEN: Yup.

  • My real password, too.

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: There you go.

  • You got it.

  • KAREEM ZIDANE: And then another user name,

  • and then another password, and so on.

  • COLTON OGDEN: Oh, you and I use the same password.

  • KAREEM ZIDANE: Yeah.

  • That's a coincidence.

  • COLTON OGDEN: It's probably not very secure.

  • KAREEM ZIDANE: I should try this on your account sometime.

  • All right, so the idea of registration in this case

  • is that it would take some data from the user,

  • and then it would essentially insert a row or a line into this Text file

  • in this very same format.

  • COLTON OGDEN: Yup.

  • KAREEM ZIDANE: Right?

  • COLTON OGDEN: Using a very simple database.

  • KAREEM ZIDANE: Yes, correct.

  • So let's actually look at this page here, Register.

  • And in this page, it's another template called Register.

  • And it has this very similar structure to the index.html page.

  • It also extends layout.html.

  • It also fills in the body block in this case.

  • But this time, it fills it up with a form that's

  • going to be submitted to register.

  • And I believe you talked about this in your HTML stream, video forms?

  • COLTON OGDEN: We talked about it very briefly.

  • That was actually the last part before we kind of had to cut it short.

  • KAREEM ZIDANE: Cool.

  • COLTON OGDEN: We didn't really get into the nitty-gritty of it,

  • but we talked about kind of like username, password, and then buttons

  • and stuff like that.

  • KAREEM ZIDANE: So, yeah.

  • COLTON OGDEN: We really get into details of like POST and GET and all that.

  • KAREEM ZIDANE: Essentially, we have a form here.

  • And this form is going to be submitted to /register.

  • And we're going to take a look at this code after this.

  • This form is actually going to be submitted using the POST request

  • method as opposed to GET.

  • COLTON OGDEN: Yup.

  • Completely different, right?

  • KAREEM ZIDANE: Right.

  • So, again, the main difference between including HTTP parameters or variables

  • in a GET request versus a POST request is

  • that, when you include HTTP parameters in a GET request,

  • they appear as part of the URL.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: But when you do that using a POST request,

  • they're actually encoded as part of the request [INAUDIBLE]..

  • COLTON OGDEN: So you probably don't want to put your password as a Get,

  • you know?

  • KAREEM ZIDANE: Correct.

  • So form submissions, usually, that includes things

  • like user names, and passwords, and files,

  • and other stuff are not typically submitted using GET.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: They're submitted using POST.

  • But what's a common form that submitted using a GET request?

  • COLTON OGDEN: A common form?

  • I guess it would be, yeah, like a search I guess.

  • KAREEM ZIDANE: Yeah.

  • So Google, for example, this essentially is a form with one text field

  • and, you know, a couple of buttons or whatever.

  • And I can search for cats.

  • And if we ignore all the stuff-- actually, you know what?

  • Let's redo this.

  • So I bet if you look at this whole URL, you're eventually going to find

  • something like q=cats.

  • And it shows the same thing essentially.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: Right?

  • So this is a form that's submitted using a GET request.

  • COLTON OGDEN: GET request, right.

  • Because we're not sort of including any really

  • personal identifying information--

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: --that we need to keep secret.

  • It's kind of all--

  • KAREEM ZIDANE: Exactly.

  • And it's not just--

  • well, I guess it is the same thing.

  • It is mainly because of the secrecy.

  • But, also, I don't really want to clutter my history

  • with all this different values of some sort of files that I have uploaded.

  • Or, you know, I don't want to record my password to be in history permanently.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: So that's kind of a bad thing to do.

  • COLTON OGDEN: To [? Andre's ?] point, yeah, I mean,

  • templating in this sense and templating and C++ are slightly similar in that

  • there's some plug and play of things, like injection of, I guess--

  • in case the templates, you're placing some place holder with actual data.

  • And you're doing the same thing with templates in C++.

  • But in C++, you're doing it across multiple different potential use cases.

  • And you're sort of creating a table of multiple things,

  • whereas in Jinja you're just injecting it once,

  • and then processing it, and then returning that one result, right?

  • The purpose of sort of generic programming

  • is to make it possible and more flexible to program with certain data types.

  • And in templating, it's to basically save you

  • from rewriting the same thing over and over again and to kind of just

  • make whatever parts you want dynamic easy to change, right?

  • [? Adam ?] [? Fighter's ?] asking, "can you talk a bit about AJAX async calls

  • with Flask-- for example, typing a name into a text box and having it print

  • instantly without refreshing the page?"

  • KAREEM ZIDANE: I don't think we're going to cover this today unfortunately.

  • But AJAX will be an interesting thing to discuss on a future stream as well.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: But the idea is that if you have a back end written

  • in Flask or whatever, as we saw in the first couple of examples,

  • we can return essentially any kind of data.

  • So we happen to have returned a string.

  • But you return a string that's formatted as JSON

  • and then parse this on the JavaScript side of things,

  • and then use it as a JavaScript object.

  • And this is how, you know, we can dive deep into REST APIs and such.

  • COLTON OGDEN: Yeah.

  • You'd need a REST API to be able to authenticate, get the information back

  • from the server, and update the page unless you

  • wanted to do it in pure JavaScript.

  • But you still need the authentication to know that that user is actually

  • a legitimate user and not just some random person typing their username.

  • It's a fairly complicated.

  • But, yeah, I think--

  • KAREEM ZIDANE: If we do have enough time,

  • we can demonstrate a quick example on how that works.

  • But I don't have it in the examples that I have pre-prepared.

  • COLTON OGDEN: [? In ?] [? The ?] [? Ready ?] asked,

  • "what's the difference between request.form name and request.form.get

  • name?

  • KAREEM ZIDANE: request.form name and request.form.get name?

  • I mean, my guess--

  • I have to look at a documentation for this.

  • I'm not sure if the parameters will be available on the request objects

  • right away, like directly.

  • I'm not sure if you would be able to access them this way.

  • But if you are, it could be the case that GET

  • allows you to specify this sort of default value, for example.

  • So I have to look at the documentation for this one and see if that's accurate

  • or not.

  • COLTON OGDEN: "Can we do functionality for the password?

  • Like when we try sudo, we can see only one bullet, so someone looking over

  • can't guess the length of the password?"

  • Like limit the number of characters that the password field reveals to us?

  • KAREEM ZIDANE: Definitely, yes.

  • I believe you can do this using a script maybe or using maybe

  • something built-in attributes into HTML if there

  • is such an attribute that exists.

  • COLTON OGDEN: Yeah, there probably is.

  • I haven't actually looked into it, but I would

  • google "password limit number of characters, limit

  • number of visible bullets" or whatever.

  • And there's probably a ton of stack overflow snippets

  • that you could copy and paste.

  • Cool.

  • KAREEM ZIDANE: All right, so do you have any more questions?

  • COLTON OGDEN: No.

  • I think we're all caught up.

  • KAREEM ZIDANE: OK, cool.

  • So this form, as you see here--

  • let's get rid of this--

  • has two text fields essentially.

  • One of them is a plain text field and one of them a password field.

  • And a Submit button, these are what I have here.

  • And the idea is that when I submit this form the data from this form is going

  • to be submitted to the /register route as we see here.

  • And the parameter names in this case are going

  • to correspond to the input element names here.

  • So I'm going to have ideally a parameter called user name and a parameter

  • called password here.

  • All right, so let's actually try this out.

  • So right now, let's actually verify that the file that I have is empty.

  • It's completely empty, doesn't have any data in it.

  • So if this works as expected, I'm going to sign up myself with some password.

  • COLTON OGDEN: Probably not 1234.

  • KAREEM ZIDANE: Exactly.

  • And this is, of course, an internal server error.

  • COLTON OGDEN: Oh, man, internal server error.

  • KAREEM ZIDANE: Because something--

  • OK.

  • User name zero is out of range.

  • So let's look back in the code.

  • And do some live debugging.

  • It's really hard to see--

  • COLTON OGDEN: Oh, man.

  • It's my favorite kind of debugging.

  • KAREEM ZIDANE: Yeah.

  • You know what?

  • Let me do this.

  • Let me make this vertical so that I can see it better hopefully.

  • Flask stream bash, and then we're going to do some live debugging here,

  • so pardon us.

  • OK, app2.

  • COLTON OGDEN: Some live debugging, AKA, stack overflow.

  • KAREEM ZIDANE: Yeah.

  • [INAUDIBLE]

  • And what was the error on line 33?

  • COLTON OGDEN: The list index out of range, row zero is equal to user name.

  • So line 33, yeah.

  • KAREEM ZIDANE: Oh, interesting.

  • OK.

  • I know why this is happening.

  • I think, because I [? truncated ?] the file the wrong way.

  • So the file is technically not empty.

  • The file that we saw right here technically has a blank line.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: Right?

  • COLTON OGDEN: But it's not going to have rows that you can parse.

  • KAREEM ZIDANE: Exactly.

  • And so I think one way you can get around this is by doing this.

  • So, now, it's empty.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • So let's try this again.

  • Let me go back to Register.

  • Let me do this again.

  • OK.

  • That worked.

  • COLTON OGDEN: Nice, cool.

  • KAREEM ZIDANE: It doesn't show anything useful.

  • It shows me the Index page again.

  • COLTON OGDEN: Right, yeah.

  • KAREEM ZIDANE: But let's check the file one more time.

  • Whoops, users--

  • COLTON OGDEN: Oh.

  • Nice.

  • KAREEM ZIDANE: There's my [INAUDIBLE].

  • There's my password.

  • COLTON OGDEN: Spoiler alert, password 123.

  • KAREEM ZIDANE: Exactly.

  • That's something you should never do, actually.

  • Never store passwords in plain text like this.

  • COLTON OGDEN: Yeah, encrypt them.

  • Yeah.

  • KAREEM ZIDANE: Exactly.

  • They are usually sort of encrypted, as you mentioned, or hashed,

  • and then stored as a hash.

  • So that if anyone gets access to this file or your database,

  • ideally, they wouldn't know what this password is actually in plain text.

  • But for simplicity today, we're not really going to talk about hashing.

  • We're just going to store it has a plain password.

  • And let's actually verify that this works by registering another user.

  • And let's say, you know, [? Aaron, ?] for example, in this case and some

  • password.

  • And then, you know, verify this again.

  • We have [INAUDIBLE].

  • COLTON OGDEN: Much more secure password than your password.

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: It's still pretty easy to brute force though.

  • KAREEM ZIDANE: Correct.

  • All right-- so kind of interesting.

  • What can we do with this, though?

  • Like, what can we do next?

  • COLTON OGDEN: Oh, man.

  • Could go a whole kinds of different directions.

  • KAREEM ZIDANE: Exactly.

  • So, now, I'm keeping track of some user data.

  • I should ideally allow them to log in or, you know, hopefully show them

  • that they are logged in or not.

  • And that's what we're going to do next.

  • And so let me go into it app3.

  • And this is going to be a bit more complicated

  • than the previous example, of course.

  • It builds on top of it.

  • And we're going to talk about it one part of the time.

  • So the first thing that we need to do is actually run the server here.

  • So Flask, OK--

  • OK.

  • So I'm using a library here called the Flask-Session.

  • We're going to talk about the sessions soon.

  • But I'm using a library called Flask-Session to keep track of,

  • you know, if the user's logged in or not.

  • And this library actually needs to be installed separately.

  • And so to do this, I'm going to do like I did last time with Flask,

  • but in this case pip3 install flask-Session like this.

  • And it should hopefully install without any problems.

  • OK.

  • I think this is done.

  • COLTON OGDEN: [INAUDIBLE] your terminology is just so small now.

  • KAREEM ZIDANE: Yeah, somewhere I can see anyway.

  • OK.

  • All right, so now I'm running the servers, no problems, which is good.

  • It looks a little bit different.

  • The layout file is pretty much the same.

  • There's a couple of things that are different that I'm going to show.

  • Index file is mostly also the same, except that--

  • let's actually look at it.

  • So tabf templates index.html--

  • so it extends index.html like the previous one,

  • except that it has some sort of logic here.

  • First of all, it checks.

  • If there is a user name, then show hello and that user name and then

  • show a log-out link, right?

  • Otherwise, show hello there and show a log-in link or a register link.

  • And this is what I'm seeing right here, because I'm not logged in.

  • Makes sense?

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: OK.

  • So let me try to register myself, because this

  • is a different application.

  • We don't have the same file here.

  • So let's do this.

  • And hopefully, it won't show the 500 again.

  • Because it might be the same file.

  • OK, good.

  • So now when I click Register, what actually

  • happens is that it shows me back that, hey, hello user name, KZidane, my user

  • name, and then a log-out link, right?

  • And if you look at the file again, we'll find

  • the row that corresponds to my user.

  • So what actually happened here?

  • So when the form data was submitted to register,

  • what actually happened is that--

  • let's ignore this first part for a second.

  • We should've covered this in a previous example, actually,

  • but I forgot to do that.

  • So let's actually talk about it here.

  • So the first thing that happens is that if we

  • get a get request, what's going to happen

  • is I'm going to render the register template with the title register,

  • right?

  • And this does something as simple as rendering the registration

  • form that we saw, right?

  • Otherwise , which means if you get a POST request,

  • we are going to try to get the user name from the form.

  • We're going to try to give the password from the form.

  • And then we're going to ensure that these actually have some value in them,

  • right?

  • They're not either missing or have an empty value like it did before.

  • And if that's the case, we're going to abort with HTTP status code for 400.

  • COLTON OGDEN: Right?

  • So that's not a not found error.

  • This is a different error in this case.

  • KAREEM ZIDANE: Correct.

  • So 400 is actually a bad method or a bad request error--

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: --and some useful description to show the user.

  • COLTON OGDEN: Which means we didn't give it the right information,

  • the POST request was missing some piece of information

  • correct and then we're going to ideally the user gets the row that

  • corresponds to this user name, right?

  • And if there's no such row, that users--

  • actually, so it gets the row that corresponds with this user name.

  • And if such row exists, that means that we have this user name from before.

  • So we can't re-register it again.

  • And in this case, we return another 400 with a different descriptive message

  • hopefully.

  • And then after that, if all our checks passed,

  • we start by inserting a row into the user's file that essentially

  • consists of the user name and password.

  • COLTON OGDEN: OK.

  • Got it.

  • KAREEM ZIDANE: All right.

  • COLTON OGDEN: Makes sense.

  • I think we have a couple things in the chat here as well

  • KAREEM ZIDANE: OK.

  • COLTON OGDEN: Yeah, no. [? Andre ?] was clarifying about C++ templates.

  • Yeah.

  • I think I mean I think that the terminology is fairly similar.

  • But, again, I think the difference between things like templates in C++

  • versus Flask is that C++ is creating an entire lookup table of functions,

  • whereas Flask, its goal is to distribute just one bit of information that gets

  • rendered to you.

  • But, yeah, in the same sense that you're injecting sort of place holder values

  • and then generating some block based on that, yes, the terminology is similar.

  • "Are we going to cover Django," says [? JL97. ?] Not today.

  • Maybe in a future stream we might cover Django, but today is just on Flask.

  • And saltyglowstick was saying, they did some research on why app is equal

  • to Flask__name.

  • And it was saying the __name variable provides the name of the package.

  • And then Flask uses this value to find out what the location of the package

  • is on disk, so it can locate other files in the same directory.

  • KAREEM ZIDANE: That is correct.

  • I mean, we're not really going to care about this right now,

  • because we're not trying to find files by location relative to this package

  • name or relative to the module name that we're using right now.

  • But that is a correct explanation I think.

  • COLTON OGDEN: "I really like these examples.

  • Where can I find them?"

  • And then [? Bela ?] actually linked to your--

  • this is correct, right, kzidane/flask-stream?

  • KAREEM ZIDANE: Yup, that is correct.

  • COLTON OGDEN: That's today's code.

  • Yeah.

  • So if you want to follow along with all these examples,

  • follow the link that's actually hidden right now.

  • Oh, Kareem is going to plug it right here in the chat.

  • KAREEM ZIDANE: ://github.com/kzidane/flask-stream.

  • COLTON OGDEN: Nice.

  • KAREEM ZIDANE: All right.

  • COLTON OGDEN: So check that out, clone that.

  • It will be good.

  • And then lastly, "is there a session on deploying using Docker?

  • He should cover it in a different class, Docker session."

  • And then, actually, yeah, we did.

  • David and I did a very brief Docker tutorial, not very brief I should say.

  • KAREEM ZIDANE: But I think he's asking about deploying

  • [INAUDIBLE] applications using Docker.

  • COLTON OGDEN: Oh, I see.

  • Yeah.

  • KAREEM ZIDANE: So containerizing [INAUDIBLE] applications maybe

  • [INAUDIBLE]?

  • COLTON OGDEN: I don't think we covered that, but, yeah, maybe in the future.

  • Something like that.

  • KAREEM ZIDANE: Yeah.

  • Maybe we could demonstrate that using Heroku or Elastic Beanstalk

  • or something.

  • COLTON OGDEN: Yeah, that could be useful to some people I think certainly.

  • KAREEM ZIDANE: All right, so this part that I just explained in the register

  • function is exactly the same as the previous example, which

  • I forgot to explain.

  • The extra part is actually remembering that the user is logged in or not,

  • which didn't happen the previous example.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And for this, we're going to use something called a session.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: And so the way a server remembers

  • whether some user is logged in or not is by sort of giving them

  • a unique identifier when they log in.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: Right?

  • So in the response, it gives them a unique identifier, a cookie, right?

  • And then when the browser tries to make another request to the same server,

  • by default, it tries to send that cookie.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • And so the server gets that cookie again, gets that identifier again,

  • and knows that, hey, this belongs to this user.

  • And so it retrieves all the information about them

  • and shows that they are logged in in this case

  • and greets them with their user name.

  • And so the way to initialize a Flask [INAUDIBLE] session is really simple.

  • So from Flask, we should import session, as we see here.

  • Right?

  • And then the package that we were using is actually Flask-Session, right?

  • And then we're going to import Session with a capital S here.

  • And then we're going to instantiate this Session class that we imported

  • and then pass it app.

  • And so this is the way we initialize the session

  • in this case or Flask [INAUDIBLE] using sessions in this case.

  • There's also a couple of session configurations in this case.

  • I'm using my file system as opposed to-- so I'm not storing,

  • essentially, the data on the client side or on the user's computers

  • or the user's devices.

  • I'm storing the data actually on my server on my file system

  • and distributing some kind of unique identifier

  • that sort of references this data.

  • And I just don't want my session to be permanent.

  • I don't want them to last forever in this case.

  • COLTON OGDEN: Also, thank you for--

  • I don't know if I'm pronouncing this correctly--

  • [? Frefa ?] or [? Fr3Thou, ?] Treet_top and codekip, thank you very much.

  • KAREEM ZIDANE: And so a session essentially ends

  • up being a simple Python dictionary, right?

  • And so to insert a value in that dictionary,

  • we just use the bracket notation.

  • In this case, we're inserting a key called user

  • name with a value user name.

  • But, ideally, you can remember pretty much anything here.

  • You can remember their ID instead if we have such thing.

  • Unfortunately, we don't use an ID here.

  • But, ideally, that's the thing that's remembered,

  • a numeric number that identifies a user, right?

  • After remembering that the user is logged in after they register,

  • we just redirect them back to index.

  • And when they go to index, this is what's going to happen, right?

  • Let's actually take a look first at the index function.

  • And the index renders the index template,

  • passes in the title, like last time, and then passes in a user name

  • from the session.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: So if there's a user name in the session,

  • this is going to be the value of this keyword argument.

  • Otherwise, it's going to be none, right?

  • And this is what it checks for.

  • If the user name exists, show this specific greeting.

  • Otherwise, show the log-in or register message.

  • Cool?

  • COLTON OGDEN: Makes sense, makes sense-- lot of session import worries

  • in there, three different ones.

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: It's pretty funny.

  • KAREEM ZIDANE: All right.

  • COLTON OGDEN: [? Jiban ?] was asking, "are you

  • going to cover the security issues of sessions?"

  • KAREEM ZIDANE: Am I going to cover the security issues of sessions?

  • Not really.

  • I believe [? Theodore ?] mentioned once on one of the streams,

  • I mean, probably the most common security issue with session

  • is called session hijacking.

  • And this happens by means of stealing someone's cookies and using them.

  • COLTON OGDEN: Using them to authenticate the server.

  • KAREEM ZIDANE: And so you appear to that server as that person, but you're not.

  • COLTON OGDEN: Makes sense.

  • KAREEM ZIDANE: So we're not really going to go

  • into much more details about this.

  • But this is the basic idea of hijacking.

  • COLTON OGDEN: If anybody wants to try and steal Kareem's cookies--

  • KAREEM ZIDANE: Yeah, feel free to.

  • All right, so the log-out function, which happens here when we visit

  • the /logout, just clears the session, so forgets that the user is logged

  • in and, therefore, logging them out.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • So it's as simple as that and then redirects back to the Index page.

  • Show I click this link, I should see the message that

  • appeared if no one is logged in again.

  • COLTON OGDEN: Correct.

  • KAREEM ZIDANE: All right.

  • COLTON OGDEN: [INAUDIBLE] says, "thank you very much for the follow-up."

  • And then [? Andre ?] was making a joke.

  • "Stealing someone's cookies?

  • What are they, monsters?"

  • Because Cookie Monster.

  • KAREEM ZIDANE: Yeah, well.

  • COLTON OGDEN: "Can you use JS frameworks with Flask" says [INAUDIBLE]??

  • KAREEM ZIDANE: In what sense?

  • I mean, I know Flask probably has a JavaScript

  • framework that sort of wraps some functionality

  • in like the URL for something.

  • I haven't used them much.

  • But, yeah, I'm not going to use any today unfortunately.

  • COLTON OGDEN: If they're referring to maybe using Flask and JavaScript

  • together just in the normal sense, then you

  • can use JavaScript with any back end framework?

  • KAREEM ZIDANE: They're just run in different contexts.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: So the Python code that you have is actually

  • a run on the server side, but the JavaScript code is actually

  • run on the client side or inside of your browser or something.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: But, yes, I mean, if you're

  • referring to any JavaScript framework or any JavaScript code in general,

  • there should be no problem using that with a Flask application in this case.

  • COLTON OGDEN: People are saying that, recently, there

  • was the cookie session hijacking with Facebook, [INAUDIBLE] brought that up.

  • And then some other folks were mentioning that as well.

  • KAREEM ZIDANE: Yeah.

  • I mean, some of these issues happen from time to time.

  • And you should definitely be careful about that.

  • The stream is not, unfortunately, on security.

  • So we're not going to dive too deep into it.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: But it's definitely an interesting thing

  • to look into and see how you can protect yourself like from exploiting yourself

  • to such attacks.

  • COLTON OGDEN: And Bagelcrush, thank you very much for following as well.

  • KAREEM ZIDANE: Thank you.

  • COLTON OGDEN: Cool.

  • KAREEM ZIDANE: All right, so let's take a brief look at the get user function

  • that we referred to earlier.

  • And this is just a helper function that essentially

  • opens the CSV files, reads in the rows.

  • And if it found the user name in one of these rows, it returns that row.

  • And that's it.

  • And so you could get fancy with CSV files

  • and use like a sorted dictionary or DictReader or DictWriter

  • and sort of refer to these by row user name or row password if you want.

  • I'm not going to do that here.

  • Again, typically, CSV files are not used for this kind of use case.

  • We're just using them for simplicity.

  • So I'm just going to go with numeric indices in this case.

  • COLTON OGDEN: xyZed92 and ml_newb, thank you very much for following.

  • KAREEM ZIDANE: Cool.

  • All right, so now that we have a web application that

  • allows us to register or log in or log out, what should we do next?

  • COLTON OGDEN: Well, then you'll see separate information

  • when they're logged in, right?

  • Are we showing their name so far?

  • KAREEM ZIDANE: Are we showing their name so far?

  • Yes.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: This should be like when they log in.

  • I forgot my password.

  • It's 123, I guess?

  • COLTON OGDEN: Hard password to--

  • OK.

  • So that's working.

  • KAREEM ZIDANE: Yeah.

  • They should see yours once they log in.

  • COLTON OGDEN: So I guess maybe some other--

  • so I guess whatever the goal is of this application, which was--

  • KAREEM ZIDANE: Right.

  • We're probably not going to transition to app4,

  • which is I think the last example in this stream.

  • But I just wanted to mention quickly that--

  • let's see.

  • I think we talked about all of these except log-in.

  • Log-in, essentially, is the same as register,

  • except that it actually gets submitted to the /login route.

  • And the button is called the Log-in instead of Register, of course.

  • And if we look at the log-in function or the function that handles this /login

  • route, it's also pretty much the same as register as well.

  • If you receive a GET request, it would render the log-in template.

  • Otherwise, we get the user name and password from the form

  • and validate them doing some sort of validation,

  • check that we have a record of a user, and check that actually their password

  • matches in this case.

  • And then if everything is OK, we just remember them in the session

  • and redirect them back to index.

  • COLTON OGDEN: Cool, sounds good.

  • KAREEM ZIDANE: Otherwise, be sent a 403, which is unauthorized.

  • COLTON OGDEN: What is it, invalid user name and password?

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: Unauthorized?

  • KAREEM ZIDANE: Yeah.

  • I'm trying to remember the control.

  • COLTON OGDEN: Unauthorized makes sense.

  • That sounds like something that they would write.

  • KAREEM ZIDANE: So this is another HTTP status code that we can send in case

  • the user is trying to do something that they're not

  • authorized to do right in other words.

  • COLTON OGDEN: Right.

  • [INAUDIBLE] was saying, "use bcrypt for your passwords."

  • KAREEM ZIDANE: Yes.

  • You could use any hashing.

  • I'm not familiar with bcrypt.

  • But you could use any sort of hashing libraries.

  • And I think by Python has actually built-in hashing mechanisms.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: So you can pretty much do that.

  • I just didn't want to complicate things, to try

  • to focus more on Flask side of things.

  • COLTON OGDEN: Oh, it's forbidden is what 403 is.

  • KAREEM ZIDANE: Forbidden, yes.

  • Not unauthorized, it's forbidden.

  • Thank you.

  • COLTON OGDEN: [? JL97, ?] "how would you prevent against CSRF forms?"

  • KAREEM ZIDANE: OK.

  • So people are trying to drag this into--

  • COLTON OGDEN: Cross-Site request Forgery, I

  • believe that's what that short for.

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: Flask has a module for that, doesn't it?

  • Or like a built-in feature for that, CSRF?

  • KAREEM ZIDANE: I think some browsers--

  • OK.

  • So there are different ways to protect against these kinds of attacks.

  • I think some browsers have some built-in mechanisms

  • of sort of preventing some JavaScript from some other origin or domain

  • to be executed on your domain.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: so I'm not sure if this is a different kind of attack or not,

  • but some web apps sort of include a unique token

  • in the form to be submitted that's valid for a specific duration or something.

  • So they use that as well.

  • Does Flask have something built-in to [INAUDIBLE]??

  • COLTON OGDEN: Yeah.

  • It looks like there's a Flask WTF, interestingly enough.

  • KAREEM ZIDANE: What The Form.

  • COLTON OGDEN: Yeah, What The Form--

  • which has a .CSRF.

  • And you can import CSRF protect.

  • And then you have to instantiate that.

  • You have to wrap your app around that basically just how you do a session.

  • KAREEM ZIDANE: Yeah.

  • Yeah.

  • I mean, I have to look into this more honestly.

  • But I believe it injects some kind of hidden sort of input

  • with some unique value that it then verifies,

  • so that no one can sort of submit this form--

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: [INAUDIBLE] were.

  • COLTON OGDEN: Yeah, you do.

  • You use a hidden form that has the token injected into it by the server.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: "You guys should give an included security session."

  • KAREEM ZIDANE: Yeah.

  • Definitely, yeah.

  • That would be a cool idea for a security stream.

  • COLTON OGDEN: David's like an expert on security.

  • So I sort of feel like he'd be great to do a security stream.

  • I'm not that great at security, one day maybe.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: I'll ask him if he wants to do like a basic security stream,

  • because that'd be pretty fun.

  • KAREEM ZIDANE: All right, so the last example that we have today is app4.

  • And app4 essentially builds on top of app3, but also adds--

  • let me actually run Flask here like last time and then show app here.

  • So it's mostly the same as the pie from app3, except that, first of all,

  • it adds the flash message.

  • So let me actually show this, because this might be useful to show.

  • So if I go back into my app3 folder and I run Flask again--

  • and let's suppose I'm logged in already.

  • If I visit register with a lowercase--

  • OK, so I added this functionality to app3 as well.

  • COLTON OGDEN: It looks beautiful.

  • KAREEM ZIDANE: So this message shows up here.

  • You can't actually register a user.

  • Or we chose that you can't register a user if you're logged in already.

  • So you must log out first.

  • COLTON OGDEN: So this is a flash message that you're just included?

  • KAREEM ZIDANE: This is a flash message that, you know,

  • it appears as an ordered list item.

  • And the way this is implemented is--

  • COLTON OGDEN: It's a list in case you want multiple flash messages?

  • Is that why you shows a list?

  • KAREEM ZIDANE: Correct, yes.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Yeah.

  • You can flash multiple messages.

  • And they would, in this case, show as a list.

  • [INAUDIBLE]

  • COLTON OGDEN: I love that unstyled HTML.

  • It's gorgeous.

  • KAREEM ZIDANE: Yeah.

  • I hear you're going to do a steam on CSS soon.

  • COLTON OGDEN: Yeah, tomorrow.

  • KAREEM ZIDANE: So maybe you should do that.

  • COLTON OGDEN: We're going to do a basic CSS stream tomorrow at 1:00 PM.

  • So tune in for that if you're curious about a little bit of CSS.

  • KAREEM ZIDANE: Yeah.

  • As you can see, my apps are really, really ugly.

  • So I'm going to watch your stream.

  • COLTON OGDEN: Mine are, too.

  • Don't worry.

  • I'm not very good at CSS, but I know the basics.

  • So we'll have a nice lovely stream on it tomorrow.

  • We'll talk about just some of the basic stuff.

  • KAREEM ZIDANE: We have a little bit of CSS in app4.

  • We're not going to dive deep into that.

  • We're going to leave it to you.

  • But the idea of flash messages is here.

  • So in the register routes, if there's a user name already in the session,

  • so if there's a user logged in, I'm just going to call flash.

  • And flash is imported from Flask as well.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: Right?

  • And then I'm going to pass it some string here-- in this case,

  • this string has a piece of HTML--

  • and redirect back to index, right?

  • And so the effect of that is that this flash message

  • is going to show up in my Index page or any page in this case

  • because I've actually added this logics and layouts.

  • And much like we have if statements with Jinja--

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: --we also have for loops logic--

  • COLTON OGDEN: Iteration.

  • KAREEM ZIDANE: --in this case.

  • So if you read the Flask documentation, you'll

  • find the snippet of code that tells you how to consume your flash messages.

  • And in this case, you get the get_flashed_messages.

  • And you check if there are messages.

  • You just loop over them.

  • So this syntax for a for loop in Jinja is

  • fairly similar to the syntax of a for loop in Python.

  • COLTON OGDEN: Yeah, it looks pretty much like they took Python

  • and, with a couple of exceptions, they put it between percent brackets.

  • KAREEM ZIDANE: Correct.

  • And there's no column here.

  • Like, the indentation-- excuse me-- doesn't really matter.

  • So in this case, we have to have an end for, end if in case of an if statement.

  • So these are [INAUDIBLE].

  • COLTON OGDEN: I like how it has context managers, too, though, the with.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: That's pretty cool.

  • KAREEM ZIDANE: Yeah.

  • It's really fancy.

  • So, yeah I'm essentially in looping through all these messages using

  • a loop in Jinja and then displaying or rendering each message,

  • passing it to a Jinja filter safe.

  • COLTON OGDEN: Right.

  • KAREEM ZIDANE: Because I know my message actually include special characters,

  • include HTML.

  • COLTON OGDEN: So HTML escapes.

  • KAREEM ZIDANE: Correct.

  • COLTON OGDEN: OK.

  • Nice.

  • KAREEM ZIDANE: So this actually says that, hey, trust this message.

  • I know what I'm doing.

  • This has HTML in it.

  • Otherwise, it would actually show the literal HTML.

  • COLTON OGDEN: Oh, I see.

  • OK.

  • Yeah, makes sense.

  • KAREEM ZIDANE: Yeah.

  • It would really escape this and show the angle brackets.

  • COLTON OGDEN: So it's actually not escaping it.

  • It's actually giving it as raw.

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: OK.

  • That makes sense.

  • KAREEM ZIDANE: Correct.

  • All right, so in app4, which is this file right here,

  • we have the same registration log-in, the same log-in, log-out.

  • And the thing that we added-- and let's actually run the [? app4 ?] [? surf ?]

  • application.

  • So if I reload this, I actually--

  • OK.

  • I saw a bug here, but never mind.

  • So we see-- and this is sort of a spoiler--

  • no posts yet.

  • COLTON OGDEN: Font's different there, too, it looks like.

  • So you got a little bit of styling there.

  • I like it.

  • KAREEM ZIDANE: Yeah.

  • Yes.

  • COLTON OGDEN: Oh, did you include Bootstrap?

  • Is that what that is?

  • KAREEM ZIDANE: I don't not.

  • COLTON OGDEN: Oh, OK.

  • KAREEM ZIDANE: I just included a couple of style properties and values.

  • COLTON OGDEN: Got ya.

  • A little bit of fancy hand-written CSS, you know?

  • KAREEM ZIDANE: So let me register you, or register me really,

  • because I'm going to post on my behalf, right?

  • COLTON OGDEN: What's on your mind?

  • KAREEM ZIDANE: So once I'm registered in,

  • I have this form that looks familiar to that of other social media websites.

  • And the idea is that I will be able to, hey, post something.

  • You know, I was on Colton's stream today.

  • COLTON OGDEN: That's right--

  • or I'm hungry today.

  • KAREEM ZIDANE: Or I'm hungry.

  • And post it.

  • COLTON OGDEN: Or both.

  • KAREEM ZIDANE: And it would show up like this.

  • COLTON OGDEN: Oh, nice.

  • I like that.

  • I like that.

  • Now, is this all client side at this point?

  • KAREEM ZIDANE: Not really.

  • COLTON OGDEN: Are you storing these?

  • KAREEM ZIDANE: I'm redirecting, but it's really fast

  • that it didn't like take a long time loading?

  • COLTON OGDEN: No, but I mean are you storing these posts in a database?

  • KAREEM ZIDANE: I am.

  • Well, I'm not storing them in a database.

  • I'm storing them in the CSV file like we did.

  • COLTON OGDEN: Oh, OK.

  • KAREEM ZIDANE: But, ideally, yes.

  • You would be storing them in a database.

  • COLTON OGDEN: Interesting.

  • Is in a separate database from the registrants?

  • KAREEM ZIDANE: That is correct.

  • And so much like you would have a separate table for posts than users,

  • I have a separate file here called post to CSV that essentially

  • includes the content of the post--

  • COLTON OGDEN: The user name and the timestamp.

  • KAREEM ZIDANE: --the author of the post, and the timestamp.

  • Yes.

  • COLTON OGDEN: OK.

  • KAREEM ZIDANE: And then if we take a look at the user,

  • it's exactly in the same format as before,

  • nothing different, nothing fancy.

  • COLTON OGDEN: So does your logic then iterate over the table of posts

  • and just all the ones that have the same user name?

  • It'll just output them?

  • KAREEM ZIDANE: That is correct.

  • So let's actually see what happens when we see the Index page.

  • So when we go to the Index page, what happens

  • is that we render the index.html template.

  • We pass in the title as usual.

  • We pass in the user name as usual.

  • And then we pass this extra thing called get_post or posts, keyword argument.

  • And the value of that is get_posts.

  • So let's take a look at get_posts.

  • Right here, we're opening the post CSV files.

  • We're reading all of it.

  • And we're sort of returning, liking massaging this data

  • and returning it as a list in Python.

  • So we take the first cell in each row and pass it

  • as the value of the content key, second cell author key, and third cell

  • is the date time, right?

  • Otherwise, if there are no posts, we just

  • return an empty array or empty list.

  • COLTON OGDEN: Cool, makes sense.

  • KAREEM ZIDANE: OK.

  • COLTON OGDEN: I can see it as being very performance heavy

  • if you had like 10 million posts.

  • KAREEM ZIDANE: Definitely.

  • And this is why--

  • COLTON OGDEN: This is why you need a database--

  • KAREEM ZIDANE: This is why you need a database.

  • COLTON OGDEN: --with indexing.

  • KAREEM ZIDANE: And even if you have a database,

  • this is why you should limit whatever you're showing to the users.

  • COLTON OGDEN: Yeah, like 10 at a time.

  • KAREEM ZIDANE: Facebook doesn't show you billions and billions of posts

  • once you [INAUDIBLE].

  • COLTON OGDEN: It feels like it.

  • KAREEM ZIDANE: Well, yes.

  • But it actually asynchronously loads more posts as you scroll down

  • or whatever.

  • So let's actually take a look at the index.html template.

  • And if you go to that one, the content has the few things

  • that are different in this case.

  • Let me indent this correctly, so that we can see better.

  • Well, I don't think it would matter.

  • So it chose something similar to before when you're logged in,

  • hello user name if you're logged in and then hello [INAUDIBLE] link.

  • But there's also this form right here that's submitted to /posts.

  • COLTON OGDEN: Right, that's the text area.

  • KAREEM ZIDANE: Correct-- using the POST request method.

  • And there's the text area where we type our post here.

  • And there's a placeholder.

  • COLTON OGDEN: It's an amazing placeholder message as well.

  • KAREEM ZIDANE: Yeah, well, thank you.

  • It didn't come from scratch.

  • COLTON OGDEN: Very enthusiastic.

  • KAREEM ZIDANE: Yes.

  • And so there's a Submit button with post on it, right?

  • And so what happens when you submit a form like this?

  • The first thing that happens is that we get the content of the post.

  • And we make sure that there is a user already logged in,

  • because we don't want to allow arbitrary people, like anonymous people,

  • on the internet to post something.

  • So we get the author of the post.

  • And we validate that.

  • We see if there is no post or, if the post is empty,

  • show that this is a better request.

  • If there is no author or if there is no one logged in,

  • show forbidden, 403, with some descriptive messages here.

  • And then like we did with registering users, we just open the CSV file.

  • We insert a row in this case.

  • The content of this row is the content of the post

  • plus the author, the user who's logged in, and then the current time and date.

  • COLTON OGDEN: Cool.

  • KAREEM ZIDANE: And that's how we store this, right?

  • And so this is, I think, all what I have for today.

  • We can demonstrate this more.

  • We can have, you know, it was good.

  • COLTON OGDEN: In case anybody was curious.

  • KAREEM ZIDANE: If I reload this page, it should--

  • COLTON OGDEN: Nice.

  • KAREEM ZIDANE: --technically show the same thing.

  • COLTON OGDEN: It loads it all at the beginning.

  • That's cool.

  • KAREEM ZIDANE: And so this is the first step

  • on creating another social network.

  • COLTON OGDEN: Yes.

  • It'll be the next Facebook--

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: --the next, you know, sort of usurper of Facebook.

  • KAREEM ZIDANE: So, yeah, I hope that was useful for a quick introduction

  • to Flask today.

  • COLTON OGDEN: Yeah, that was awesome.

  • Thank you so much.

  • We'll catch up with all the chat here.

  • KAREEM ZIDANE: Thank you.

  • COLTON OGDEN: Then we'll close it up.

  • People are saying they're waiting for the CSS stream.

  • "Should I learn Flask or Django," says [INAUDIBLE] or [INAUDIBLE]..

  • KAREEM ZIDANE: Django, I think, is a bit more

  • difficult to use or get started with than Flask at least for me.

  • So if you don't need Django, if you don't have a specific use

  • case that you need Django for, probably start with Flask--

  • easier, simpler, quicker.

  • COLTON OGDEN: [? Frame ?] [? of ?] [? Ref, ?] "where can I keep track

  • of upcoming sessions?

  • Go to facebook.com/cs50, which I'll type here in the chat.

  • KAREEM ZIDANE: Whoops, that's slash--

  • COLTON OGDEN: Whoops.

  • And if you go to this URL, you can see all the events and videos

  • that we have coming up.

  • But I'm also going to work on getting a schedule integrated into the Twitch

  • site as well.

  • So thank you for the question.

  • "Are you going to talk about Bootstrap tomorrow," says [? Bavik. ?] Not

  • Bootstrap tomorrow, no.

  • Tomorrow is just going to be raw CSS and pretty simple ultimately.

  • If you're already familiar with CSS, it's

  • probably going to be old hat for you.

  • It will open us up to be able to do more a advanced CSS stream in the future.

  • But, no, it's going to be pretty basic.

  • No Bootstrap.

  • Bootstrap we'll have as a separate stream.

  • "I get intimidated by CS-only tags on CodePen and some crazy 3D animation

  • using a ton of CSS," says [? NACL ?] [? Eric. ?] Well,

  • I hate to disappoint you, [? Eric. ?] But tomorrow we are not going to be

  • doing 3D animation in CSS.

  • I wish I was that skillful, but unfortunately I am not.

  • But, you know, maybe in the future if I find somebody here

  • that's just amazing at CSS, we can have a follow-on stream

  • which does some of that crazy stuff.

  • KAREEM ZIDANE: Can you be amazing at CSS?

  • COLTON OGDEN: Me?

  • KAREEM ZIDANE: Anyone?

  • COLTON OGDEN: Oh, can you?

  • Oh, yeah.

  • The people on CodePen that do this stuff,

  • I'd say they're probably amazing at CSS.

  • KAREEM ZIDANE: Wow, OK.

  • COLTON OGDEN: "Flash versus Django, everyone

  • says I should learn Django for fast development.

  • What are your thoughts on that?"

  • Kind of the same question as before, right?

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: Yeah.

  • I could see Django being fast if you're really familiar with it

  • and you ship all the time with it and you have a workflow.

  • But I think if you're in brand new to that ecosystem,

  • it's probably more time to get started with Django than Flask.

  • Because Django is just so much bigger, so much more robust.

  • There's a higher learning curve, same with Rails, for example,

  • being a pretty large framework.

  • "Does Flask code appear on the browser page source," says [? olegasemi1376? ?]

  • KAREEM ZIDANE: That's a great question.

  • No, it doesn't.

  • So this is actually something that we should have explained.

  • When you call render template on the server side, what it actually does

  • is that it loads your template.

  • It sort of processes it, so it resolves the extends

  • whatever with the actual base HTML file that we have.

  • It plugs in all the necessary values that we plugged in using our code.

  • And at the end, it produces a big HTML file

  • with everything processed and resolved.

  • And what we end up seeing is actually the things that we care about here.

  • So there is no Jinja syntax here.

  • There is no Python specific syntax here.

  • All of it is actually the code that we [INAUDIBLE]..

  • COLTON OGDEN: It serves it just like a regular HTML page.

  • It looks like it was completely hand-written--

  • KAREEM ZIDANE: Yes.

  • COLTON OGDEN: --by somebody.

  • KAREEM ZIDANE: So this is often referred to our server-side rendering.

  • There's also client-side rendering, which is you can do something like this

  • similar with a front end framework like React or--

  • did we cover React?

  • COLTON OGDEN: Brian covered React, some basics of React, yeah.

  • KAREEM ZIDANE: Brian covered it, yeah.

  • So you can maybe look at Brian's stream for a React tutorial

  • and see how you can do client-side rendering as well.

  • COLTON OGDEN: "I'm eager for two sessions, one on databases

  • and two on Heroku slash Docker deployment," says [INAUDIBLE]..

  • Yeah.

  • That's be cool.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: "People are saying that the hardest thing about making APIs

  • is designing your data.

  • Somebody else mentioned it was a headache deploying my Flask app

  • on Heroku and connecting the database."

  • So that'd be cool to talk about.

  • KAREEM ZIDANE: Yeah.

  • Yeah.

  • We should probably talk about this in the future stream.

  • It would be interesting.

  • Of course, you can do this without Docker at all.

  • Or you can do it with Docker and sort of make a couple of things

  • easier for yourself since the environments are going to be the same.

  • But, yeah, that would be something interesting to look into.

  • COLTON OGDEN: And then, "the hardest thing about making APIs

  • is designing your data."

  • Again, yeah, that'd be interesting to have an API stream.

  • Brian did an APIs and ORMs lecture for CS50 Beyond.

  • So maybe we'll get him in here for APIs conversation.

  • KAREEM ZIDANE: Yeah.

  • COLTON OGDEN: And thank you very much from [INAUDIBLE] and [INAUDIBLE]

  • and also [? Scout969 ?] for the follows, much appreciated.

  • KAREEM ZIDANE: Thank you, all.

  • COLTON OGDEN: Ba, ba, ba, let's make sure we're all caught up.

  • "Thanks Kareem the Dream and Colton.

  • There we go.

  • We almost got through the stream without it.

  • We almost did it.

  • No, we got it.

  • We got it in there.

  • KAREEM ZIDANE: Yeah, thank you for watching this.

  • COLTON OGDEN: "On forms, should the content type [INAUDIBLE]

  • type equals be set?" says [? Jiban3. ?] Encoding type,

  • I'm guessing, that's short for.

  • KAREEM ZIDANE: I believe so.

  • Yes, I think forms have a default encoding type.

  • But long story short, you can sort of submit

  • the data using different formats.

  • I think the default formats, I can't even

  • remember the names, like duh, duh, duh, data slash something.

  • And this is the sort of key value pair format.

  • So if you have an input field with a user name and the value foo,

  • it will be submitted as literally user name equals foo.

  • But there are other for encoding formats like JSON,

  • for example, where it would be submitted as a key for the JSON object.

  • And the value would be the foo in this case.

  • COLTON OGDEN: Got ya.

  • And [? Andre ?] says, "yes CSV file-based Facebook

  • is the next big thing.

  • I'm sure it'll be very performant."

  • KAREEM ZIDANE: Wow.

  • COLTON OGDEN: [? Kiefa ?] is asking, "how do you implement up-voting

  • for posts and comments?

  • What's the logic look like?"

  • KAREEM ZIDANE: That's a great question.

  • This will be another piece of data that you would have to keep track of.

  • Ideally, you don't really want to reload the page, though,

  • when someone up-votes your post.

  • So this will be ideally done using an AJAX request.

  • And so the idea of an AJAX request is that you

  • would be sending a request using JavaScript from your browser

  • without actually reloading the page.

  • And the server would receive this request, process it as usual,

  • and then maybe change something in your database or CSV files in this case.

  • So you would have to keep track of some counter.

  • And every time you receive a request for this particular post with an ID,

  • you just up this counter by one or down it by one if you're down-voting.

  • COLTON OGDEN: "Awesome stream," says [? Bela. ?]

  • "Thank you, Kareem and Colton."

  • Thanks, [? Bela ?] for tuning in, much appreciated.

  • KAREEM ZIDANE: Thank you so much.

  • COLTON OGDEN: "Thank you for the stream,"

  • says [? Bavik, ?] much appreciated for your attendance.

  • "How would someone go about connecting React or another front end framework

  • to Flask?

  • Will it interfere with the default Jinja templating?"

  • KAREEM ZIDANE: Yes.

  • That's a great question.

  • And I actually looked into this briefly before.

  • And I don't think there is an ideal way to do this.

  • Like, it's certainly possible.

  • It's just going to give you headaches.

  • Because as you mentioned, the syntax for Jinja

  • is going to be problematic with syntax for React.

  • And so ideally, that's why frameworks like React

  • are typically used with, I think, a node back end.

  • COLTON OGDEN: Node back end with an API, so you

  • don't have to worry about templating.

  • KAREEM ZIDANE: So you could use an Express or something.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: They usually contain something putting--

  • I guess you could disable that, or you could sort of

  • try to get around it somehow.

  • COLTON OGDEN: Yeah.

  • KAREEM ZIDANE: But you're right, that's a good point.

  • COLTON OGDEN: [? Hela ?] from Belgium says,

  • ""[INAUDIBLE] was wondering what Linux distro Kareem is using."

  • KAREEM ZIDANE: I'm using Ubuntu 18.10, which is the latest version of Ubuntu.

  • Yeah, so it's been working well so far.

  • COLTON OGDEN: Cool, looks great.

  • I think that's all the questions.

  • If anybody has any last questions, that would be awesome.

  • [? Kiefa ?] [INAUDIBLE] from Nairobi, awesome, thank you so much.

  • "Great session.

  • Thank you for answering our questions.

  • See you tomorrow," says [? Kiefa. ?] Yup.

  • See you tomorrow for some CSS.

  • KAREEM ZIDANE: Thank you so much.

  • COLTON OGDEN: Yeah.

  • We'll stick around for just a couple more minutes in case anybody

  • has any last questions.

  • And then otherwise, we will bid you adieu and see you tomorrow.

  • Or at least I will see you tomorrow for some CSS.

  • And then the day after, we will review your source code

  • live on Twitch, so that'll be a lot of fun.

  • KAREEM ZIDANE: Yeah.

  • That's exciting.

  • COLTON OGDEN: We got to get you in here again for another stream, too.

  • KAREEM ZIDANE: Hopefully, yes.

  • COLTON OGDEN: And as always, many of you have been contributing your ideas

  • fantastically.

  • So keep doing that.

  • We want to hear all of your ideas for future streams,

  • so we can keep producing some awesome content.

  • So any topics, anything you want us to build, anything

  • you want us to talk about, that would be nice.

  • [? JL ?] asking, "where did you submit the code?"

  • So do you want to plug your repo in there one more time?

  • KAREEM ZIDANE: No, I think he's asking about the code review thing.

  • COLTON OGDEN: Oh, right, right, right, right.

  • So that is at bitly/cs50twitchcodereview.

  • And then [? Frame ?] [? of ?] [? Ref ?] included the longer you URL that Bitly

  • actually maps to.

  • But you can go to either of those.

  • And there will be a form asking you for your GitHub repo or a Gist link,

  • so that we can look at it, make sure that it's ideally not a CS50 pset

  • so that we don't spoil the solution for anybody online.

  • Also, it's more catered again towards beginner or intermediate programmers.

  • It's not meant for bug testing.

  • So if you have any bugs, we won't be debugging your code live on stream.

  • But we will answer any style questions you might have.

  • We will be looking at the style, critiquing it, critiquing the design,

  • making sure that it's well-implemented, well-formatted.

  • And regardless of your experience level, you know, submit it.

  • But, again, it's more catered towards folks that don't necessarily

  • know maybe how best to style, or design, or code yet

  • and are just kind of beginning.

  • "Gist is adding extra spaces in the code, anyway to solve it"

  • says [INAUDIBLE]?

  • KAREEM ZIDANE: If you're using GitHub, when you were creating a Gist,

  • it allows you to choose the number of spaces to use for indentation.

  • COLTON OGDEN: Sure.

  • KAREEM ZIDANE: So if you're using two, whatever, make sure to choose that.

  • COLTON OGDEN: Yeah.

  • And if you're copying and pasting in the middle of your code base,

  • that might also be screwing up the spacing a little bit.

  • So you can copy it to another file and Shift Tab it

  • back to where it's flush with the left side.

  • Ideally, the snippet should have some context.

  • So maybe just include the whole function or the whole body.

  • But you know, either way send us what you have.

  • And if we can work with it, we'll give it our best shot.

  • [INAUDIBLE], "thank you as always.

  • You are wonderful."

  • Thanks so much, [INAUDIBLE],, much appreciated.

  • But I think that's it.

  • I think we're all caught up.

  • So thanks to everybody who tuned in live today.

  • This was Flask.

  • Thanks to Kareem for this wonderful stream.

  • KAREEM ZIDANE: Yeah, thank you for having me.

  • COLTON OGDEN: We built a very simple social network of sorts,

  • more like a blog at this point it looks like.

  • KAREEM ZIDANE: Yeah, correct.

  • COLTON OGDEN: But, yeah, no, it was awesome.

  • So we got to cover Flask.

  • KAREEM ZIDANE: Thank you so much.

  • COLTON OGDEN: If you were looking to get into back end programming with Python,

  • this is a good starting point.

  • Tomorrow join us for front end, more front end stuff.

  • So last week, we did HTML or two weeks ago we did HTML.

  • This week we're going to do CSS.

  • Tomorrow we're going to do CSS, Cascading Style Sheets, the basics.

  • Again, I'm not an expert.

  • I'm not going to wow you with my amazing CSS skills,

  • because I don't have amazing CSS skills.

  • But I will get you on the right track if you are an aspiring web developer.

  • So thanks so much everybody once again.

  • This was CS50 on Twitch with Kareem and Flask.

  • I will see you all tomorrow.

  • Bye-bye.

COLTON OGDEN: All right.

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

FLASK BASICS (SERVER-SIDE PYTHON) - CS50 on Twitch, EP.31 (FLASK BASICS (SERVER-SIDE PYTHON) - CS50 on Twitch, EP. 31)

  • 6 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字