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:


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.


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.


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
    ▼ single_page            # application dir
        ▼ oneel              # blueprint dir; one language page
        ▼ twoels             # blueprint dir; two languages page
    ▼ 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/ This is to start the application in the development server.

from single_page import create_app

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

File single_page/ To create the application.

from flask import Flask

def create_app():
    '''create and configure the app'''
    app = Flask(__name__)

    # a simple page that says hello
    def hello():
        return 'Hello, World!'

    from .oneel import views

    from .twoels import views

    return app

Two empty files:

  • single_page/oneel/ and
  • single_page/twoels/

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

File single_page/oneel/ 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
def index():
    return 'one language index'

File single_page/twoels/ 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
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
    ▼ single_page
        ▼ oneel
            ▼ static           # + this dir holds static resources
                ▼ css
            ▼ templates        # + blueprint templates are here
        ▼ twoels
    ▼ docs
    ▼ tests
    ▼ venv

File single_page/oneel/ 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',                       # +-

@oneel.route('/')                 # index URLs
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') }}">
  <h1>Single Page - single language</h1>
      <li><a href="{{ url_for('oneel.index') }}">single language index</a>
<section class="content">
    {% block header %}{% endblock %}
  {% for message in get_flashed_messages() %}
    <div class="flash">{{ message }}</div>
  {% endfor %}
  {% block content %}{% endblock %}

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