RESTful and HTTP APIs in Pyramid Transcripts
Chapter: Customer Renderers
Lecture: Generating image-based responses with renderers (v1)
0:01 Now let's come back and add another type of renderer. I think seeing this a couple of times you guys will totally have this down,
0:08 we're going to take two variations on this, one, a kind of simplistic one and another one a little more advanced. So what I want to add to our app next
0:16 is this ability to request an image about the car, so let's go over here and see if we can do this,
0:22 so let's duplicate this and we're going to go ask for an individual car,
0:26 let's actually run this again, okay, and we're going to ask for an individual car here,
0:31 close, no, copy like this, so now we have a json one and that's fine, but let's go over here, and we want to accept image/png,
0:41 well, we're still getting json, we have no renderer that knows about images. However though, if you look carefully, we have an image,
0:50 it is right there right, that's the image; somehow what we'd like to do is have our system come along
0:56 and actually when we get this request with image png say you know what, let's somehow give that image back to them as a png great,
1:07 so that's what the job of this image redirect renderer is, and the redirect part we'll talk about what that means in a second.
1:13 So standard, we have our adapters, right, we want to work in a general way, so the rules around this one is the thing it can get an image from is
1:23 if the type can be adapted to an individual dictionary and that individual dictionary contains a link under the image key,
1:31 somewhat restrictive, but it's not too hard to imagine adapter that we can add for almost any type if it has some link,
1:39 we want to get the request, we want to set the response type, and let's just go over here and we'll do some work with the adapter;
1:47 so we'll say adapter self.adapters we'll get the type of value now this time, I don't really know how to return
1:55 a single image that represents like a list of cars so it's only going to work if you pass individual items
2:01 of the type to ask the image for not in a more general sense, right. So let's go ahead and say if there's no adapter
2:09 and the type of the value, let's ask it this way, and not is instance value and dict so either there's an adapter that we can use
2:21 or the instance is a dictionary, those are basically the two types let's actually do this in reverse, let's say if adapter here
2:28 and we'll do the adapting and then we'll deal with this in a minute, so we'll say if adapter then value equals adapter. the value
2:35 and the way the generalized framework works is we pass in a second item there so we'll just use none, adapters are not making use of this.
2:44 So now, now I have to go on the right track so we'll ask if it's not a dictionary then we have no idea how to deal with this,
2:49 so we'll raise exception, could not convert type whatever, and we'll put the type here, ok, so now our job is just to implement this renderer
3:02 so we have a dictionary, our rules are it has an image value, right so let's go over here to say image url equals value.get image
3:14 if not image, then something went bad, so we'll say it couldn't find the url, now it's pretty simple
3:21 we have an image url here, and we just need to say hey go there, right, so in this one, this redirecting version, what we can do is
3:31 we can send a redirect response by raising an http found exception this lives in pyramid, http exceptions right,
3:40 so it's basically hey this is like a soft redirect to 302 moved over there, image url. Okay, so this is good, and as long as we pass the right adapter
3:52 we don't want to do this trick here, we'll get the type if the type exists actually we don't need to even do this, do we,
4:01 here we're just getting the adapter straight, the conversion is so simple, we don't have a method for it. Okay, I think we're ready, so we'll come in,
4:10 because we're using a redirect I guess we don't need this, and the new one, I am going to comment this out
4:15 in the next version we're going to need this, this is the more advanced variation. So we get the adapter, if there is one we adapted
4:21 and then either there was an adapter which made it a dictionary or already is a dictionary, if one of those cases doesn't match
4:27 this is a problem we're out here. Get the image, and we're going to redirect. This is pretty straightforward, so let's go up and add this again
4:36 remember we have to register these, so I'll call this image renderer equals that of course I've got to imports that again,
4:45 I said it's just png because I don't want to deal with the nuances of all the different content types, right,
4:51 we could look for something more complex, like image and it could look and say is that image png is it a jpeg, and so on.
4:59 But, for now, let's just go over here and let's go to our individual car a single car and make a change there.
5:06 So first, I want to request the single car one more time and of course, because we're not using our database,
5:11 not yet, very soon this problem is going to go away but for now, we need to keep updating that. Okay, so you see we want to get this url here a
5:19 and right now we are accepting the png but it's not doing anything, let's go over here and we can say what did I call it png, yeah,
5:27 we can get png and this is going to be accept equals this all right so this is a more restrictive one, it should do bidding for us,
5:37 let's try— first of all, let me turn this off to see if we still get json, no we don't because we got to keep redoing this,
5:45 like I said, this is temporary, it's going to go away, could not convert, yeah that was not so good, was it?
5:52 Let me just for now do you like this, like i said, we're going to get a better version of this, where you have to have separate image, right,
6:07 so well just do that one, ok I guess for this to work I have to set accept type on both of these,
6:21 that's too bad, but like I said, this is all temporary, we're going to sort of add a more general model
6:26 so we've got our car going— oh and here's little trick that I want to start using,
6:30 notice this first here, so instead of putting this, we'll just put underscore first and whatever the first car is we're just going to get that back,
6:38 it will save us a lot of rework, we'll take this away for a real api of course but for this little development work is nice.
6:46 All right, so now if we come over here and we say I do want an image, it's going to crash, it says I can't convert this type for cars
6:56 so we need to come over and look where we're setting up this renderer, now the csv renderer knows about cars, so does json, but this one doesn't,
7:05 so the next thing to do is to add to our image renderer this adapter, so now it should know how to adapt cars, so it's good,
7:15 so we've already seen that if we just go default we're going to get json, if we add this we should get an image, let's see.
7:21 Ta-da, there it is, how awesome is that! It's pretty cool right? So we said we wanted an image, at this url, give me the first auto, give me an image,
7:31 I get that, if I go to the first auto and say I want json by default I think it passes json over and here is like what it will accept
7:40 but anyway we'll get json here, if we go to header, put it back, boom, there is our car again. Okay, so this is super cool,
7:50 what's not super cool is all the work to juggle this around up here like this. Also, maybe we don't have a straight url to point at,
8:00 what if this is stored as a blob in the database, then how do we deal with it? We should still be able to get it, but how do we do that?
8:09 We need to somehow like embed this as a binary object and then scream it out of the server— which turns out we could totally do and we'll do next.