1 00:00:00,470 --> 00:00:03,660 Honestly you could stop building your API right here. 2 00:00:03,660 --> 00:00:05,520 Solid resources with authentication and 3 00:00:05,520 --> 00:00:09,350 protected methods is 99% of what most APIs need. 4 00:00:09,350 --> 00:00:11,190 But for that extra bit of security and 5 00:00:11,190 --> 00:00:13,900 peace of mind, you probably want to bring in some rate limiting. 6 00:00:15,250 --> 00:00:18,210 Rate limiting makes it so that a particular user can only access 7 00:00:18,210 --> 00:00:21,200 an endpoint so many times in a certain time period. 8 00:00:21,200 --> 00:00:23,580 This helps prevent stampedes against your API and 9 00:00:23,580 --> 00:00:25,220 makes things that much more stable. 10 00:00:26,370 --> 00:00:29,020 All right I got one last feature I want to add and 11 00:00:29,020 --> 00:00:34,330 this API will be more or less ready for the world. 12 00:00:34,330 --> 00:00:38,000 Right now I can hit this API as many times as I want. 13 00:00:38,000 --> 00:00:44,489 If I was to come over here to Postman, and do a get on courses, 14 00:00:44,489 --> 00:00:49,070 and hit Send, I could send this just as many 15 00:00:49,070 --> 00:00:53,936 times as I want and the server doesn't care. 16 00:00:53,936 --> 00:00:55,270 It's not going to do anything to me. 17 00:00:55,270 --> 00:00:59,602 Now if i was all nefarious and wicked, I would set up a bot network and 18 00:00:59,602 --> 00:01:02,416 just pound on the server until it went down. 19 00:01:02,416 --> 00:01:05,210 As an API owner though, I wouldn't want that to happen. 20 00:01:05,210 --> 00:01:10,290 You probably don't want that to happen either, so it's time to take care of that. 21 00:01:10,290 --> 00:01:16,040 Now unlike signing the tokens, I do have to install another package for this one. 22 00:01:16,040 --> 00:01:17,698 Can't win them all. 23 00:01:17,698 --> 00:01:19,370 So let's install this package real quick. 24 00:01:19,370 --> 00:01:20,390 I'll quit the server. 25 00:01:20,390 --> 00:01:24,910 And we're gonna do pip install flask_limiter. 26 00:01:24,910 --> 00:01:26,730 And I don't think it matters if you do an underscore or 27 00:01:26,730 --> 00:01:30,250 a hyphen there, but whatever. 28 00:01:30,250 --> 00:01:30,788 All right. 29 00:01:30,788 --> 00:01:32,597 So then, I'm gonna go ahead and 30 00:01:32,597 --> 00:01:36,688 run the server again just to have it running while I'm doing this stuff. 31 00:01:36,688 --> 00:01:39,600 Gonna to do all of this here in app.py. 32 00:01:39,600 --> 00:01:42,290 Cuz this is where it's all to be done. 33 00:01:43,410 --> 00:01:47,229 So up here, let's say from 34 00:01:47,229 --> 00:01:52,213 flask_limiter import Limiter and 35 00:01:52,213 --> 00:01:59,370 from flask_limiter.util import get_ipaddr. 36 00:01:59,370 --> 00:02:02,530 So this is a function that will get the IP address off of the request. 37 00:02:05,220 --> 00:02:10,760 Down here we want to make a new limiter, and 38 00:02:10,760 --> 00:02:14,040 we're going to say app is what the limiter is for. 39 00:02:15,070 --> 00:02:17,358 And i'm gonna say global_limits=["100/hour"]. 40 00:02:17,358 --> 00:02:22,399 And it's kind of cool you can specify this as a string, 41 00:02:22,399 --> 00:02:25,158 as just a descriptive thing. 42 00:02:25,158 --> 00:02:28,054 And then key_func= this function here is, 43 00:02:28,054 --> 00:02:31,110 this is how the limiter determines who user is. 44 00:02:32,960 --> 00:02:36,900 We're gonna do that with the IP address because that's good enough. 45 00:02:36,900 --> 00:02:39,980 Most people don't swap IP addresses constantly. 46 00:02:39,980 --> 00:02:44,840 But if you are thinking this was gonna be used by, say, a site that might be living 47 00:02:44,840 --> 00:02:49,900 on a whole bunch of EC2 instances, you'd wanna have some other way of getting 48 00:02:49,900 --> 00:02:54,600 the user's identification, probably something like using the token, or 49 00:02:54,600 --> 00:02:58,280 the user name, or the ID of the user that we already have. 50 00:02:58,280 --> 00:02:59,764 But I'll that you set that up yourself. 51 00:03:01,355 --> 00:03:04,727 So let's set up a couple of limits other than this 100 an hour. 52 00:03:04,727 --> 00:03:10,165 So limiter.limit, and we can say ("40/day"). 53 00:03:10,165 --> 00:03:12,205 And we'll apply that to the users_api. 54 00:03:13,795 --> 00:03:18,425 We could say, and then we could exempt 55 00:03:18,425 --> 00:03:23,505 the courses_api and the reviews_api. 56 00:03:23,505 --> 00:03:24,700 All right? 57 00:03:24,700 --> 00:03:31,840 Maybe for some reason we wanna make those things not be limited somehow. 58 00:03:31,840 --> 00:03:34,800 I don't know why we'd do that anyway though. 59 00:03:34,800 --> 00:03:36,470 Just to go over this again really quick. 60 00:03:36,470 --> 00:03:42,140 So I've got this global limit set to 100 per hour, 100 requests per hour, 61 00:03:43,280 --> 00:03:46,634 and we're looking to see the IP address to see who it is that's making the request. 62 00:03:47,860 --> 00:03:50,265 And again, you'll probably wanna use a token or an auth_user, 63 00:03:50,265 --> 00:03:53,590 something like that if you're worried about them having multiple IP addresses. 64 00:03:53,590 --> 00:03:57,700 And then we can set specific limits, like for this one, the user's API is limited 65 00:03:57,700 --> 00:04:00,860 to 40 per day as opposed to the hundred per hour. 66 00:04:00,860 --> 00:04:02,170 So this means I could only, 67 00:04:02,170 --> 00:04:05,400 with one IP address, I can only create 40 users in a given day. 68 00:04:05,400 --> 00:04:06,990 I think it's fair. 69 00:04:06,990 --> 00:04:10,150 I think creating 40 users is maybe a little excessive. 70 00:04:10,150 --> 00:04:14,760 If you need to suddenly create 500 users, maybe you should email me or 71 00:04:14,760 --> 00:04:16,250 something, and we'll work it out. 72 00:04:17,250 --> 00:04:21,860 And then with this exempt, I've made courses and reviews exempt. 73 00:04:21,860 --> 00:04:25,908 Now this is something I want to do for an API. 74 00:04:25,908 --> 00:04:28,286 Probably you don't want to exempt any of these things, so I'm going to go ahead, 75 00:04:28,286 --> 00:04:29,620 I'm gonna actually take those lines out. 76 00:04:29,620 --> 00:04:33,930 You know what, I'll just comment them so that you can see them and remember them. 77 00:04:33,930 --> 00:04:34,670 Okay, so let's test this out. 78 00:04:34,670 --> 00:04:40,230 I don't want to try to do 100 per hour, so I'm gonna change this to two per hour. 79 00:04:41,700 --> 00:04:46,320 So let's go and post a couple of new courses. 80 00:04:47,520 --> 00:04:49,110 Yeah? So we've got Django Basics. 81 00:04:50,270 --> 00:04:53,640 Let's do Django ORM, which is a new one. 82 00:04:53,640 --> 00:04:56,560 And I'm gonna send that in. 83 00:04:58,250 --> 00:04:58,950 Cool, I got a new one. 84 00:04:58,950 --> 00:05:01,444 All right. And let's do Django Forms, 85 00:05:01,444 --> 00:05:03,120 which is also a new one. 86 00:05:04,200 --> 00:05:06,690 Django Forms, let's send that in. 87 00:05:06,690 --> 00:05:07,290 Okay. And 88 00:05:07,290 --> 00:05:10,800 then let's send in Flask Basics cuz it's not on the list yet. 89 00:05:13,380 --> 00:05:16,220 Flask Basics. 90 00:05:16,220 --> 00:05:19,920 Cool, we're getting a lot of work done, and look at that, 91 00:05:19,920 --> 00:05:22,180 I have a 429 Too Many Requests. 92 00:05:22,180 --> 00:05:24,190 And my messages is two per 1 hour. 93 00:05:24,190 --> 00:05:26,320 I can only do two in an hour. 94 00:05:26,320 --> 00:05:28,550 I guess that means I'm gonna have to just sit here for 95 00:05:28,550 --> 00:05:32,640 an hour until I can continue adding courses, right? 96 00:05:32,640 --> 00:05:35,590 Cuz you all just want to sit here and watch me for two hours, right? 97 00:05:35,590 --> 00:05:36,630 Just watch the screen? 98 00:05:36,630 --> 00:05:38,160 I'll scroll around every once in a while. 99 00:05:39,330 --> 00:05:40,030 No? 100 00:05:40,030 --> 00:05:40,730 Okay. 101 00:05:40,730 --> 00:05:41,910 I can just change the limit then. 102 00:05:43,130 --> 00:05:49,580 So right now the kind of funny thing is like, let's put this back to 100 per hour. 103 00:05:49,580 --> 00:05:53,400 What if I wanna do this to where it only applies to certain methods, right? 104 00:05:53,400 --> 00:06:00,410 I don't care if somebody is doing a whole lot on the get, right? 105 00:06:00,410 --> 00:06:01,990 They're trying to get a lot of courses or 106 00:06:01,990 --> 00:06:04,290 are trying to get a lot of reviews or whatever. 107 00:06:04,290 --> 00:06:05,970 That's not that big of a deal. 108 00:06:05,970 --> 00:06:06,940 That makes a lot of sense. 109 00:06:06,940 --> 00:06:08,900 People are gonna read more than they write. 110 00:06:10,210 --> 00:06:15,600 Well right now, all of these limits apply to all of my stuff. 111 00:06:15,600 --> 00:06:17,560 Maybe I wanna change that. 112 00:06:17,560 --> 00:06:19,910 Maybe I want it to be just some methods. 113 00:06:19,910 --> 00:06:21,760 Right, that applies to all the methods. 114 00:06:21,760 --> 00:06:26,180 So let's go over here to config, and let's make default rate. 115 00:06:26,180 --> 00:06:29,178 And we'll make that a 100/hour. 116 00:06:29,178 --> 00:06:32,436 So that's our default rate. 117 00:06:32,436 --> 00:06:38,400 So then over here, well we still have our limiter, we're not going to change that, 118 00:06:38,400 --> 00:06:44,116 but instead of this hundred per hour, let's just say config.DEFAULT_RATE. 119 00:06:44,116 --> 00:06:45,436 Actually, you know what? 120 00:06:45,436 --> 00:06:47,236 I wanna, yeah yeah that's fine. 121 00:06:47,236 --> 00:06:48,820 All right, so we're gonna leave that alone. 122 00:06:48,820 --> 00:06:51,450 All right, and then I'm gonna leave that limit in there. 123 00:06:51,450 --> 00:06:57,010 And then I wanna set a couple of custom limits on the reviews and courses. 124 00:06:57,010 --> 00:07:03,540 So let's do limiter.limit config.DEFAULT_RATE. 125 00:07:03,540 --> 00:07:07,260 And then I'm gonna set per_method=True. 126 00:07:07,260 --> 00:07:11,990 The limiter sees the entire resource as being one single view. 127 00:07:13,100 --> 00:07:15,760 So it doesn't care about the get post put whatever. 128 00:07:15,760 --> 00:07:19,780 When we put in per_method=True, it suddenly cares about the post, 129 00:07:19,780 --> 00:07:22,680 the put, the get, the delete, the whatever. 130 00:07:22,680 --> 00:07:29,210 And then we're gonna say methods=["post", "put", "delete"]. 131 00:07:30,970 --> 00:07:33,140 So those are the ones that we want to control. 132 00:07:34,360 --> 00:07:36,565 And this is gonna be for the courses_api. 133 00:07:39,220 --> 00:07:42,188 And we can break that down. 134 00:07:42,188 --> 00:07:43,250 Okay. 135 00:07:43,250 --> 00:07:44,450 And then let's copy this. 136 00:07:44,450 --> 00:07:51,076 I wanna do the exact same thing for the reviews_api. 137 00:07:51,076 --> 00:07:55,545 So this makes it so that each method has its own limit and only the post, put, and 138 00:07:55,545 --> 00:07:56,560 delete methods. 139 00:07:56,560 --> 00:08:00,180 The get method let's again, 140 00:08:00,180 --> 00:08:04,924 let's go set this back to use 1/hour. 141 00:08:04,924 --> 00:08:06,620 Why not? 142 00:08:06,620 --> 00:08:11,775 So if I do the get here, I can get this is many times I want. 143 00:08:11,775 --> 00:08:13,610 Get is no longer controlled. 144 00:08:13,610 --> 00:08:16,030 It's no longer limited at all. 145 00:08:16,030 --> 00:08:17,706 And I might wanna go and change that. 146 00:08:17,706 --> 00:08:22,490 I might want to set up, hey you can only get one hundred times an hour. 147 00:08:22,490 --> 00:08:24,190 But right now it's not set that way. 148 00:08:24,190 --> 00:08:27,075 But post and put are locked down. 149 00:08:27,075 --> 00:08:29,850 Flask-Limiter has a lot of options, so be sure and 150 00:08:29,850 --> 00:08:31,930 check the teacher's notes for a link to the documentation. 151 00:08:33,190 --> 00:08:36,460 There are lots of other things you might want to add to your API. 152 00:08:36,460 --> 00:08:40,250 Caching our database queries is a great way to make it more stable and powerful. 153 00:08:40,250 --> 00:08:43,110 And you'll probably want to build some sort of site on top of it so 154 00:08:43,110 --> 00:08:46,778 people know what your API does, how to sign up for it, and how to use it. 155 00:08:46,778 --> 00:08:49,070 But I'm gonna leave all of that up to you to do on your own. 156 00:08:50,260 --> 00:08:53,240 Congratulations on building a great API with Flask. 157 00:08:53,240 --> 00:08:55,440 I can't wait to see what you build with Flask RESTful, 158 00:08:55,440 --> 00:08:57,970 and all of the other tools that we've learned in this course. 159 00:08:57,970 --> 00:08:58,570 I'll see you next time.