Flask + Bootstrap. HTML interface for effortless Python projects

Get started with the Python Flask library to add an HTML interface and create a dashboard for connected objects
Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on email
Share on whatsapp

Flask is a framework that simplifies HTML interface development for Python projects. Flask makes it easy to manage interactions between Python code and user actions on the interface, making JavaScript and jQuery code unnecessary.

 

GitHub logo

Source Code

Flask is a robust and efficient industrial solution that can be used without hesitation for large-scale projects.

Note before you start

You must stop the Flask server “cleanly” before launching a new script using the Ctrl + C key combination, whether in the Terminal or Thonny Python IDE.

If you exit the Code Editor or attempt to run a script without stopping the previous one, you will get the error oserror: [errno 98] address already in use flask which indicates that a processor is still running.

python flask errno 98 address already in use

If so, follow the procedure described in this paragraph to “kill” it.

Install the Python3 Flask library

The Flask library requires Python 3.5 or higher. The Desktop version of Raspberry Pi OS is installed with version 2.7 and 3.7 or later. To verify that version 3 is installed, run the following command in a Terminal.

If Python3 is properly installed, you should get the version number in response.

python3 --version
Python 3.7.3

To install the Python libraries, it is easier to use the pip3 script. To check that the pip3 script is properly installed on Raspberry Pi OS, run this command which should send you the path to the script

pip3 --version
pip 18.1 from /usr/lib/python3/dist-packages/pip (python 3.7)

If pip3 is not installed, run

sudo apt install python3-pip

Now we can install Flask

python3 -m pip install Flask

First Python server with Flask

Launch Thonny Python IDE from the Programming menu

raspberry pi os thonny python ide

Paste the code below

from flask import Flask  

app = Flask(__name__) 

@app.route("/") 
def home(): 
    return "Hello World!"

app.run(debug = True)

Save the script then launch it using the green arrow

thonny python ide start script

By default, the Flask server is accessible on port 5000

Serving Flask app "1 first flask app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 275-643-102

Click on the link or open Chromium then enter http://127.0.0.1:5000/ in the address bar.

You must get this page

python flask app hello world

Explanation of the code

app is the name of the Flask app

app = Flask(__name__)

To be able to access the server, routes must be defined. Here, we simply point to the root of the site using the character /

The @ decorator allows you to specify an endpoint and the function (immediately after) to be executed as soon as the page is called by the user. Here the home method simply returns a text string. In a real application, the method will be able to return an HTML page built from a string or a standard HMTL file.

@app.route("/") 
def home(): 
  return "Hello World!"

At the end of the script, we start the web server with the debugging option.

app.run(debug = True)

Resend HMTL code

Now let’s go further by returning HTML code.

HTML pages can be rendered in 3 ways with Flask

  • return directly returns a string containing the HMTL code of the page. This solution should be reserved for pages with little HTML code or small projects.
  • render_template_string The rendering of the web page is done from a string stored directly in the Python code. Same
  • render_template the rendering of the web page is done from an HTML file stored in a separate file

Directly in the code

This first version directly returns the HTML code of the page in the form of a string

from flask import Flask  

app = Flask(__name__) 

@app.route("/") 
def home(): 
    return "<html>\
              <body>\
                <strong>My First Flask App</strong>\
              </body>\
            </html>"

app.run(debug = True)

The HTML code consists of several lines. Each line of HTML code must end with the \ character in order to be concatenated by the Python interpreter.

Using the render_template_string method

We import the render_template_string method at the start of the code

The HTML_PAGE variable contains the HTML code of the page in the form of a string surrounded by ” ‘. Each line must end with \ .

from flask import Flask, render_template_string  

app = Flask(__name__) 

HTML_PAGE = '''
<html>\
   <body>\
     <strong>My First Flask App</strong>\
   </body>\
</html>
'''

@app.route("/") 
def home(): 
    return render_template_string(HTML_PAGE)

app.run(debug = True)

Using the render_template method

Now let’s see how to generate a web page from a separate HTML file.

HTML files must be stored in a folder named templates located at the root of the project. It is possible to create subfolders to organize HTML files

app.py
└ templates
   └ subfolder
       └ page.html

