Welcome to a short series on learning how to build Flask web applications! đ
Flask is a micro-framework. That means it has a whole bunch of pre-written code ready for you to use to build a web application. Itâll handle a lot of the work (like routing templating) for you youâd otherwise have to build from scratch.
Larger frameworks like Django or Ruby on Rails additionally have very opinionated rules on the folder structure of your project. Flask is less restrictive. But that also means that it requires a little more code you have to write yourself. But thatâs perfect for beginners as itâll help you better understand the structure of a web backend.
Prerequisites
Iâll assume you have some previous knowledge to keep this course focused. If any of the following topics seem foreign to you, make sure to catch up on them before continuing with this tutorial.
- Using the command line (on your operating system)
- Using git
- How the internet works (client-server relationship)
- HTML (CSS and JavaScript are optional but helpful)
- Python (particularly functions, for-loops, object-oriented programming with classes)
Setup
Create a virtual environment as described here to get started.
Make sure to create a .gitignore file and include the venv
folder in it.
Donât forget to activate the environment. Then, install Flask with pip install flask
.
Side note: If youâre on macOS or work with someone who uses macOS, itâs a good idea to also add .DS_Store
to the .gitignore file. Thatâs a file automatically created by macOS containing some meta information. Itâs annoying and useless in our repository code, though.
Create a Flask App
A Flask app can be as simple as a single Python file. Most larger projects benefit from multiple files. But as we start learning, it can be helpful to have it all in one place to understand how everything is connected a little better. Later in the course, youâll learn to split your application into multiple files. Thatâs considered best practice and will help you a lot as your project grows.
But for now, create an app.py file. In it import Flask like so:
from flask import Flask
This imports the class Flask
from the package you just installed called flask
. (It actually matters whether itâs lowercase or uppercase! Usually, in Python, when a variable starts with an uppercase letter, it usually means itâs a class.)
Now, we want to create an instance of that Flask
class. So, below the import add:
app = Flask(__name__)
First, we assign a variable called app
. Throughout our code, weâll use that variable to interact with the Flask app framework. Then, we create an instance of the Flask
class with Flask()
. This means the app will represent all the class methods defined by the framework Flask, and weâll be able to use many features like routing
.
__name__
is a variable provided by Python. Itâs not related to Flask but is available in all Python programs. It represents a string and tells the Flask framework which file of your code is the main file. Right now, itâs not extremely necessary. But it will be as your app grows. So itâs best practice to have it in there from the beginning. More details on that you can find here
Now, we have Flask initialized. But it doesnât do much yet.
Creating the First Route
Youâll learn more about routes in the future. But in short, routes define the paths a client can enter, for example, in the web browser to access your backend. Without routes, your backend is not available to the public.
To create a route, we can start by defining a Python function that returns some text. Add:
def index():
return 'Hello World!'
This function just returns some text âHello World!â. I named the function index
because, in web development, you usually name the start page of your web application index
. The name of the function could be anything you like, though.
Right now, itâs just a function, though. To connect it to the Flask app, we need to add a decorator. Right above the index()
function add @app.route('/')
. This is what it should look like:
@app.route('/')
def index():
return 'Hello World!'
Decorators are a feature of the Python language but not always well known. Take a moment to read up on them if youâre new to the concept.
In short, they allow you to chain functions. What will happen here is that whenever a user accesses your web app at the route /
(which is just the domain name without any path added to it - so, e.g. codecookies.xyz/
), some magic Flask code will be executed hidden behind the app.route()
method. But because itâs a decorator, the app.route()
method will execute some code together with whatever your index()
function returns.
Starting a server
Now that we have a route defined, the last step is actually to run our app as a web server. Flask comes with a simple server pre-installed. To make use of it, add app.run()
at the end of your Python file.
Now, you can execute the python file with python app.py
and should see a server running. Itâll tell you that you can now access your server using the link 127.0.0.1:5000. You can just type in that IP in the browser and should see âHello Worldâ show up.
Very nice. But this part isnât completely done yet. Itâs common practice to hide the app.run()
behind a condition to check if the __name__
variable is equal to the string "__main__"
like this:
if __name__ == '__main__':
app.run()
Remember the __name__
variable from above? The variable will always equal the string __main__
in the file thatâs being executed. For example, if you had a separate file in your project called test.py and added to it print(__name__)
, then youâd import the test.py file in your app.py file with import test
. Then, you execute the app.py file with python app.py
. In that case, youâd see the word âtestâ printed out in the command line. If instead, you add print(__name__)
now in the app.py file, youâll see "__main__"
printed out. Try it to get a feel for it!
This gives you an idea of why we added the condition above. The condition makes sure the server is only started if the app.py file is executed directly and not executed whenever we access the file by, e.g., importing it. This will be more relevant later on.
Config and Environment Variables
Right now, youâd have to restart your server every time you make a change in your code. Thatâs a little tedious. Also, you may have noticed a little warning that tells you not to use the server in production. You see that warning because your Flask app doesnât know yet that itâs being executed on a development environment (your local computer).
To fix both those things, we can define an environment variable that tells our app that we are in a development environment. (Environment variables are variables defined outside of your project code, globally on a machine, your computer, or a server - aka âenvironmentâ. Because theyâre not defined in your project but on the environment istself, you can set an environment variable to âDevelopmentâ on your own computer and define the same variable as âProductionâ or âliveâ on a server. This way, your code knows where itâs being executed. Environment variables can also be used if you want to have a different key/password or link to a database on your server then you have on your local computer.)
There are many ways to define environment variables. But one way is to use the python-dotenv
package.
Install it, running pip install python-dotenv
. To make use of the package, weâre going to create a separate config file.
(Donât forget to run pip freeze > requirements.txt
afterward!)
Create a file called config.py. In it, import load_dotenv
from dotenv
and execute that function. It should look like this:
from dotenv import load_dotenv
load_dotenv()
We can use this file later on for other configurations if we need it.
Now, we need to tell Flask how to find the configuration. Flask has a built-in method to do that. Back in your app.py file, underneath the line where you instantiate the Flask()
class, add a new line:
app.config.from_object('config')
The code above tells Flask where to find your config file. The 'config'
is the name of the config file. If the file was named configuration.py
you should pass 'configuration'
as a parameter.
Now, we can actually create a .env file in our project folder. In it, add the line:
FLASK_DEBUG=True
đĄ If youâre using using a version of Flask older than 2.2 you have to either upgrade to the newest version of Flask for this to work or instead use the environment variable
FLASK_ENV=development
.
FLASK_DEBUG
is a predefined variable that Flask will automatically look for. If itâs set to True
, Flask knows weâre in a development environment. This will tell Flask that itâs ok to automatically restart the server whenever changes are made to the code. if you donât set this variable, the server has to be restarted by hand every time you make a change.
In a later exercise, youâll learn to deploy your application to a server. You should never set this environment variable to True
on a server where real users interact with your website!
Lastly, itâs very important that your .env file is not part of your git repository. So make sure to add it in a new line to your .gitignore file. Many people store passwords and keys in the .env file later on. Those should never show up in your repository.
Side Note: gitignore pycache
As soon as you start importing different files (aka modules), you may see a folder called pycache show up in your project. That folder contains some caching files (as you might have guessed) and is not relevant to your code. So you should also add a line with __pycache__
in it to your .gitignore file to keep your code clean.
Restart the server
Thatâs it. You have set up your Flask application. You can now stop the server with the keys Ctrl + C. Then, start it again with python app.py
. Whenever you make changes, the server will automatically reload from now on.
Recap
Thatâs it! You created a brand new virtual environment for your project and installed the Flask package using pip.
You created your first route and now know how to start a simple web server that comes with Flask. You also know how to run the web server in debug mode to make sure it restarts automatically whenever you make changes.
You also set up your project to be used with other developers (or your future self) through git by adding venv
, __pycache__
, and .DS_Store
to a .gitignore file and created a requirements.txt file with the installed packages.
This is what your project folder should look like now:
đ Practice
As you go through the tutorials, I recommend you follow along and write the code as you go through the material. Donât copy and paste but type everything by hand.
Once you have completed an exercise and written the tutorial code, I recommend you spend some time practicing what you have learned.
This section was about setting up a Flask project from scratch. To practice that a little more, set up a couple more projects entirely from scratch (including the virtual environment).
Whenever you start a new project, make sure youâre not still within the active environment of another project!! To deactivate the environment, simply type deactivate
in your command line and hit âEnterâ.
Cheat Sheet
Create a new Python virtual enviornment (Do only once in the beginning)
python3 -m venv venv
Activate the virtual environment (Itâs active if you see (venv)
in the terminal)
macOS & linux:
source venv/bin/activate
Windows:
venv\Scripts\activate.bat
Deactivate the virtual environment (e.g., when switching folders/projects)
deactivate
Install pip packages (e.g., Flask)
pip install flask
Update requirements.txt file with installed packages
pip freeze > requirements.txt
Install packages from a requirements.txt (e.g., after downloading the repo)
python -m pip install -r requirements.txt
Run the server (while the virtual environment is active)
python app.py