Création d'un serveur Flask avec des scripts Python

De Wiki de Mémoire Vive
Aller à la navigation Aller à la recherche

L'objectif est de créer une application de test avec Flask, en environnement Debian. C'est à dire un site HTML composé de pages dynamiques.

On crée un conteneur LXC avec Debian12

Puis, sous root,

apt update

apt install python3 python3-venv python3-pip -y

On crée un répertoire /app pour loger notre projet et on s'y met

mkdir /app

cd /app

python3 -m venv venv

source venv/bin/activate

Comme on va s'amuser à aller chercher des données influxDB, on installe ces éléments

pip install flask influxdb-client

Et on crée un fichier pour garder trace des dépendances

pip freeze > requirements.txt

Architecture générale des dossiers,

/app/
├── templates/              # Templates HTML pour Jinja2
│   ├── index.html          # Page d'accueil
│   ├── data.html           # Page affichant les données
├── static/                 # Fichiers statiques (CSS, JS, images)
│   ├── css/
│   │   └── style.css       # Fichier de style CSS
│   ├── js/
│   │   └── script.js       # (Optionnel) Fichier JS
│   └── images/             # (Optionnel) Images statiques
│       └── logo.png        # Exemple d'image
├── venv/                   # Environnement virtuel Python
│   ├── bin/                # Binaires pour l'environnement virtuel
│   ├── lib/                # Bibliothèques installées
│   └── ...                 # Autres fichiers gérés par venv
├── app.py                  # Application principale Flask (point d'entrée)
├── influxdb.py             # Gestion de la connexion à InfluxDB
├── config.py               # Configuration de l'application Flask
├── requirements.txt        # Liste des dépendances Python
├── .env                    # Variables d'environnement (e.g., token InfluxDB)
├── start.sh                # Script de démarrage
├── README.md               # Documentation du projet

Création d'un fichier de service

nano /etc/systemd/system/flask_app.service

nano app.py

from flask import Flask, render_template
from influxdb import fetch_data_from_influxdb

app = Flask(__name__)
app.config.from_pyfile('config.py')

@app.route('/')
def index():
    return render_template('index.html', title="Accueil")

@app.route('/data')
def data():
    data_points = fetch_data_from_influxdb()
    return render_template('data.html', title="Données", data_points=data_points)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)


Puis création de influxdb.py (connexion influxDB, à personnaliser)

nano influxdb.py

from influxdb_client import InfluxDBClient

def fetch_data_from_influxdb():
    INFLUXDB_URL = "http://localhost:8086"
    INFLUXDB_TOKEN = "votre_token"
    INFLUXDB_ORG = "votre_organisation"
    INFLUXDB_BUCKET = "votre_bucket"

    client = InfluxDBClient(url=INFLUXDB_URL, token=INFLUXDB_TOKEN, org=INFLUXDB_ORG)
    query = f'from(bucket:"{INFLUXDB_BUCKET}") |> range(start: -1h)'
    query_api = client.query_api()
    tables = query_api.query(query, org=INFLUXDB_ORG)

    data_points = []
    for table in tables:
        for record in table.records:
            data_points.append({
                "time": record.get_time(),
                "value": record.get_value(),
                "measurement": record.get_measurement()
            })

    return data_points


Fichier de conf pour influxDB nano config.py

import os

SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
INFLUXDB_URL = os.environ.get('INFLUXDB_URL') or 'http://localhost:8086'
INFLUXDB_TOKEN = os.environ.get('INFLUXDB_TOKEN') or 'votre_token'
INFLUXDB_ORG = os.environ.get('INFLUXDB_ORG') or 'votre_organisation'
INFLUXDB_BUCKET = os.environ.get('INFLUXDB_BUCKET') or 'votre_bucket'

on crée le répertoire templates

mkdir templates

Puis le fichier index.html pour la page d'accueil

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }}</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
    <h1>Bienvenue dans votre application Flask</h1>
    <a href="/data">Voir les données</a>
</body>
</html>

Puis une page pour les données infuxDB

nano data.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }}</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
    <h1>Données d'InfluxDB</h1>
    <table>
        <thead>
            <tr>
                <th>Temps</th>
                <th>Valeur</th>
                <th>Mesure</th>
            </tr>
        </thead>
        <tbody>
            {% for point in data_points %}
            <tr>
                <td>{{ point.time }}</td>
                <td>{{ point.value }}</td>
                <td>{{ point.measurement }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <a href="/">Retour à l'accueil</a>
</body>
</html>

Et ça marche.

un script pour démarrer l'appli,

nano start.sh

#!/bin/bash
source venv/bin/activate
python app.py

et on rend le script exécutable

chmod +x start.sh

lancer

./start.sh

la page est consultable avec

http://192.168.xx:5000, xx étant l'adr IP de la machine