Rate Limiting8:59 with Kenneth Love
Even known, authenticated users can abuse your API. By introducing a rate limiter, you can control how often someone can access your API in a given time period which can be the difference between 99.999% uptime and 9.9999%.
Honestly you could stop building your API right here. 0:00 Solid resources with authentication and 0:03 protected methods is 99% of what most APIs need. 0:05 But for that extra bit of security and 0:09 peace of mind, you probably want to bring in some rate limiting. 0:11 Rate limiting makes it so that a particular user can only access 0:15 an endpoint so many times in a certain time period. 0:18 This helps prevent stampedes against your API and 0:21 makes things that much more stable. 0:23 All right I got one last feature I want to add and 0:26 this API will be more or less ready for the world. 0:29 Right now I can hit this API as many times as I want. 0:34 If I was to come over here to Postman, and do a get on courses, 0:38 and hit Send, I could send this just as many 0:44 times as I want and the server doesn't care. 0:49 It's not going to do anything to me. 0:53 Now if i was all nefarious and wicked, I would set up a bot network and 0:55 just pound on the server until it went down. 0:59 As an API owner though, I wouldn't want that to happen. 1:02 You probably don't want that to happen either, so it's time to take care of that. 1:05 Now unlike signing the tokens, I do have to install another package for this one. 1:10 Can't win them all. 1:16 So let's install this package real quick. 1:17 I'll quit the server. 1:19 And we're gonna do pip install flask_limiter. 1:20 And I don't think it matters if you do an underscore or 1:24 a hyphen there, but whatever. 1:26 All right. 1:30 So then, I'm gonna go ahead and 1:30 run the server again just to have it running while I'm doing this stuff. 1:32 Gonna to do all of this here in app.py. 1:36 Cuz this is where it's all to be done. 1:39 So up here, let's say from 1:43 flask_limiter import Limiter and 1:47 from flask_limiter.util import get_ipaddr. 1:52 So this is a function that will get the IP address off of the request. 1:59 Down here we want to make a new limiter, and 2:05 we're going to say app is what the limiter is for. 2:10 And i'm gonna say global_limits=["100/hour"]. 2:15 And it's kind of cool you can specify this as a string, 2:17 as just a descriptive thing. 2:22 And then key_func= this function here is, 2:25 this is how the limiter determines who user is. 2:28 We're gonna do that with the IP address because that's good enough. 2:32 Most people don't swap IP addresses constantly. 2:36 But if you are thinking this was gonna be used by, say, a site that might be living 2:39 on a whole bunch of EC2 instances, you'd wanna have some other way of getting 2:44 the user's identification, probably something like using the token, or 2:49 the user name, or the ID of the user that we already have. 2:54 But I'll that you set that up yourself. 2:58 So let's set up a couple of limits other than this 100 an hour. 3:01 So limiter.limit, and we can say ("40/day"). 3:04 And we'll apply that to the user's_api. 3:10 We could say, and then we could exempt 3:13 the courses_api and the reviews_api. 3:18 All right? 3:23 Maybe for some reason we wanna make those things not be limited somehow. 3:24 I don't know why we'd do that anyway though. 3:31 Just to go over this again really quick. 3:34 So I've got this global limit set to 100 per hour, 100 requests per hour, 3:36 and we're looking to see the IP address to see who it is that's making the request. 3:43 And again, you'll probably wanna use a token or an auth_user, 3:47 something like that if you're worried about them having multiple IP addresses. 3:50 And then we can set specific limits, like for this one,the user's API is limited 3:53 to 40 per day as opposed to the hundred per hour. 3:57 So this means I could only, 4:00 with one IP address, I can only create 40 users in a given day. 4:02 I think it's fair. 4:05 I think creating 40 users is maybe a little excessive. 4:06 If you need to suddenly create 500 users, maybe you should email me or 4:10 something, and we'll work it out. 4:14 And then with this exempt, I've made courses and reviews exempt. 4:17 Now this is something I want to do for an API. 4:21 Probably you don't want to exempt any of these things, so I'm going to go ahead, 4:25 I'm gonna actually take those lines out. 4:28 You know what, I'll just comment them so that you can see them and remember them. 4:29 Okay, so let's test this out. 4:33 I don't want to try to do 100 per hour, so I'm gonna change this to two per hour. 4:34 So let's go and post a couple of new courses. 4:41 Yeah? So we've got Django Basics. 4:47 Let's do Django ORM, which is a new one. 4:50 And I'm gonna send that in. 4:53 Cool, I got a new one. 4:58 All right. And let's do Django Forms, 4:58 which is also a new one. 5:01 Django Forms, let's send that in. 5:04 Okay. And 5:06 then let's send in Flask Basics cuz it's not on the list yet. 5:07 Flask Basics. 5:13 Cool, we're getting a lot of work done, and look at that, 5:16 I have a 429 Too Many Requests. 5:19 And my messages is two per 1 hour. 5:22 I can only do two in an hour. 5:24 I guess that means I'm gonna have to just sit here for 5:26 an hour until I can continue adding courses, right? 5:28 Cuz you all just want to sit here and watch me for two hours, right? 5:32 Just watch the screen? 5:35 I'll scroll around every once in a while. 5:36 No? 5:39 Okay. 5:40 I can just change the limit then. 5:40 So right now the kind of funny thing is like, let's put this back to 100 per hour. 5:43 What if I wanna do this to where it only applies to certain methods, right? 5:49 I don't care if somebody is doing a whole lot on the get, right? 5:53 They're trying to get a lot of courses or 6:00 are trying to get a lot of reviews or whatever. 6:01 That's not that big of a deal. 6:04 That makes a lot of sense. 6:05 People are gonna read more than they write. 6:06 Well right now, all of these limits apply to all of my stuff. 6:10 Maybe I wanna change that. 6:15 Maybe I want it to be just some methods. 6:17 Right, that applies to all the methods. 6:19 So let's go over here to config, and let's make default rate. 6:21 And we'll make that a 100/hour. 6:26 So that's our default rate. 6:29 So then over here, well we still have our limiter, we're not going to change that, 6:32 but instead of this hundred per hour, let's just say config.DEFAULT_RATE. 6:38 Actually, you know what? 6:44 I wanna, yeah yeah that's fine. 6:45 All right, so we're gonna leave that alone. 6:47 All right, and then I'm gonna leave that limit in there. 6:48 And then I wanna set a couple of custom limits on the reviews and courses. 6:51 So let's do limiter.limit config.DEFAULT_RATE. 6:57 And then I'm gonna set per_method=True. 7:03 The limiter sees the entire resource as being one single view. 7:07 So it doesn't care about the get post put whatever. 7:13 When we put in per_method=True, it suddenly cares about the post, 7:15 the put, the get, the delete, the whatever. 7:19 And then we're gonna say methods=["post", "put", "delete"]. 7:22 So those are the ones that we want to control. 7:30 And this is gonna be for the courses_api. 7:34 And we can break that down. 7:39 Okay. 7:42 And then let's copy this. 7:43 I wanna do the exact same thing for the reviews_api. 7:44 So this makes it so that each method has its own limit and only the post, put, and 7:51 delete methods. 7:55 The get method let's again, 7:56 let's go set this back to lose 1/hour. 8:00 Why not? 8:04 So if I do the get here, I can get this is many times I want. 8:06 Get is no longer controlled. 8:11 It's no longer limited at all. 8:13 And I might wanna go and change that. 8:16 I might want to set up, hey you can only get one hundred times an hour. 8:17 But right now it's not set that way. 8:22 But post and put are locked down. 8:24 Flask-Limiter has a lot of options, so be sure and 8:27 check the teacher's notes for a link to the documentation. 8:29 There are lots of other things you might want to add to your API. 8:33 Caching our database queries is a great way to make it more stable and powerful. 8:36 And you'll probably want to build some sort of site on top of it so 8:40 people know what your API does, how to sign up for it, and how to use it. 8:43 But I'm gonna leave all of that up to you to do on your own. 8:46 Congratulations on building a great API with Flask. 8:50 I can't wait to see what you build with Flask RESTful, 8:53 and all of the other tools that we've learned in this course. 8:55 I'll see you next time. 8:57
You need to sign up for Treehouse in order to download course files.Sign up