Created on 16 Jan 2021 ;    Modified on 18 Jan 2021

How create a minimal flask project (part 1: to show a page with single language)


This is the first part of an article about Flask, as follows:

Objective

This Flask project will show a simple page in two different versions:

  • single language;
  • two languages.

Note: the minimal request, will drive us to skip some interesting and important features of Flask.

Needed knowledges

This is not a training ab initio. It's a fast note just to remember how to do it. So, to understand this note you need to know:

  • what is a web site, a programming language, a development framework;
  • a basic knowledge of Python, html, http;
  • what is a virtual environment about Python;
  • console commands in the operating system of your development personal computer;
  • how works a template system, specifically Jinja.

Methodology

To make our project, we are going to use Flask's blueprint(s): one blueprint to show the single language html page. The other to show the double languages html page.

Each blueprint is an app, and our site (an application) will be formed by these two apps.

Development

First of all we need to install the environment: Python and the Flask framework.

We are going to do it using a Python's virtual environment, given that Python is already installed in our machine. Below are the commads to use in shell:

 1  # installation
 2  >mkdir flask_single_page                 # our project base directory
 3  >cd flask_single_page
 4  >python -m venv venv                     # install python's virtual environment in flask_single_page/venv ...
 5  >venv\Scripts\activate                   # ... and activate it
 6  (venv) >python -m pip install -U pip     # upgrade pip
 7  ...
 8  (venv) >pip install flask                # install flask in virtual env.
 9  ...

Now we need to structure the application, i.e. create and initialize its basic locations where afterwards build it. Our directories structure will be ( ▼ means directory, and is not part of directory's name):

▼ flask_single_page           # project dir
    run.py
    ▼ single_page            # application dir
        __init__.py
        ▼ oneel              # blueprint dir; one language page
            __init__.py
            views.py
        ▼ twoels             # blueprint dir; two languages page
            __init__.py
            views.py
    ▼ docs                        # documentation dir
    ▼ tests                       # tests dir
    ▼ venv                   # virtual env. dir

And now we load a core just to check the correct structure of directories. We load these files.

File flask_single_page/run.py. This is to start the application in the development server.

from single_page import create_app

if __name__ == '__main__':
    app = create_app()
    app.run()

File single_page/__init__.py. To create the application.

from flask import Flask

def create_app():
    '''create and configure the app'''
    app = Flask(__name__)
    app.config.from_mapping(
        SECRET_KEY='leave-hope-to-enter',
    )

    # a simple page that says hello
    @app.route('/hello')
    def hello():
        return 'Hello, World!'

    from .oneel import views
    app.register_blueprint(views.oneel)

    from .twoels import views
    app.register_blueprint(views.twoels)

    return app

Two empty files:

  • single_page/oneel/__init__.py and
  • single_page/twoels/__init__.py

These are necessary to declare to python our blueprints as modules.

File single_page/oneel/views.py. Where to collect the app logic to respond to the URL. This is for the oneel blueprint.

from flask import Blueprint

# this app will respond to srv/1l/... URLs
oneel = Blueprint('oneel', __name__, url_prefix='/1l')

@twoels.route('/')                 # index URLs
@oneel.route('/index')
@oneel.route('/index.html')
def index():
    return 'one language index'

File single_page/twoels/views.py. And this is for the twoels blueprint.

from flask import Blueprint

# this app will respond to srv/2l/... URLs
twoels = Blueprint('twoels', __name__, url_prefix='/2l')

@twoels.route('/')                 # index URLs
@twoels.route('/index')
@twoels.route('/index.html')
def index():
    return 'two languages index'

Now we can check our project structure running the application. From directory flask_single_page:

Where last four lines show how application is responding to our calls using a web browser. We'll get:

URL string in browser
http://localhost:5000/hello Hello, World!
http://localhost:5000/1l one language index
http://localhost:5000/2l/ two languages index

From here on we can forget the URL http://localhost:5000/hello.

Now, working on oneel (single language page) to show a true html page, not a simple string. We are going to use two templates: a base and an index using the base. We'll use a simple css file too, just to remember us how to make it.

Our directory schema changes as follow (new directories are marked with # +  ):

▼ flask_single_page
    run.py
    ▼ single_page
        __init__.py
        ▼ oneel
            __init__.py
            views.py
            ▼ static           # + this dir holds static resources
                ▼ css
                    style.css
            ▼ templates        # + blueprint templates are here
                base.html
                index.html
        ▼ twoels
            __init__.py
            views.py
    ▼ docs
    ▼ tests
    ▼ venv

File single_page/oneel/views.py become (modified lines/functions are marked with # +-  ):

# 3rd parties libs import
from flask import Blueprint, render_template     # +-

# this app will respond to srv/1l/... URLs
oneel = Blueprint('oneel',                       # +-
                  __name__,
                  static_folder='static',
                  template_folder='templates',
                  url_prefix='/1l')

@oneel.route('/')                 # index URLs
@oneel.route('/index')
@oneel.route('/index.html')
def index():                                     # +-
    return render_template('index.html')

We make our page using two templates: index.html uses base.html as a foundation to build upon. These templates are in directory single_page/oneel/templates:

File single_page/oneel/templates/base.html is

<!doctype html>
<title>{% block title %}{% endblock %} - Single Page, single language</title>
<link rel="stylesheet" href="{{ url_for('oneel.static', filename='css/style.css') }}">
<nav>
  <h1>Single Page - single language</h1>
  <ul>
      <li><a href="{{ url_for('oneel.index') }}">single language index</a>
  </ul>
</nav>
<section class="content">
  <header>
    {% block header %}{% endblock %}
  </header>
  {% for message in get_flashed_messages() %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  {% block content %}{% endblock %}
</section>

File single_page/oneel/templates/index.html is

{% extends 'base.html' %}

{% block header %}
  <h1>{% block title %}Home{% endblock %}</h1>
{% endblock %}

{% block content %}
  <p>Single page, single language, content</p>
{% endblock %}

Now if we run our application, using a web browser on http://localhost:500/1l/ we get:

single page, single language

Where we can appreciate the presence of a complete html page with applied css style.

While requesting http://localhoost:5000/2l/ we get again the simple initial test string:

single page, two languages

Enjoy, ldfa