Setting Up Project
Instead of following the trivial way to set up a project, we’re going to follow a slightly more elaborate way that will give us a good base structure for scaling our application. You can learn more about this here.
The application will exist in a package. In Python, a sub-directory that includes an __init__.py file is considered a package and can be imported. When we import a package, the __init__.py executes and defines what symbols the package exposes to the outside world.
Let’s create a package called
app, that will host the application.
$ mkdir app
The __init__.py for the
app package is going to contain the following code:
The script above simply creates the application object as an instance of class
Flask imported from the flask package. The
__name__ variable passed to the
Flask class is a Python predefined variable, which is set to the name of the module in which it is used. Flask uses the location of the module passed here as a starting point when it needs to load associated resources such as template files. For all practical purposes, passing
__name__ is almost always going to configure Flask correctly. The application then imports the
routes module, which doesn't exist yet.
One aspect that may seem confusing at first is that there are two entities named
app package is defined by the app directory and the __init__.py script and is referenced in the
from app import routes statement. The
app variable is defined as an instance of the class
Flask in the __init__.py script, which makes it a member of the
Another peculiarity is that the
routes module is imported at the bottom and not at the top of the script as it is always done. The bottom import is a workaround to circular imports, a common problem with Flask applications. We are going to see that the
routes module needs to import the
app variable defined in this script, so putting one of the reciprocal imports at the bottom avoids the error that results from the mutual references between these two files.
So what goes in the
routes module? The routes are the different URLs that the application implements. In Flask, handlers for the application routes are written as Python functions, called view functions. View functions are mapped to one or more route URLs so that Flask knows what logic to execute when a client requests a given URL.
Here is our first view function, which we need to write in the new module named app/routes.py:
This view function is actually pretty simple, it just returns a greeting as a string. The
@app.getline above the function is decorator, a unique feature of the Python language. A decorator modifies the function that follows it. A common pattern with decorators is to use them to register functions as callbacks for certain events. In this case, the
@app.getdecorator creates an association between the URL given as an argument and the function. In this example, the decorator associates the URL
/ to this function. This means that when a web browser requests this URL, Flask is going to invoke this function and pass the return value of it back to the browser as a response. If this does not make complete sense yet, it will in a little bit when we run this application.
To complete the application, we need to have a Python script at the top level that defines the Flask application instance. Let’s call this script main.py, and define it as a single line that imports the application instance:
Remember the two
app entities? Here we can see both together in the same sentence. The Flask application instance is called
app and is a member of the
app package. The
from app import app statement imports the
app variable that is a member of the
Now, since we are using an extensible way to set up our project, we’ll define SECRET_KEY(required for secured sessions) and DEBUG variables in a separate file called config.py at the top level. Add the following in the config.py file :
The configuration settings are defined as class variables inside the
Config class. As the application needs more configuration items, they can be added to this class, and later if we find that we need to have more than one configuration set, we can create subclasses of it.
Also, we can now replace the code in __init__.py with the below code:
In the above code, we just asked our Flask app to use the configurations as mentioned in the Config class.
Our project has been set up successfully and we are ready to run it using the below command :
$ python main.py