[0:00] which python web framework is the best [0:02] flask is considered the most popular [0:03] beginner framework django is the most [0:05] popular full stack framework offering [0:07] the most functionality and is used by [0:09] many companies in production and fast [0:12] api has only been around for three years [0:14] but it took the hearts of the python [0:15] developer community by storm [0:17] facilitating rapid development and [0:19] offering a tremendous web app speed when [0:21] comparing google trends flask is on top [0:24] closely followed by django but fast api [0:26] is rising quickly based on github stars [0:28] django is the winner but also closely [0:30] followed by flask and fast api catching [0:33] up quickly and in the speed benchmark [0:35] test fast api is the clear winner [0:37] outperforming the other frameworks by a [0:39] factor of two or even three so which one [0:41] should you use it's hard to give one [0:43] clear recommendation because as always [0:45] the answer depends each framework has [0:47] its own strengths and weaknesses and all [0:50] of them are great so in this video i [0:52] created the same to-do app with all [0:53] three frameworks in the process you [0:56] learn how to use each framework and [0:57] hopefully get a better feel for the [0:59] trade-offs between each of these so in [1:01] the end you can make the best choice for [1:03] your next project the project we are [1:05] going to build is a simple to do app [1:07] providing functionality to add update [1:10] and delete to-do's for each app you'll [1:12] learn how to use a database use html [1:14] templates and implement the api routes [1:17] so let's get started let's start with [1:19] flask flask is well established in the [1:21] python community it is loved by [1:22] beginners and experts for its simple [1:25] syntax while still being capable of [1:27] managing full-blown production-ready web [1:29] apps so let's see how to do it first i [1:31] recommend to create a virtual [1:32] environment and then activate it then we [1:34] need to install flask and also flask sql [1:37] alchemy to work with a database then we [1:39] create one file app.pi and import all [1:42] classes and functions from flask that we [1:44] need the convention is always to create [1:46] an app instance with a double underscore [1:48] name and then creating a route is as [1:51] simple as defining a function and using [1:53] the appropriate decorator here we say [1:56] app.get and then a simple forward slash [1:58] since this is our home page this would [2:00] now display hello world on the website [2:03] in order to use the database we import [2:05] sql alchemy now we have to set some [2:08] configuration variables for example the [2:11] name or path to the database here we [2:13] simply use a sqlite file and then we [2:16] create a database instance by using sql [2:19] alchemy and passing the app to it now we [2:21] create a model for the database so we [2:23] create a class to do that inherits from [2:26] db.model and we give it three columns [2:28] with the appropriate data type we want [2:31] an id a title and a complete flag for [2:34] the to-do item and then we call [2:36] db.createall to create and initialize [2:38] our database [2:40] now of course we want to use this so in [2:42] the home route we call [2:44] db.session.query2do to retrieve all [2:46] to-do items and then we use the render [2:49] template function from flask with a [2:51] template file name and the to-do list is [2:53] additional arguments so that we can use [2:55] it in the html code of course we need to [2:58] create the template so we have to create [3:00] a folder named templates and then a file [3:02] that we call base.html [3:04] and here we can use normal html code [3:07] that displays a form and all to do items [3:10] now what is special here are these curly [3:12] braces with percent characters this is [3:15] special ginger 2 template syntax that [3:17] basically allows us some python-like [3:19] logic for example we can have a for loop [3:22] where we iterate over all to-do's and [3:24] show the id and title for each to-do [3:26] then we have an if-else statement to [3:28] check the complete flag and show the [3:30] label in a different style and then we [3:32] also need closing statements for the if [3:34] and also for the for loop we also create [3:36] two links that are the buttons to update [3:39] and delete a to do and the important [3:41] part is that the ahref points to the [3:43] update and delete route for this [3:45] particular to-do id please note that [3:48] these will be get requests which is not [3:50] a best practice for updating and [3:51] deleting data but it works and for [3:53] simplicity i will use it like this now [3:55] we go back to the app.pi and can [3:57] implement the remaining routes first [4:00] let's create a route to add a new item [4:02] this has the [4:03] app.postdecorator since it should be a [4:06] post request we get the title [4:08] wirerequest.form and then we create a [4:10] new to-do item and call [4:13] and db.session.add.com the changes as [4:15] last step in here i use the redirect [4:17] function together with the url4 function [4:19] to redirect and load the updated home [4:21] page the update route works similar here [4:24] we query the particular to-do item with [4:26] the id remember that we also specified [4:29] the id in the html code then we update [4:32] the complete flag commit the changes and [4:34] again redirect to the home page and the [4:36] delete route is the very same code [4:38] except that here we delete the to-do and [4:40] that's it 49 lines of code is all we [4:42] need super simple and straightforward [4:44] this is where flask really shines it [4:46] won't be that quick with the other two [4:48] frameworks now to run the app we can [4:50] export the environment variables flask [4:52] app equals app.pi and flask n equals [4:56] development to get hot reloading and [4:58] then we say flask run to start their [5:00] development server and now we can add [5:02] new to-do's update them and also delete [5:04] them [5:05] next let's use fast api it's one of the [5:08] fastest python web frameworks out there [5:10] right now it also provides an easy [5:12] syntax allows for rapid development and [5:14] offers some more nice to have features [5:16] like automatic interactive documentation [5:18] and type validation that's why [5:20] developers love it and it's rising so [5:22] fast in popularity that i think it will [5:24] soon catch up with flask and django [5:26] let's create a new virtual environment [5:27] for this project then we need to install [5:30] fast api we also need an asgi server for [5:33] example uv corn and for the template [5:36] files and database support we need [5:38] python multipart sql alchemy and ginger [5:41] 2. these are essentially the same [5:43] dependencies as we get with the flask [5:45] and flask sql installation here we [5:47] create three files app.pi models.pi and [5:50] database.pi we need a little bit more [5:52] code for each compared to flask and we [5:54] want to maintain a clean project [5:56] structure the basic app will be very [5:58] similar to before we import fast api [6:01] create an app instance and create a [6:03] function that we decorate with app.get [6:05] here we return a dictionary which will [6:08] be automatically converted to a json [6:10] response one cool thing to mention here [6:12] is that we could also declare the [6:14] function as async dev since fast api [6:16] supports asynchronous programming out of [6:19] the box and allows for an extremely fast [6:21] web app but for simplicity i'll stick [6:23] with a normal function here fast api [6:26] heavily relies on tie pins so if we want [6:28] a dynamic route we use this syntax we [6:31] put the argument in curly braces in the [6:33] route and then we use the same name as [6:36] function argument together with a type [6:38] hint in this case it should be an [6:39] integer this is concise reduces bugs and [6:42] gives us automatic type checking which [6:44] we will see later so let's continue with [6:47] our to-do app we need a few more imports [6:49] from fast api we also import a few [6:52] requirements from starlet this is the [6:54] asgi framework that fast api is built on [6:57] top of then we specify our template [7:00] directory and use a template response in [7:02] the home function we pass the request as [7:04] argument and also the database which is [7:07] a session object that depends on another [7:09] function don't worry about this syntax [7:11] yet it will become clear in a moment but [7:13] note that again for each argument we are [7:15] using typins here and then again we [7:17] query the database for all to do's and [7:20] return a template response that needs [7:22] the html file the request and the to-do [7:24] list in this case the arguments for the [7:27] template file are passed as dictionary [7:29] now we also create a template directory [7:31] and the base.html file and here we can [7:34] use the exact same code as before since [7:36] we are also using ginger 2 templating [7:39] syntax now let's set up the database we [7:41] get the imports and set up the path to [7:43] the sqlite database then we need to [7:45] create an engine we also need to create [7:48] a session instance and lastly we declare [7:50] the base class from which the model will [7:52] inherit in the next step for the model [7:54] we import the database and this base [7:56] class we just declared and then we [7:58] create a to-do class that looks very [8:00] similar to the one from the flask app [8:02] but now we inherit from base then we [8:04] define a table name and use the same [8:07] fields as before now we can go back to [8:09] app.pi and make use of all of this we [8:12] import the session class so we can use [8:14] it as type hint we import the models the [8:16] session local object and the engine then [8:19] we create all database tables and then [8:21] we create a helper function to access [8:23] the data by session this will now be [8:25] passed to the home function as a [8:27] dependency which means if the database [8:30] cannot be accessed then also the request [8:32] to this route throws an error and this [8:34] is already handled for us by fast api so [8:37] you can see we need a little bit more [8:39] code here but in return we get a lot [8:41] more functionality already and a safer [8:44] code now inside the function we can use [8:47] the session object and query the [8:48] database with the same syntax as in the [8:50] flask app let's continue and add the add [8:53] route which must be a post request [8:56] as parameter we also use the request and [8:58] the database and now as new argument we [9:01] also put in the title which is a string [9:04] that comes from the form and then again [9:06] we create a new to-do added to the [9:08] database and commit the change and then [9:10] i get the url of the home page and [9:12] return a redirect response i also [9:14] specify a particular status code which [9:17] is needed because we now change from a [9:19] post route to a get route very similar [9:21] we now add the update route and as [9:23] mentioned before we use the to do id as [9:26] dynamic argument with a tie hint then we [9:28] query the to do change the complete flag [9:31] commit the change and again redirect to [9:33] the home page and finally we use the [9:35] same code for the delete route but here [9:37] we delete the to-do item and that's it [9:39] we can now start a server by saying [9:41] uvicorn app colon app the first is the [9:44] file name and the second is the app [9:46] instance we also use minus minus reload [9:49] while we are in development mode and [9:50] then we can go to this address and have [9:52] a working to-do app one more cool [9:54] feature we also get out of the box with [9:57] fast api is automatic api documentation [10:00] so we can go to the slash docs route and [10:03] here we see all the different api [10:05] endpoints together with the type for [10:07] example we can click on the add post [10:10] endpoint and then we see more details [10:12] like that it needs a title as string we [10:14] can also try this out enter a title and [10:17] execute the command and then we can [10:19] inspect the result so here we see we get [10:21] the response code 200 so all is good and [10:24] we see the raw template response that is [10:26] visible on the page we could also try [10:29] another route so let's test the update [10:31] route this needs a to-do id as integer [10:34] so if we try to send a string here then [10:36] it wouldn't let us and on the page we [10:38] would see an error code and again all of [10:41] this is handled for us by fast api and [10:44] this is possible because we used the tie [10:46] pins all right and that's the to-do app [10:48] with fast api i hope i could demonstrate [10:50] some of the cool features here now for [10:52] the final app we use django while flask [10:54] and fast api are considered to be more [10:57] like a micro framework change is a full [10:59] stack framework with many batteries [11:01] included it's the backend framework of [11:03] choice for many fortune 500 companies [11:05] while the learning curve might be [11:06] steeper than with the others it offers [11:09] so many features that it makes your life [11:11] easier once you know your way around it [11:13] again i start by creating and activating [11:15] a virtual environment then we only need [11:17] to say pip install django this comes [11:19] with all the requirements that we need [11:21] now we say changu admin start project [11:24] and give it the name to do app this [11:26] creates a new folder and inside the [11:28] folder we have the manage.py file and [11:31] another subfolder with the same name and [11:33] all the starter files we need we cd into [11:36] the first folder and can run python [11:38] manage.pi run server this starts the [11:41] server and we have the initial app up [11:43] and running for now we quit the server [11:45] again and say python manage.pi start app [11:48] and the name to do list an app is a [11:51] component inside a project that is [11:53] responsible for certain things like here [11:55] for managing the to-dos in this simple [11:58] project this is the only app we need but [12:00] imagine if we add authentication then we [12:03] could put this in another app to keep [12:05] the logic separate and clean after [12:07] creating an app we also need to add the [12:09] app name to the installed apps in the [12:11] settings.py file now we want to add the [12:14] views so inside to do list.views pi we [12:18] add a function that gets a request and [12:20] then we return the render function with [12:22] a template name and this dictionary all [12:24] items we want to pass the missing to-do [12:27] part will be implemented in a moment for [12:29] each view we need to register a url so [12:32] we create a urls.pi file inside the [12:35] to-do-list folder import the path [12:37] function the views module and then we [12:39] define all url patterns we want to add [12:42] in this case we leave the route of the [12:44] path empty since this is our home page [12:47] and then we use the corresponding [12:48] function and can also give it a name now [12:50] we go to the to do app.urls.pi [12:54] and use the include function to include [12:56] all urls from the to do list app you can [12:59] see that there already exists an admin [13:01] path this is because django gives us an [13:03] admin panel out of the box which we will [13:05] see in a moment now we will need to [13:07] create the template file so let's create [13:09] a new templates folder in the top [13:11] directory and then we again create the [13:13] base html file and put in the same code [13:16] django uses its own templating language [13:19] which is similar but slightly different [13:21] than the ginger 2 template but in this [13:23] case we only have a for loop and an if [13:26] statement and this is actually the very [13:28] same syntax but there is one thing we [13:30] need to change in the form part we need [13:32] to add the csrf token this is a security [13:36] mechanism that prevents attacks to the [13:38] form but we don't need to do more than [13:40] adding this here now we need to go back [13:42] to the settings.py and add the templates [13:45] folder to the directories key now we [13:47] implement the model class so inside the [13:49] to-do list models.py we create a class [13:52] that inherits from models.model and then [13:55] we again create the same fields with the [13:57] correct data type and we also implement [13:59] the string method to see an accurate [14:01] description here we don't need to create [14:03] an id since django does this for us now [14:06] in the console we say python manage.pi [14:09] make migrations followed by [14:11] pythonmanage.pi migrate then we also [14:14] create a super user because i want to [14:16] show you the admin panel so we say [14:18] python manage pi create super user we [14:21] follow the instructions and put in a [14:23] name and email and the password as next [14:25] step we go to the admin.py and register [14:28] the to-do model and now we go back to [14:31] the views.pi import the to-do class and [14:34] then query all to-do's in the index [14:36] function let's run the server again and [14:38] test this we see the home page with zero [14:41] to-do's for now if we click on the add [14:43] button we get an error since we haven't [14:45] implemented this view yet but one cool [14:47] feature that is already available is the [14:49] admin panel so if we go to the slash [14:52] admin route we can log in with the super [14:54] user we created and here we can see [14:57] different groups and users if we would [14:59] add authentication we also see the to-do [15:01] models with all the fields we specified [15:04] and here we can interact with our [15:06] database so we could add or modify the [15:08] database entries right from the admin [15:10] panel this is one very cool built-in [15:13] feature that you don't get with the [15:14] other frameworks so now let's log out [15:17] again and implement the missing views so [15:19] we import two more functions and then [15:22] implement the add route we require that [15:24] this should be a post method by using [15:26] this decorator we could also check the [15:29] type of the request inside the function [15:31] but i wanted to show you this second way [15:33] of doing it inside the function we then [15:35] create and save a new to-do and redirect [15:38] to the index page now we implement the [15:40] update function this gets an additional [15:43] parameter to do id which is then be used [15:46] to query for this to do and then we [15:48] change the complete flag and save it and [15:50] again redirect the syntax for working [15:52] with django models is slightly different [15:55] than before but in my opinion it's even [15:57] more simple and straightforward and the [15:59] last view we need is the delete view [16:01] which is very similar but here we delete [16:03] the to do and now we only need to add [16:05] all these views to the urls.py [16:08] so in here we add all the paths with the [16:10] corresponding route and view function we [16:13] can use this syntax with a data type and [16:16] parameter name to add dynamic views and [16:18] that's it we can now go back to our app [16:21] and we should be able to add new to-do's [16:23] and then update and delete them awesome [16:26] alright that's it you can find the code [16:28] for all apps on github the link is in [16:29] the description this video was a lot of [16:31] work so if you enjoyed it please hit the [16:33] like button i'm also interested to hear [16:35] what's your favorite framework so please [16:37] leave me a comment below and as always i [16:39] hope to see you in the next video bye