Report 5 on Linux course - Developing Python Flask apps on Linux

Feb. 4, 2020

This week our assignment was to play around with Python Flask and making deployment ready version of the application

Report 5 on Linux Course

Installing Python Flask on a Linux environment

Flask is a framework for Python that is great for building light web applications with Python.

Installing Flask on Python can be done by running the commands:

sudo apt-get update - To download the most recent package information from the package manager

sudo apt-get install python3-flask - To install Flask for Python 3

There is mostly no reason not to use Python 3 but apparently older versions are still supported because some bigger software companies for example might be using older versions of Python in their products and the refactoring cost/benefit would be too big in most cases.

a) Create a “Hello world!” -application on Python Flask

Flask can simply be imported to a Python application.

Below is an example code.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
return "Hello Flask!"

app.run(debug=True)

The app.run(debug=True) is only recommended for development environment. It would not be safe to leave the True value here for production environments.

b) Make a production installation of a Flask application

For this I'm going to be installing Apache as the web-server with the following commands:

sudo apt-get update
sudo apt-get -y install apache2

After this I created new separate user for the app.

sudo adduser mikkowsgi

Then lock the password -login for the user

sudo usermode --lock mikkowsgi

I added myself to the new user's group

sudo adduser $(whoami) mikkowsgi

The $(whoami) -line simply prints the currently logged in user's name

Next I created a name based virtual host by editing the .conf -file on sites-available -folder

sudoedit /etc/apache2/sites-available/mikkowsgi.conf

<VirtualHost *:80>
ServerName example.com

WSGIDaemonProcess mikkowsgi user=mikkowsgi group=mikkowsgi threads=5
WSGIScriptAlias / /home/mikkowsgi/public_wsgi/mikko.wsgi

<Directory /home/mikkowsgi/public_wsgi/>
WSGIScriptReloading On
WSGIProcessGroup mikkowsgi
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
</VirtualHost>

After this I created the symlinks, so I basically linked the files in sites-available folder to the sites-enabled folder

sudo a2ensite mikkowsgi.conf
sudo a2dissite 000-default.conf

Installing the WSGI is done with command

sudo apt-get -y install libapache2-mod-wsgi-py3

Restarting apache server with command

sudo systemctl restart apache2

I also ran the configtest just to make sure the syntax on .conf file is ok and the test went through fine.

apache2ctl configtest

Now that the virtual host was in ok -condition I installed the app.

I created the folder for the application

sudo mkdir /home/mikkowsgi/public_wsgi

I fixed the permissions for the users to allow everyone in the group to edit the files

sudo chown mikkowsgi:mikkowsgi /home/mikkowsgi/public_wsgi

sudo chmod g=rwxs /home/mikkowsgi/public_wsgi

Finally I created the .wsgi file

sudo vim /home/mikkowsgi/public_wsgi/mikko.wsgi

import sys
assert sys.version_info.major >= 3, "Python version too old in mikko.wsgi!"

sys.path.insert(0, '/home/mikkowsgi/public_wsgi/')
from hello import app as application

Now the application worked fine when I ran command: curl localhost, it printed out the the content of the web-page correctly.

I did not actually run into any issues with this exercise, also because I already did it in class. One easy place to mess up is in the .conf -file but that is easy to check with the configtest command mentioned earlier.

As a guide and reference I used my teacher's blogposts that related to this lectures content: terokarvinen.com

c) Adding flask templates to the production version

Templates are at it's core reusable .html -pages that can be used for example on web-pages that have similar pages with only different content. This blog uses Django Wagtail CMS and every blog post uses 'blog' -template. It would be simply insane to re-write/copypaste same html for every different blogpost. Django also has the same basic logic when it comes to templates. This concept should be pretty familiar for anyone who has done web-development.

Below is an example my templates-flask.py -file

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def templates():
return render_template("base.html", greeting="Hello Templates!")

app.run(debug=True)

When it comes to the actual .html -file, the greeting specified in the .py -file can be inserted with ({greeting}) -code for example in the middle of <p> </p> (paragraph) tags in a .html file. This does open up a lot of interesting opportunities and allows reusable code snippets.

Return to blog