Full Web Apps with FastAPI Transcripts
Chapter: Dynamic HTML templates
Lecture: Organizing view methods
0:00 Let's pause building our application for a minute and actually do a little bit of organization.
0:04 What's going on here? We have got our one file where everything is in
0:08 here and right now it's only 20 lines of code.
0:11 It's no big deal. But as this grows,
0:13 is going to get larger and larger and larger.
0:15 We've got to read stuff from configuration files or secret files, for our passwords
0:19 potentially like to our database connection.
0:21 We've got to set up the database connection.
0:23 We're already setting up the templates.
0:25 Maybe we're setting up other things,
0:26 like routing and so on, as you will see,
0:29 and it's gonna be a real mess for a real application.
0:32 So what I want to do is first sketch out what we might expect to build
0:37 here. So we're gonna go over here.
0:39 I want to say, @app.get there mostly gonna be,
0:42 but not all, gets. I'm gonna go over here and have an about,
0:46 let's just have these be empty for a moment.
0:51 We're gonna have this about function and like these are the sort of the homepage overall
0:56 type of things. But we're also gonna have,
0:58 say, account management. So let's go over here and have a an index for the
1:03 account. Although in this case,
1:07 because it's in the same file,
1:09 we'll maybe call it not index,
1:10 but you'll see that we don't really want to. For the url it's gonna be "/account"
1:13 And we're gonna have a way to register for the site.
1:17 So this could be "/account/register".
1:20 This will be register. We're actually gonna have one to accept a get and one
1:25 to accept a post. Talk more about that later.
1:28 Also gonna have a login and we're gonna have a logout and so on.
1:42 As you can see, this has started to get really not so nice.
1:46 And this is just scratching the surface.
1:49 Also in our templates over here we have a big pile
1:52 of dough. So what I want to do is just take a moment and talk about
1:54 reorganizing these for a larger application that
1:58 looks like this. What I'm gonna dio is I'm going to go and create a
2:02 folder for all of our views and call it views.
2:06 And then I'm gonna further organize this.
2:09 Say well, over here we're gonna have the home views and over here we're going to have
2:15 Let's say the views that go with account.
2:19 We're also gonna have stuff about packages like package details,
2:22 package list, search package and so on.
2:25 So I'll call that packages like this and so on.
2:29 And then what we're going to do is move some of these over.
2:32 So, like these two right here,
2:34 this should be about. That's it. Let's move those over into home.
2:44 You're gonna need to import some stuff like that.
2:49 Notice this is a problem. Will fix this in a second.
2:52 We have our account things. So here's the three about account, like that.
2:59 We're also gonna need that same template thing.
3:01 So I'm gonna go ahead and just rob that from up here.
3:04 So we got it. Put that at the top of account as well and packages
3:12 we'll put some stuff in here eventually.
3:14 OK, but this is a problem,
3:18 isn't it? If I try to run this,
3:20 I don't think it'll crash or anything.
3:22 It's just gonna give me 404. That's weird.
3:24 Why? well, remember the way it worked is we load up this main file
3:29 and everything that was listed there.
3:30 I left my logout. Everything that was listed here before we had run,
3:35 got registered. Well, now we're not doing that anymore.
3:39 So what we need to do is use something different and FastAPI
3:42 has a really great way to deal with this.
3:44 We need to import FastAPI
3:47 and then what we do is: we create this thing called API router.
3:50 So we say router = fastapi.APIRouter()
3:53 like that.
3:57 And what this lets us do is it lets us build up the various routes or
4:01 roots for my British friends. Do basically whatever you would have done with app.
4:05 You just do that here. So we've got our get,
4:08 we've got our post and so on.
4:11 And then later we say, well,
4:13 router, everything you've gathered up,
4:15 install that into the application. So we're gonna do that everywhere we were using app
4:26 Perfect, those were all good.
4:29 And let's go ahead and do this for packages as well.
4:32 OK this are all done.
4:35 If we run this. Nothing magical has happened.
4:38 It's still going to be that same "404 Not Found" that we saw right
4:41 there. Until we go over here and we say from views import home and account.
4:49 Ypu can put this all in one line if you want.
4:51 I kind of like to have it separate.
4:52 We're gonna import this and then somewhere along the way,
4:55 we need to go to the app and say include_router and the order here might
4:59 matter. So make sure you do in the order you want.
5:02 Do home, we do account,
5:06 then we do packages, clean up on that.
5:09 Not gonna need this template business over here anymore.
5:12 Now, if I run it,
5:13 it should be back to good.
5:16 Let's try. Tada! perfect. We got our anonymous user sort of passed in. This
5:22 we should we go back and we do user=abc.
5:28 Now we get our abc user right there.
5:31 Okay, So what this is gonna let us do is this unlocks the ability to
5:34 build much, much larger applications.
5:37 We can put all the stuff we need in the home here.
5:39 We do all the complicated account stuff over here,
5:42 and it doesn't all get jammed into the same file. Now,
5:45 corresponding to this, let's go over and organize this a little bit.
5:49 Because when you see index, well,
5:50 is that the index of view for home?
5:52 Or is that the index view for help?
5:55 I don't know. So I'm gonna make subdirectories here,
5:59 and what I'm gonna do is I'm gonna name them exactly the same as the view
6:03 module. So home, account and packages.
6:11 Perfect. And I'm gonna take this and
6:12 I'm gonna put it in home. Now,
6:15 PyCharm may have fixed this.
6:16 Maybe not. No, it didn't.
6:18 So what we need to do is go over here,
6:19 say home/ like that, go
6:22 templates and then whatever goes there,
6:24 let's run this one more time and make sure everything's hanging together.
6:28 Perfect, still works. So this gives us a lot more organization. Now for in
6:32 the home views. We know exactly where all the dynamic HTML is going to live
6:37 Let me do one quick change.
6:40 Here, let me rename this to pt. I renamed in here and PyCharm found that and named
6:47 it over there because the way we're naming this,
6:50 we actually, our template has a convention template
6:54 decorators, a convention that will look at the module name: home, and it will look
6:58 at the method name: index. And it says,
7:01 Where's the template folder? Well,
7:02 let's go look for home/index if you don't specify anything here.
7:08 So we can actually omit that in this case.
7:11 And look, it still works.
7:13 Cool, huh? So very,
7:15 very nice that it will go and find that over there for us.
7:19 One final thing to address over here is this.
7:21 I don't really like the way this is working here.
7:23 So what I like to do is make this a little bit more clear.
7:26 Because, as I said, it's going to get more complex and more complex and
7:29 so on. I want to define an overall function here.
7:32 I'm gonna say define a function called main and main is going to run this.
7:41 And I want to define a function called configure and actually configure, at the moment can just
7:49 do all this and here we'll say configure.
7:55 So the idea is: there's a bunch of different pieces that we're gonna be putting together here
7:59 and it'll make a little more clear where to go find those pieces.
8:02 Like, for example, in the Talk Python Training equivalent of this file the only
8:07 does what. The kind of stuff you're seeing here.
8:09 I think it's like two or 300 lines long.
8:12 You want some organization, in the end.
8:14 So one thing to be aware of, I told you about in production,
8:18 what gets run is the else stage.
8:22 This part. We wanna make sure that we still call configure over here.
8:29 Otherwise, in production you have no routes.
8:31 Nothing. It won't be good.
8:32 The other thing is, I wanna have more partitioning here.
8:35 So I wanna make that a function and that function.
8:37 So we come over here and say,
8:38 extract method, say configure_route and this one. I know right now,
8:47 simple. But let's go ahead and make a method out of it
8:50 configure_templates because, you know,
8:53 maybe you've got to do a little more work to find this thing.
8:56 And there's some path juggling and whatnot.
8:58 This feels to me a lot cleaner.
9:01 I could come in and say OK, well what do we do for the main?
9:03 When you run the app, you say I'm gonna configure it.
9:05 I'm gonna run it with uvicorn.
9:06 We could even go and be more explicit.
9:08 Say the host="127.0.0.1" I wish you could say "localhost".
9:13 I don't think you can. And then I want to configure the template and configure the
9:19 routes and then either run it directly or for running in production.
9:23 Just set it up, but don't actually call "run".
9:26 Let's just make sure everything still works.
9:28 Should be unchanged with that refactoring.
9:31 And it is everything is still working.
9:33 OK, so this gives us a really nice convention for the way that main works
9:37 and using the routers we're able to partition out the different pieces.
9:45 You very well may have APIs as well.
9:47 So you might have an API directory like this and then a views directory
9:53 like that. That's what I typically do.
9:54 But I don't think there's any reason for us to
9:57 write an API in this example course because I'm keeping it focused just on
10:00 the website. But in a real one,
10:02 you probably have both. I think PyCharm has special support for templates and for some
10:07 reason, I think it marked it up there.
10:09 If we go and say unmark is just the name,
10:12 it automatically grabbed that one. We can come over here and say mark directory as template
10:17 folder and it says, hold on,
10:18 hold on, hold on. For this project,
10:21 we don't know if you want to use Jinja or if you want to use Chameleon
10:25 or Django templates. So let's go set that. Now,
10:29 what would be nice is if you said yes and it took you to where that's
10:34 supposed to be. For some reason,
10:36 it doesn't do that. So you got to go over here and type template language
10:39 and wait a second. I noticed
10:41 over here it says None, and it gives you all these different template languages.
10:45 I'm gonna say we're doing Chameleon,
10:47 so that will give us extra support for Chameleon syntax.
10:51 But now, if I go over here,
10:54 I can type things like tal:
10:57 repeat, whatever, right? This is the syntax that will be working with for
11:01 Chameleon. And now you can see we get support in the editor for it.
11:05 To me, this is a much,
11:07 much more professional looking application that's ready to build a real, complicated app that is easy to maintain over time