RESTful and HTTP APIs in Pyramid Transcripts
Chapter: Calling services with Python and JavaScript
Lecture: Enabling cross-domain requests with CORS

Login or purchase this course to watch this video and the rest of the course contents.
0:01 Here we are back in our actual server side service code. And our goal is to add cors support, that is cross-origin scripting support
0:10 so we could come in here, and actually on every single one of these requests set the various cors headers that are required, that is not a good idea.
0:21 We're not going to do that, it's totally not maintainable, it's not centralized, things like that. There are also third party packages,
0:28 other packages that add core support to Pyramid but you'll see that really we just have to add a couple of headers in the right location
0:36 and globally or actually however we want to choose to support it, we would support and enable cors, so I'm just going to show you
0:44 the raw way to do it, if you want to grab some other package and that does it as well, that's fine, but I don't really think that it's necessary.
0:50 So we're going to come down here and we're going to write another function here called allow cors, we're going to need the config in order to do this
1:02 so we create this will function, and just like all the mains I prefer to have this stuff below main, there we go.
1:10 So what we're going to do is we're going to write a function that's going to leverage what are called events in Pyramid,
1:16 and these are basically filters that run before and after various requests. So what we're going to do is we're going to hook
1:24 every single request that comes into our site and we're going to write a little function that for any request that comes in
1:30 we're going to add the proper headers that allows cors, and then let the rest of the app run and it wouldn't even know
1:36 that we've done this trick to add cors to it. So in order for this to work, we're going to need to do a couple of things-
1:44 we're going to start by coming over here, we're going to write a function that goes to the config and says add a subscriber
1:51 and it's going to subscribe to the new request event, so we can notice this is from
1:58 we'll import that at the top, well what is this function? This is a function that is going to get called every time a new request comes in,
2:05 so you are going to have to follow me a little bit down the rabbit hole here
2:10 but it's pretty easy once you see it; so here's what that function looks like, we want to come in and say add cors headers into this response right,
2:18 so we're going to process that request and as part of the response we're going to add these headers, we can do that at the very end
2:24 and it's got to come with the event, the reason we care about the event is this has things like the request and response objects on it,
2:31 so this function here will run at the beginning of the request, and so what we're going to do is use this function to say
2:39 call one more function that we don't have yet, call one more function after our various API calls,
2:46 or view calls if I have already processed it, and at the end add in those headers. So we have one more function here that we're going to write,
2:53 and I'm just going to copy this over, because you don't want to mess up the headers.
2:57 So here, we are going to say cors headers given a request and a response,
3:01 it doesn't really matter here but the request is we're going to go to the response and we're going to update the headers, allow control origin star
3:07 allow control methods and so on, so these are the various things and you can of course tune them to the security that you are after,
3:15 but how does this function get called, well, remember, the function on line 18 runs at the beginning and the goal is to get line 19 to run at the end
3:25 so when I come here I want to say go to the event request hey request, when you are done and you're generating the response
3:33 run the function that adds the headers. So that probably looks a little g narly, a little intense,
3:39 but here's the thing, you write this code and you never ever think about it again, so let's just add a little print here I'll say print adding headers,
3:48 if we run this again, if we just click on it, you can see we got three adding headers one of them from our straight request,
3:56 and one for our css and one for javascript or something like that, you know calling back into this service, maybe even images.
4:03 So it looks like that's working, let's do one more thing, let's go back here and do another request; now notice, our headers went from 4 to 9,
4:13 and there you can see all of the headers that allow cors are now added back in here. So be very careful, these controls are in here for a reason,
4:22 you don't want some javascript on some bad form to reach back to your site and grab some private data using a logged in cookie of your user
4:30 that maybe also visited that site, things like that, but if your goal is to write just a pure service endpoint
4:37 that anybody can call, then you need to enable cors. It looks like those are coming back, now let's go and clear this out,
4:44 let's go and try our other client, this one here; so we can come back to this, and run this again,
4:51 and now we had one that had it open right, so if I click this, let's erase that do this again, abc oh look at that- 404 not found,
5:01 well why is it not found- it's not found because there's no car with id abc,
5:06 this is super cool, so now let's go and, remember, this list is out of date, because I restarted the server, so let's refresh,
5:14 and let's try to get this Opel Signum here with id that ends in f f. So when I come over here and paste it, you've got to be very careful
5:24 I got a quote on the end, so if we hit go, it shows the id, I am going to get rid of that little alert, that part is working- success,
5:33 see that, success, right, you have an error here but that's just leftover. All right, so things are looking great, this is fine,
5:39 let's say if e.error, remember we added that in get alert, error contacting service, like so;
5:54 otherwise, we'll just say a generic fail, who knows what happened here, like site is down, network is off, something like that.
6:03 So that's the fail, but over here that's done one, this is the success so the results remember, we're getting an individual car
6:11 so the results are going to actually be the car, so let's say populate data, and we'll pass the car which is the results here,
6:19 I put that in the wrong spot, let's put it where it belongs, all right there so when it's done, we're going to populate the car with the results
6:28 and this is when it runs successfully, if it fails, well then we get something over here. Ok so the final thing to do is to just populate the results,
6:35 and let's go ahead and write that, let's go over here, grab that and drop that in. So no,we don't want to switch languages to whatever that is,
6:44 so we're going to come over here and we want to use jquery again, and we're going to go grab all these,
6:50 so we want to basically do like this at the beginning of every one of these and then drop off the end, put something there to set the value,
6:58 down here at this part, we want to say .text is going to be, okay, in this case it's name, in this case it's price.
7:12 Remember, our service gave javascript json and json are basically javascript objects so we can access the values with dot notation there.
7:22 Okay, so, notice we are going to the car detail section and we're fading it out in case it was already shown and then we're fading it in,
7:31 by default it's not shown initially until you load a car into it, so doing a get when things are done successfully, we're going to call this
7:39 otherwise there's some error handling, let's go and try this so here we refresh that, click and I got to get rid of this,
7:47 but look at that, there it is, success, we've done it! All right, that's pretty cool, so notice there's no errors in the console
7:54 that's really pretty sleek, and the last thing is there's some alert somewhere that I still have that I want to get rid of.
8:01 So let's refresh this, get it again, notice we've got this one, let's go get a different one, this one's going to be the Astra, find little vehicle
8:08 okay, so let's go check out the Astra, this should go to the server, download it as it starts,
8:13 it's going to fade out this part and then when the fade out is done, it's going to populate it and fade it in,
8:19 so it should fade away and come in with the Opel Astra, and not the Signum. Ta- da, and there it is, okay so what have we learned here?
8:27 We've learned, well jquery still works and makes life pretty easy, right, so we come over here and we order the document,
8:34 and we say give me the form, somebody tries to submit it, instead we're going to use ajax to do that and tell it don't actually submit the form,
8:40 we can go over here and we do a little bit of grabbing the car id value out and use that to build the url that is basically our api
8:49 our schema that we want to talk to here, and we use $.get because we're trying to do a get
8:54 we could just as easily do a post and post the data, but we're not there yet; if it's done successfully, we populate the results,
9:00 otherwise there's error handling, remember we return like a 404, and we put this error, let's try something else,
9:06 like let's change 1 to a 2 and see what we get- fail, okay. So if we try to get one where the idea is wrong, we just get a 404,
9:14 but of course, if we get the one that is right, it fades in and everything is good.
9:20 So everything was pretty straightforward in terms of javascript here, the one thing that maybe was unexpected, depending on how much you've done this,
9:29 is we actually had to go over to pyramid and we had to add this cors operation or cors configuration on the server side, we had to go to every request
9:39 and say for this request, we would like to add the cors headers, now of course, this thing here was the request
9:47 you could look at the request that's coming in and say well, only if its /api/something do you want to actually add the cors headers,
9:56 all the other requests we don't want javascript to be able to get to that we just wanted to be able to get to /api/whatever right,
10:04 so you could be more discriminating, more careful than just throwing it on every single request, but we don't really have a use case for excluding it
10:12 so I'm going to put it everywhere, and you guys can adapt this to your situation.

Talk Python's Mastodon Michael Kennedy's Mastodon