Création d'un serveur Flask avec des scripts Python
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
L'application principale,
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 influxDB
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
On crée un fichier de définition du service,
nano /etc/systemd/system/flask_app.service
[Unit] Description=Application Flask After=network.target [Service] User=root Group=root WorkingDirectory=/app ExecStart=/app/venv/bin/python /app/app.py Restart=always Environment="FLASK_ENV=production" [Install] WantedBy=multi-user.target
systemctl daemon-reload
systemctl start flask_app
systemctl enable flask_app
Pour vérifier,
systemctl status flask_app
Résumé des commandes clés :
python app.py : Voir les logs dans le terminal pour vérifier l'état de l'application.
sudo systemctl status flask_app : Voir l'état du service systemd.
sudo journalctl -u flask_app : Voir les logs détaillés du service systemd.
ps aux | grep app.py : Vérifier si l'application est en cours d'exécution en arrière-plan.
netstat -tuln | grep 5000 ou ss -tuln | grep 5000 : Vérifier si le port 5000 est utilisé par Flask.