1 00:00:00,220 --> 00:00:04,720 Since Flask is a microframework, it often gets used as a single module or 2 00:00:04,720 --> 00:00:09,280 maybe a model or two and then all of the routes and logic in a single app module. 3 00:00:09,280 --> 00:00:12,370 This works great until your app gets moderately complex and 4 00:00:12,370 --> 00:00:16,580 you start having to use your editor search function just to find a particular piece. 5 00:00:16,580 --> 00:00:18,869 Once you split everything out into separate files, 6 00:00:18,869 --> 00:00:22,311 you'll likely find that it gets harder and harder to avoid circular imports. 7 00:00:22,311 --> 00:00:26,139 Or a chain of imports that ends up having one file import another file that 8 00:00:26,139 --> 00:00:27,660 also imports the first one. 9 00:00:29,000 --> 00:00:31,320 Flask has a feature named Blueprints, and 10 00:00:31,320 --> 00:00:35,040 Blueprints give us the ability to make objects that are almost like proxies for 11 00:00:35,040 --> 00:00:38,360 Flask apps or other features like our API resources. 12 00:00:38,360 --> 00:00:42,386 Let's hop back into work spaces and get this all wired up with Blueprints. 13 00:00:42,386 --> 00:00:48,020 Okay so I need to import the Blueprint object from Flask. 14 00:00:48,020 --> 00:00:53,671 I'm here inside courses.py and so I'm just gonna add Blueprint right there. 15 00:00:53,671 --> 00:00:57,680 Now this might seem a little bit weird and awkward but just stick with me for 16 00:00:57,680 --> 00:00:58,640 a minute. 17 00:00:58,640 --> 00:01:04,070 So I'm gonna to make a blueprint that represents this entire module course.py. 18 00:01:04,070 --> 00:01:05,532 I'm wanna do this down here at the bottom. 19 00:01:05,532 --> 00:01:09,969 And I'm gonna say courses_api = Blueprint 20 00:01:09,969 --> 00:01:15,922 ('resources.courses'), which is the path to the file and 21 00:01:15,922 --> 00:01:20,721 then name which is the namespace that we're in. 22 00:01:20,721 --> 00:01:23,250 So it's the file all over again. 23 00:01:23,250 --> 00:01:32,050 So basically this says, okay, treat this file with this namespace and 24 00:01:32,050 --> 00:01:36,830 this path as being another app, another thing. 25 00:01:36,830 --> 00:01:42,150 And like it's a proxy to this module that kind of sort of acts like an app. 26 00:01:42,150 --> 00:01:45,470 It's not an application, this isn't a pluggable app or anything like that. 27 00:01:46,500 --> 00:01:49,400 It actually kind of acts like a log to some degree. 28 00:01:49,400 --> 00:01:50,990 Anything that I do to this, 29 00:01:50,990 --> 00:01:54,680 all the actions that I execute on the blueprint, don't actually happen 30 00:01:55,770 --> 00:01:59,510 until I register the blueprint with an actual running Flask app. 31 00:01:59,510 --> 00:02:02,830 I'll show you what I mean with this next step. 32 00:02:02,830 --> 00:02:06,720 We've got to add a little bit more to this file though. 33 00:02:06,720 --> 00:02:09,921 So we have to actually make an API. 34 00:02:09,921 --> 00:02:16,550 And it's weird that the import is capital A lowercase pi, but just whatever. 35 00:02:16,550 --> 00:02:21,780 Okay, so then we're gonna say api = Api(courses_api). 36 00:02:21,780 --> 00:02:28,340 So we're making an API out of the current module, which kind of acts like an app. 37 00:02:28,340 --> 00:02:32,850 Normally you pass in an app here, okay, you with me so far? 38 00:02:32,850 --> 00:02:37,574 All right, let's do the next thing here so api.add_resource. 39 00:02:38,980 --> 00:02:40,945 And resource we're going to add is CourseList. 40 00:02:42,060 --> 00:02:47,048 And we're going to set the endpoint to be /api/v1/courses, 41 00:02:47,048 --> 00:02:49,677 or this is the URL slug rather, and 42 00:02:49,677 --> 00:02:54,680 then the endpoint we're actually going to call this is courses. 43 00:02:56,770 --> 00:03:02,600 Okay, and then we're gonna add another one here, api.add_resource. 44 00:03:02,600 --> 00:03:05,463 And this one goes to Course, and 45 00:03:05,463 --> 00:03:10,247 again we're going to give it /api/v1/courses. 46 00:03:10,247 --> 00:03:14,481 And then we're going to say that there's an int argument that we're gonna call id. 47 00:03:14,481 --> 00:03:17,120 And then this endpoint is going to be course. 48 00:03:18,140 --> 00:03:19,240 All right. 49 00:03:19,240 --> 00:03:23,740 So each of these specifies the resource to add, like CourseList. 50 00:03:23,740 --> 00:03:26,570 The URI to give to that resource. 51 00:03:26,570 --> 00:03:27,880 And then the endpoint to name it. 52 00:03:27,880 --> 00:03:30,820 This way we can be like, I want the courses endpoint. 53 00:03:30,820 --> 00:03:32,834 Now you don't have to provide the endpoint name, 54 00:03:32,834 --> 00:03:36,370 Flask just lower cases the name of the resource. 55 00:03:36,370 --> 00:03:39,610 So like this one would become course list and this one would become course. 56 00:03:40,620 --> 00:03:42,780 You'll probably find yourself wanting simpler import names, 57 00:03:42,780 --> 00:03:46,060 you don't necessarily want course list as the endpoint name. 58 00:03:46,060 --> 00:03:49,480 And the name can be used a few different places in Flask RESTful. 59 00:03:49,480 --> 00:03:52,160 Some of those, we're gonna talk about a little bit later. 60 00:03:52,160 --> 00:03:55,870 Okay so now I have to register the endpoint with the app, so 61 00:03:55,870 --> 00:03:59,360 I'm going to pop back over here to app.py. 62 00:03:59,360 --> 00:04:04,991 And up here after I import models I'm gonna say from resources.courses 63 00:04:04,991 --> 00:04:07,770 import course_api. 64 00:04:07,770 --> 00:04:12,042 And then after the app thing here I'm gonna do app.register 65 00:04:12,042 --> 00:04:16,882 _blueprint (course_api). 66 00:04:16,882 --> 00:04:25,604 All right, so, courses_api, and courses_api. 67 00:04:29,844 --> 00:04:31,480 There we go, okay. 68 00:04:31,480 --> 00:04:34,740 So I should be able to get a list of my courses. 69 00:04:34,740 --> 00:04:40,910 So if I go to /api/v1/courses, cool. 70 00:04:40,910 --> 00:04:45,750 There's my courses and my fake course that's in there. 71 00:04:45,750 --> 00:04:47,020 All right, so that's awesome. 72 00:04:47,020 --> 00:04:47,920 There it is. 73 00:04:47,920 --> 00:04:54,540 Now I'm enforcing the API versioning, the versioning number right here in the URL. 74 00:04:54,540 --> 00:04:55,980 Right that's what I have the /v1. 75 00:04:55,980 --> 00:04:59,950 This is pretty common and it's probably the easiest solution. 76 00:04:59,950 --> 00:05:02,880 This is probably what you'll find yourself doing most of the time. 77 00:05:02,880 --> 00:05:07,060 And this way you're keeping the resource and the API right next to each other. 78 00:05:07,060 --> 00:05:09,110 But you can also do this in the blueprint. 79 00:05:10,340 --> 00:05:12,240 I kinda like that solution a little bit better too. 80 00:05:12,240 --> 00:05:14,190 It feels a little bit cleaner. 81 00:05:14,190 --> 00:05:17,380 Let me show you that one for reviews, and 82 00:05:17,380 --> 00:05:19,320 you can decide which one that you like better. 83 00:05:19,320 --> 00:05:22,754 So up here at the top, we're gonna import Blueprint. 84 00:05:22,754 --> 00:05:25,774 And we're gonna import API just like we did before. 85 00:05:27,974 --> 00:05:34,278 And then down here, reviews_api=Blueprint( 86 00:05:34,278 --> 00:05:40,133 'resources.reviews, __name__), 87 00:05:40,133 --> 00:05:44,049 api= Api(reviews_api). 88 00:05:44,049 --> 00:05:49,923 api.add_resource, and ReviewList and 89 00:05:49,923 --> 00:05:54,661 I'm just gonna put in /reviews. 90 00:05:54,661 --> 00:05:56,816 And my endpoint is gonna be reviews. 91 00:05:56,816 --> 00:06:00,963 And then api.add_resource. 92 00:06:00,963 --> 00:06:05,690 Review, and here I'm gonna put reviews. 93 00:06:05,690 --> 00:06:12,295 And then of course again my int:id argument and endpoint = review. 94 00:06:12,295 --> 00:06:13,490 All right. 95 00:06:13,490 --> 00:06:16,790 So I didn't put any of the versioning numbers in here. 96 00:06:16,790 --> 00:06:21,772 So I'm gonna come back over here to app.py and 97 00:06:21,772 --> 00:06:27,156 from resources.reviews import reviews_api. 98 00:06:27,156 --> 00:06:33,378 And then here, app.register_blueprint(reviews_api), 99 00:06:33,378 --> 00:06:35,200 just like before. 100 00:06:35,200 --> 00:06:41,910 And then we're gonna do this url_prefix='/api/v1'). 101 00:06:41,910 --> 00:06:46,570 And so this does the same work, but we're doing it where we register 102 00:06:46,570 --> 00:06:50,180 the blueprint instead of where we create the resource. 103 00:06:50,180 --> 00:06:52,900 So it's kind of six of one half a dozen of the other. 104 00:06:52,900 --> 00:06:57,280 So if we go here to reviews, then we get our reviews. 105 00:06:57,280 --> 00:06:58,680 Now have the same URL pattern, 106 00:06:58,680 --> 00:07:02,030 but I've defined them in two different ways in two different places. 107 00:07:03,180 --> 00:07:07,540 Like I said you can pick whichever one of these URI methods that you like better. 108 00:07:07,540 --> 00:07:09,872 I'll leave them both implemented throughout the course though, so 109 00:07:09,872 --> 00:07:11,330 that you can see them both multiple times. 110 00:07:12,680 --> 00:07:14,944 Blueprints actually took me quite a while to figure out. 111 00:07:14,944 --> 00:07:18,827 They're not 100% intuitive, but once you get the basic ideas of them down you'll be 112 00:07:18,827 --> 00:07:22,670 able to use them to make your Flask projects cleaner and better organized. 113 00:07:22,670 --> 00:07:25,220 They open up a whole new world of Flask project design.