The source code of the HTML page is perfectly standard

<!doctype html>
<html>
   <body>
     <strong>My First Flask App</strong>
   </body>
</html>

The render_template method takes 2 parameters

  • The path to the HTML page in the templates folder
  • Parameters passed to the HTML code from the Python code which will update the display (we will see later)
from flask import Flask, render_template  

app = Flask(__name__) 

@app.route("/") 
def home(): 
    return render_template('subfolder/page.html')

app.run(debug = True)

In all three cases, you will get exactly the same web page.

flask python render methods

Return dynamic code

As we have seen previously, it is possible to pass arguments to the render_template method which will update the display of the page

Like the Angular framework , Flask embeds a rendering engine called Jinja2. Jinja2 offers a pseudo language that allows you to generate the HTML page according to conditions.

Jinja2 evaluates expressions based on parameters and values ​​and generates corresponding HTML code. There are several types of delimiters:

  • {% …%} to declare an expression
  • {{…}} the variable is replaced by its value
  • {# … #} allows you to add comments or prevent including the part of the code concerned in the final HTML
  • # … ## equivalent to {% …%}, an example
# for item in seq
    <li>{{ item }}</li>
# endfor
</ul>

<ul>
{% for item in seq %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

Here is an example where the label of the LED is displayed ON or OFF depending on

<!doctype html>
<title>Jinja2 demo</title>
{% if status %}
  <p>LED is ON</p>
{% else %}
  <p>LED is OFF</>
{% endif %}

This template displays the status of the LED (On or Off) according to the status parameter .

The Python code corresponding to the previous Template

from flask import Flask, render_template  

app = Flask(__name__) 

@app.route("/") 
def home(): 
    return render_template('subfolder/page.html', status=True)

app.run(debug = True)

You can pass as many parameters as you want, separating them with a comma. The value can be of any type, including a JSON object.

return render_template('page.html', param1=val1, param2=val2, param3=val3...)

Add a CSS style sheet

Style sheets must be stored in the static folder located at the root of the project (like templates)

app.py
├ statics
| └ style.css
├ templates
  └ subfolder
    └ page.html

Then we declare the CSS style sheet as for any other HTML project.

<!doctype html>
<html>
    <head>
        <link rel="stylesheet" href="/static/style.css">
    </head>
    <body>
        <h1>Jinja2 demo</h1>
        {% if status %}
          <p>LED is ON</p>
        {% else %}
          <p>LED is OFF</>
        {% endif %}
        <p>Temperature: {{ temperature }}°C</p>
    </body>
</html>

The corresponding CSS style sheet

h1 {
    font-size: 24px
}    
p {
    font-size: 14px;
    font-weight: 500
}

Launch the script and refresh the browser

jinja2 flask python css render HTML template

Add the Bootstrap stylesheet

Rather than developing your own CSS stylesheet, the easiest way is to use the Bootstrap project.

Replace the link to the style.css file by the one from Bootstrap. The link proposed in the example corresponds to version 4 of Boostrap. Go here to find the most recent link

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

Now the standard HTML tags (h1, h2, p, span …) are automatically formatted.

Here, we will create a row made up of 2 columns (col). In each column is inserted a card. The first for the status of the LED, the second for the temperature.

<!doctype html>
<html>
    <head>
        <!-- Bootstrap CSS --> 
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    </head>
    <body>
        <div class="container">
            <h1>Flask Dashboard with Bootstrap ♥</h1>
            <div class="row">
                <div class="col-6">
                    <div class="card text-white bg-dark mb-3 h-100" style="max-width: 10rem;">
                        <div class="card-header">LED State</div>
                        <div class="card-body text-secondary">
                            <p class="card-text" >
                                {% if status %}
                                  <p style="color:green">ON</p>
                                {% else %}
                                  <p style="color:red">OFF</>
                                {% endif %}
                            </p>    
                        </div>   
                    </div>     
                </div>    
                <div class="col-6">
                    <div class="card bg-light mb-3 h-100" style="max-width: 10rem;">
                        <div class="card-header">Temperature</div>
                        <div class="card-body">
                            <p class="card-text">
                                {{ temperature }}°C
                            </p>    
                        </div>   
                    </div>     
                </div>    
            </div>    
        </div>
    </body>
</html>

And here is the result obtained. The code may look a lot more complex, but it isn’t. With Bootstrap, the HTML page can be displayed on any internet browser, including a smartphone!

flask python dashboard bootstrap style

Send data or actions from the Dashboard

Last point to cover before concluding this introduction to Flask, how to send data or actions from the HTML page.

The HTTP protocol has several methods for each operation that can be performed through HTTP requests.

GET to retrieve data from the internet browser

POST to submit data to the server. For example the fields of a form, pressing a button …

PUT to refresh data in a database

DELETE to delete data from a database

We will mainly use the GET and POST methods in our projects. The other operations are more specific and are generally used when it is necessary to manipulate records in a database.

We send commands to Python code using HTTP POST requests. To do this, simply place the buttons (a group of Bootstrap buttons ) in an Formular.

Here is an example of an HTML page that allows you to select the distance to move the axis of a CNC or 3D printer motor.

<!doctype html>
<html>
    <head>
        <!-- Bootstrap CSS --> 
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    </head>
    <body>
        <div class="container" style="padding:10px">
                <div class="card mb-3 h-100">
                    <div class="card-header">Distance to move {{distance}} mm</div>     
                    <div class="card-body"> 
                        <form method="POST" action="setdistance"> 
                            <div class="btn-group" role="group" > 
                                <button name="distance" type="submit" class="btn btn-secondary" value="0.1">0.1 mm</> 
                                <button name="distance" type="submit" class="btn btn-secondary" value="1">1 mm</> 
                                <button name="distance" type="submit" class="btn btn-secondary" value="10">10 mm</> 
                            </div> 
                        </form> 
                    </div>    
                </div>
        </div>
    </body>
</html>    

The Python code of the page

from flask import Flask, render_template, redirect, request  

app = Flask(__name__) 

distance = 0.1

@app.route("/") 
def home(): 
    global distance
    return render_template('subfolder/page.html', distance=distance)

@app.route("/setdistance", methods=["POST"])
def setdistance():
    global distance
    distance = float(request.form["distance"])
    print("set distance to", distance)
    return redirect(request.referrer)   

app.run(debug = True)

When you press a selector button, the form is sent to the server.

You must tell Flask that POST methods are accepted for this endpoint using the methods option. An endpoint can accept several types of methods which are indicated without an array passed as a parameter.

@app.route("/setdistance", methods=["POST"])

The request.form([“nom_element”]) method allows you to retrieve the selected value (which is converted to a float here).

distance = float(request.form["distance"])

You have certainly noticed the trick which consists in giving the same name to all the buttons of the selector which makes it possible to retrieve the selected value with a single line of code.

Note, Flask manages the data binding, ie the web page is updated automatically as soon as a variable is modified in the Python code! Therefore, there is no need to resend the updated template.

However, a response must be sent back to the browser, which awaits confirmation from the server. For this, we use the redirect () method . The redirect() method is used to refer the user to a response page. This is for example what happens when you subscribe to a newsletter.

Here we will simply refer to the original page using the request.referrer function .

A small video demo

 

If you are interested in the project, the code is used in this tutorial on stepper motors (Nema)

Erreur oserror: [errno 98] address already in use flask.

Problem  A Flask process is still active which prevents launching a new server on the same port.

Remedy Open a Terminal and execute the following command to identify the flask process in memory which corresponds to the script that remained active.

ps -fA | grep python

Locate the process ID that matches your script

python flask processus kill error errno 98 address already in use

Then run the command kill process_number to stop the Flask server, here

kill 1013 

Updates

2020/11/06 Publication of the article

Version Française

Click to rate this post!
[Total: 0 Average: 0]

Are you having a problem with this topic?

Maybe someone has already found the solution, visit the forum before asking your question
Ask your question

Share on facebook
Share on twitter
Share on linkedin
Share on pinterest
Share on email
Share on whatsapp

Did you like this project ? Don't miss any more projects by subscribing to our weekly newsletter!

1 Comment

    Leave a Reply

    DIY Projects
    %d bloggers like this: