I’m currently doing some online courses on web development, learning a bit about Flask before moving on to Django. This blog post is a brief introduction to Flask (micro)framework and its installation on Ubuntu server. In this post we will look into how to install Flask and run flask applications.
What is Flask? Flask is a microframework written in Python. “Microframework”, in this case, supposed to be understood as “expandable and lightweight”, rather than “restricted and limited”. But “expandable” part, does translate into the fact that you need to write more code for things which are not included in favor of “lightweight” (but there are lots of extensions which can make your life easier). Some people would say that Flask is your best option for prototyping, whereas you may want to investigate other options/frameworks for large scale production projects. As with any technology choice final decision is yours and it should be largely defined by your existing expertise and specific task(s) at hands.
Architecturally Flask includes two big parts: a web server and a templating engine which simplify creation of web applications. With help of those components you can leverage concepts of routes (defined URLs which your app can recognize and reply to with HTML) and use Jinja2 web templating engine for the Python programming language (which allows you to write HTML templates with variables and control flow statements).
Here is how routes definition may look like in your application code:
As I already mentioned Jinja2 syntax allows you to use variables and conditions/flow control statements inside of HTML code creating dynamic web applications.
Hopefully that gives you a bit of an idea of what is Flask and to avoid theoretical information overflow, I will move on to more practical aspects of the subject. Let’s have a look at how we can install Flask on Ubuntu 18.04 and run Flask applications.
Flask installation has number of dependences which installed along with Flask, and more specifically the following gets installed:
Werkzeug to implement WSGI as a standard Python interface between applications and servers.
Jinja – template language that renders the pages your application serves (it also installs MarkupSaf to escape untrusted input when rendering templates to avoid injection attacks).
ItsDangerous for secure signing of data to ensure its integrity (used to protect Flask’s session cookie).
Click – a framework for writing command line applications. It provides the flask command and allows adding custom management commands.
Optional dependencies include Blinker, SimpleJSON, python-dotenv and Watchdog.
List above is intended just to give you a feel of what’s involved in case you would like to go into details about innerworkings of Flask (which you will probably need to do in case you will be building some real/complex projects using it). But don’t rush into issuing pip install Flask, as you need to learn something else first.
And this something else is an idea of virtual environments. With Flask we use virtual environments to manage dependencies for Flask projects (both in development and in production). Essentially, we do this to ensure certain level of isolation for different projects to avoid conflicts amongst different versions of Python libraries and/or Python which may vary per each project. As per Flask documentation “Virtual environments are independent groups of Python libraries, one for each project. Packages installed for one project will not affect other projects or the operating system’s packages”.
Ubuntu 18.04 includes Python 3 by default, and, according to Flask documentation, Python 3 comes with the venv module allowing you to create virtual environments (in case you are using Python 2 it will be necessary to install virtualenv first). To create virtual environment, we use python3 -m venv venv command. On my Ubuntu 18.04.2 LTS installation first attempt to create virtual environment failed due to missing ensurepip module:
Corrective steps for this problem are provided in error message itself, namely we just need to run sudo apt-get install python3-venv -y to install python3-venv as shown below:
Once ensurepip module installed, we can create virtual environment as demonstrated below (we first create virtual environment directory using mkdir command, and after changing directory with cd we then create virtual environment itself):
Once created, virtual environment needs to be activated by means of issuing . venv/bin/activate command:
You can tell that environment is activated by changed command line prefix (as you can see it contains “(venv)” before username@server). Finally, having virtual environment created and activated, we are ready to install Flask into it (pip install Flask):
At this point we have virtual environment with Flask installed, and we can start creating Flask applications and testing them.
For development and testing scenarios you may want to enable debug mode which allows Flask ааweb server to pick up code changes dynamically without restart. You can do that by issuing export FLASK_ENV=development command (in Windows environments you would use SET instead of EXPORT):
This setting tells flask run to use the interactive debugger and reloader by default. With debug mode enabled we can run Flask by issuing flask run command:
As you can see from the screenshot above Flask is running on default port 5000 and you can try accessing Flask web server using web browser:
You should get NoAppException, which is expected as we have not created any Flask app yet. Let’s do this now.
Overall flow of the process here is that we first create Python application file using your favorite editor inside of your environment folder (“test_flask_project” in my examples here) and then pass this file name as a value into FLASK_APP environment variable so that Flask server loads it on startup.
Let’s stop Flask server using Ctrl + C and create canonical “Hello world” example app.
Example 1. “Hello world!”. Inside of our virtual environment we need to create HelloWorld.py file and add the following code into it:
To explain these lines of code, what we do is just importing Flask module (line 1, be sure to capitalize module name), we then create Flask server object naming it after the script we are running – “__name__” (line 3), and then adding default app route (line 6), specifying Flask response for this route in the form of a function (lines 7-8). Note that bare minimum example can just use some literal text value in quotes for return, but I’m using f prefix (supported in Python 3) which allows use of HTML tags inside of return value to set site title and return “Hello world!” formatted as a header.
Once you saved this file in the root of your virtual environment directory as “HelloWorld.py” you can set FLASK_APP to HelloWorld.py and start Flask:
If you then navigate to in your browser you can see this app in action. Instead of NoAppException you should see something like this:
In the second example we will do the same but using html template for route response.
Example 2. “Hello World!” using HTML template. When working on real world Flask apps you would want to display quite complex web pages and hence it makes sense to separate them into regular HTML files instead of cramming them into your Flask app code. There we have approximately the same logic as in HTML/CSS split – with HTML/CSS we are dividing document structure and design, and with Flask templates we divide application code/logic from HTML documents themselves. Let’s redesign our first example with use of HTML template. This capability enabled by Jinja2 template engine and use of render_template() method. First, we need to create “templates” folder inside of our virtual environment directory, and create index.html file with the following content there:
As you can see it is more or less the same HTML that we had inside of return value of example 1, but now we have it written in plain HTML stored as a separate file (that’s more readable and we can also make use of CSS if necessary). I’ve only changed header color so that we can see some visual difference after making these changes in our app. Once we have our HTML template, we need to do slight adjustments to our original HelloWorld Flask app we created earlier:
We just importing render_template and use render_template function to return index.html (note that we don’t need to specify path to the file as Flask looks for the files in templates folder by default).
As long as you run Flask in debug mode (environment=development) your app code changes will be picked up without Flask server restart, so you can just refresh your browser page to test your changes:
As a final step for now, let’s add use of variable/conditions in our app now.
Example 3. “Hello World!” using HTML template with variable/condition. Let’s add some variables into our Flask app code as shown below:
As you can see we just import datetime and calendar modules (lines 1 and 2), then setting couple of variables to get current weekday and its name (lines 10 and 11) – this is all pure Python, and we next append our return_template() function indicating there that we want to return these variables for this route – which will enable us to use them inside of HTML template as shown below:
As you can see, we use {{ }} to enclose variables and {% %} to enclose conditions inside of plain HTML syntax. As a result, we have dynamic HTML page which will be displaying different content based on current day of the week. Here is an example screenshot of this Flask application running in the browser:
There are much more things which you can do with Flask, for example work with sessions, but covering everything is not possible in one post (especially when the focus is “introduction/installation”). But, I believe, that if you followed through the steps and examples above you now have an idea on how to install Flask and run Flask apps (and even about some basics of creating Flask apps) – the rest boils down to following numerous examples from Internet and Flask documentation or trying to implement some little project on Flask. I hope that this post has been useful for you, thanks for reading! 😊