Blueprints7:25 with Kenneth Love
One of the trickiest parts of working with Flask is having a larger, well-organized code base. Flask is really happy for you to keep everything together in a single file that makes code messy and hard to find. Splitting code bits up into separate files is the solution to this, but that darn app object gets in the way. Blueprints give us a great way to around this problem.
Since Flask is a microframework, it often gets used as a single module or 0:00 maybe a model or two and then all of the routes and logic in a single app module. 0:04 This works great until your app gets moderately complex and 0:09 you start having to use your editor search function just to find a particular piece. 0:12 Once you split everything out into separate files, 0:16 you'll likely find that it gets harder and harder to avoid circular imports. 0:18 Or a chain of imports that ends up having one file import another file that 0:22 also imports the first one. 0:26 Flask has a feature named Blueprints, and 0:29 Blueprints give us the ability to make objects that are almost like proxies for 0:31 Flask apps or other features like our API resources. 0:35 Let's hop back into work spaces and get this all wired up with Blueprints. 0:38 Okay so I need to import the Blueprint object from Flask. 0:42 I'm here inside courses.py and so I'm just gonna add Blueprint right there. 0:48 Now this might seem a little bit weird and awkward but just stick with me for 0:53 a minute. 0:57 So I'm gonna to make a blueprint that represents this entire module course.py. 0:58 I'm wanna do this down here at the bottom. 1:04 And I'm gonna say courses_api = Blueprint 1:05 ('esources.courses', which is the path to the file and 1:09 then name which is the namespace that we're in. 1:15 So it's the file all over again. 1:20 So basically this says, okay, treat this file with this namespace and 1:23 this path as being another app, another thing. 1:32 And like it's a proxy to this module that kind of sort of acts like an app. 1:36 It's not an application, this isn't a pluggable app or anything like that. 1:42 It actually kind of acts like a log to some degree. 1:46 Anything that I do to this, 1:49 all the actions that I execute on the blueprint, don't actually happen 1:50 until I register the blueprint with an actual running Flask app. 1:55 I'll show you what I mean with this next step. 1:59 We've got to add a little bit more to this file though. 2:02 So we have to actually make an API. 2:06 And it's weird that the import is capital A lowercase pi, but just whatever. 2:09 Okay, so then we're gonna say api = Api[courses_api]. 2:16 So we're making an API out of the current module, which kind of acts like an app. 2:21 Normally you pass in an app here, okay, you with me so far? 2:28 All right, let's do the next thing here so api.add_resource. 2:32 And resource we're going to add is CourseList. 2:38 And we're going to set the endpoint to be /api/v1/courses, 2:42 or this is the URL slug rather, and 2:47 then the endpoint we're actually going to call this is courses. 2:49 Okay, and then we're gonna add another one here, api.add_resource. 2:56 And this one goes to Course, and 3:02 again we're going to give it /api/v1/courses. 3:05 And then we're going to say that there's an int argument that we're gonna call id. 3:10 And then this endpoint is going to be course. 3:14 All right. 3:18 So each of these specifies the resource to add, like CourseList. 3:19 The URI to give to that resource. 3:23 And then the endpoint to name it. 3:26 This way we can be like, I want the courses endpoint. 3:27 Now you don't have to provide the endpoint name, 3:30 Flask just lower cases the name of the resource. 3:32 So like this one would become course list and this one would become course. 3:36 You'll probably find yourself wanting simpler import names, 3:40 you don't necessarily want course list as the endpoint name. 3:42 And the name can be used a few different places in Flask RESTful. 3:46 Some of those, we're gonna talk about a little bit later. 3:49 Okay so now I have to register the endpoint with the app, so 3:52 I'm going to pop back over here to app.py. 3:55 And up here after I import models I'm gonna say from resources.courses 3:59 import course.api. 4:04 And then after the app thing here I'm gonna do app.register 4:07 _blueprint (course_api). 4:12 All right, so, Courses_api, and courses_api. 4:16 There we go, okay. 4:29 So I should be able to get a list of my courses. 4:31 So if I go to /api/v1/courses, cool. 4:34 There's my courses and my fake course that's in there. 4:40 All right, so that's awesome. 4:45 There it is. 4:47 Now I'm enforcing the API versioning, the versioning number right here in the URL. 4:47 Right that's what I have the /v1. 4:54 This is pretty common and it's probably the easiest solution. 4:55 This is probably what you'll find yourself doing most of the time. 4:59 And this way you're keeping the resource and the API right next to each other. 5:02 But you can also do this in the blueprint. 5:07 I kinda like that solution a little bit better too. 5:10 It feels a little bit cleaner. 5:12 Let me show you that one for reviews, and 5:14 you can decide which one that you like better. 5:17 So up here at the top, we're gonna import Blueprint. 5:19 And we're gonna import API just like we did before. 5:22 And then down here, reviews_api=Blueprint( 5:27 'resources.reviews, __named__), 5:34 api= Api(reviews_api). 5:40 api.add_resource, and ReviewList and 5:44 I'm just gonna put in /reviews. 5:49 And my endpoint is gonna be reviews. 5:54 And then api.add_resource. 5:56 Review, and here I'm gonna put reviews. 6:00 And then of course again my int:id argument and endpoint = review. 6:05 All right. 6:12 So I didn't put any of the versioning numbers in here. 6:13 So I'm gonna come back over here to app.py and 6:16 from resources.reviews import reviews_api. 6:21 And then here, app.register_blueprint(reviews_api), 6:27 just like before. 6:33 And then we're gonna do this url_prefix='/api/v1'). 6:35 And so this does the same work, but we're doing it where we register 6:41 the blueprint instead of where we create the resource. 6:46 So it's kind of six of one half a dozen of the other. 6:50 So if we go here to reviews, then we get our reviews. 6:52 Now have the same URL pattern, 6:57 but I've defined them in two different ways in two different places. 6:58 Like I said you can pick whichever one of these URI methods that you like better. 7:03 I'll leave them both implemented throughout the course though, so 7:07 that you can see them both multiple times. 7:09 Blueprints actually took me quite a while to figure out. 7:12 They're not 100% intuitive, but once you get the basic ideas of them down you'll be 7:14 able to use them to make your Flask projects cleaner and better organized. 7:18 They open up a whole new world of Flask project design. 7:22
You need to sign up for Treehouse in order to download course files.Sign up