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