• Home
  • About
    • Gregory S. Fellis photo

      Gregory S. Fellis

      Problem Solver | Code Slinger | Python Enthusiast | Lifelong Learner | Ravenclaw

    • Learn More
    • Resume
    • Email
    • Twitter
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

100 Days of Code - Day 2: Flask

Wednesday, January 2, 2019 @ 06:31:00 PM EST

Reading time ~5 minutes

Flask


I’m beginning a new project in my spare time for work. Many years ago the directive was handed down where our system operators could no longer have command line access to any of our systems. This did not bode well since the crucial component that needs constant monitoring is a Linux-based system with custom scripts designed to allow operators to do their jobs. At this time, another one of our engineers was able to piece together a “web app” that would allow the operators to perform these tasks through a web browser interface, without actually touching the command line itself. This satisfied the needs of the time.

Unfortunately, that engineer left the company shortly there after, and no one has maintained this application. I’ve taken a look into it and while I could add some functionality to it, it’s really an unwieldy mess to maintain. It’s a single file script containing everything it needs to run, laid out in, what I consider, a very unorganized mess that spits in the face of PEP 8 and 20. While I applaud the engineer for getting this working, I don’t think much thought was put into maintainability, which is something I try to consider when doing any kind of development.

So I’ve decided to reimplement this app in a modern Python Web Framework. I’ve used Bottle previously, which I enjoyed, but I thought I would give Flask a chance to see what it has to offer.

I’ll be working my way through two different Flask tutorials, the first is the official tutorial, which I’ve completed recently, and the other is the Flask Mega Tutorial by Miguel Grinberg. Both take slightly different approaches, so I’m trying to balance them as I work my way into Flask for my own project.

Like so many Python projects, I start by creating a virtual environment. I’m working in Windows 10 again, so I fire up a Powershell window, create a new folder for my project, and then create a venv folder within that to house the virtual environment. I’ve never taken this approach before, and both tutorials do it. I’m not certain if this is a convention I just missed, but I like it and will be using it in the future. Typically I’ve been making the root folder the virtual environment folder, and then scaffolding from there, but that always seemed messy to me.

With the virtual environment setup, the first thing I do is update pip, because it’s always out of date. Then I install Flask.

Powershell virtual environment and Flask installation:
python -m venv venv
.\venv\Scripts\activate

python -m pip install --upgrade pip

pip install flask

Next I create a folder which will hold the app structure. Within this folder I create the “Application Factory”, which will spawn the Flask app and establish the app folder as a Python package that can be loaded. To start I setup a very basic “Hello, World!” application in __init__.py.

project/app/__init__.py:
from flask import Flask

app = Flask(__name__)

Now I begin by figuring out my routes and templates. This is where the tutorials start do differ a bit. The official tutorial goes into database connections and blueprints. Both of which are great, but I don’t think will be needed for my project, at least not initially. So I follow Miguel’s tutorial and jump into creating routes.py file in the app folder. This will be used to define the routes that will be called by the users. For now, I’m just creating a basic route and template to get the structure started.

project/app/routes.py:
from flask import render_template
from app import app

@app.route('/')
@app.route('/index')
def index():
    msg = {"text": "Hey, is this thing on?"}
    return render_template('index.html', title="Test", msg=msg)

I need Flask’s render_template function to return Jinja2 templates which can be leveraged to load data dynamically into the HTML code. Here we’ll simulate that by defining the msg dictionary with the text and data key value pair.

I want a place to store the templates, so I add a templates folder under app, and I create a very basic HTML/Jinja2 template, index.html as specified in routes.py.

project/app/templates/index.html:
<html>
    <head>
        {% if title %}
        <title>{{ title }}</title>
        {% else %}
        <title>No Title Here</title>
        {% endif %}
    </head>
    <body>
        {% if msg %}
        <h1>{{ msg.text }}</h1>
        {% else %}
        <h1>Hello, World!</h1>
        {% endif %}
    </body>
</html>

Jinja2 uses the {% ... %} syntax for flow control and conditional statements, and the {{ }} syntax to insert data into the HTML syntax. So if title and msg data is passed into the template, it will use it, but if it’s not it will use these default values. Here this isn’t very useful, but will help me later on.

There’s a few more steps before I can run the project. First, I need to add our routes into the application factory, so I add a line into __init__.py:

from flask import Flask

app = Flask(__name__)

from . import routes

Next I need to create two environment variables that will be used by the Flask framework. Again, this is where the two tutorials differ slightly. I opt to go with the “lazy loading” approach from the official tutorial opposed to Miguel’s suggestion of creating a one line Python file at the root of the project. I create the FLASK_APP environment variable and set it’s value to app, instead of the name of a Python script. Additionally, I setup the FLASK_ENV variable and set it to development, which starts Flask in debug mode.

Powershell commands to create environment variables:
$env:FLASK_APP = "app"
$env:FLASK_ENV = "development"

Now we’re ready to fire up the application by launching flask run at the command line:

Flask application running

With the application running, I open a browser and I’m greeted with a lovely message:

Route opened in browser

That’s all I have for the day, a quick introduction to Flask that’s laying the ground work for future development. Tomorrow I hope to convert one of the routes from the old application to this Flask application.



Python100 Days of CodeFlask Share Tweet +1