Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3538d77217 | ||
|
|
b7551073f5 | ||
|
|
e8b4a604e9 | ||
|
|
caa0b126b1 | ||
|
|
75f9727710 |
@@ -150,6 +150,9 @@ activemq-data/
|
||||
# Environments
|
||||
.env
|
||||
.envrc
|
||||
# Configuration de déploiement : contient la chaîne de connexion et
|
||||
# la clé JWT. Seul api.env.example (sans valeurs) est versionné.
|
||||
api.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
|
||||
@@ -132,8 +132,8 @@ pip install pytest httpx && pytest -q
|
||||
|
||||
**82 tests**, curseur SQL simulé (aucune vraie base requise) :
|
||||
|
||||
| Fichier | Couverture |
|
||||
|---------|------------|
|
||||
| Fichier | Domaine testé |
|
||||
|---------|---------------|
|
||||
| `test_endpoints.py` | santé, référentiels, authentification, filtres du dashboard, rôles par enum |
|
||||
| `test_historique.py` | bornes de dates, validation du format, agrégation des courbes par monitoring et par service |
|
||||
| `test_securite.py` | protection 401 de chaque route, RBAC 403, jeton forgé rejeté, en-têtes de sécurité, rate-limit 429, compte désactivé, droits RGPD |
|
||||
|
||||
+1
-1
@@ -77,4 +77,4 @@ docker compose up -d datasentinel-api
|
||||
## Contacts
|
||||
|
||||
- Hébergement / infra : administrateur homelab (neckfire).
|
||||
- Application / code : A. Coyaud (auteur, dépôts GitHub).
|
||||
- Application / code : A. Coyaud (auteur, dépôts Gitea — git.nfteam.ovh).
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# ============================================================
|
||||
# Data Sentinel — modèle de configuration de l'API
|
||||
#
|
||||
# Copier ce fichier en api.env (à côté du docker-compose.yml)
|
||||
# et renseigner les valeurs. api.env n'est JAMAIS versionné :
|
||||
# il est exclu par .gitignore.
|
||||
#
|
||||
# cp Api-DataSentinel/api.env.example api.env
|
||||
# ============================================================
|
||||
|
||||
# ---- Base de données ---------------------------------------
|
||||
# Hôte SQL Server. En conteneur, le nom du service Docker
|
||||
# (ex. dev-mssql) ; en local, localhost ou HOTE\INSTANCE.
|
||||
DB_SERVER=dev-mssql
|
||||
|
||||
# Port. Laisser VIDE pour une instance nommée (HOTE\INSTANCE).
|
||||
DB_PORT=1433
|
||||
|
||||
DB_NAME=DataSentinel
|
||||
|
||||
# Compte applicatif dédié — surtout pas « sa ».
|
||||
# Création : voir README.md §3.3 (db_datareader + db_datawriter
|
||||
# sur la seule base DataSentinel).
|
||||
DB_USER=datasentinel_app
|
||||
DB_PASSWORD=
|
||||
|
||||
# Pilote ODBC embarqué dans l'image.
|
||||
DB_DRIVER=ODBC Driver 18 for SQL Server
|
||||
|
||||
# Mettre à yes pour forcer l'authentification Windows
|
||||
# (poste de développement uniquement, sans DB_USER).
|
||||
DB_TRUSTED_CONNECTION=
|
||||
|
||||
# ---- Sécurité ----------------------------------------------
|
||||
# OBLIGATOIRE en déploiement. Sans cette variable, l'API démarre
|
||||
# mais tire une clé aléatoire à chaque redémarrage : toutes les
|
||||
# sessions sont alors invalidées au moindre restart.
|
||||
# Générer : python -c "import secrets; print(secrets.token_urlsafe(64))"
|
||||
JWT_SECRET=
|
||||
|
||||
JWT_ALGORITHM=HS256
|
||||
JWT_EXPIRE_MINUTES=60
|
||||
|
||||
# ---- CORS ---------------------------------------------------
|
||||
# Origines autorisées, séparées par des virgules. Doit contenir
|
||||
# l'URL exacte du front (schéma + hôte, sans slash final).
|
||||
CORS_ORIGINS=https://datasentinel.nfteam.ovh
|
||||
|
||||
# ---- Build --------------------------------------------------
|
||||
# Injecté par la CI (SHA court du commit) et exposé par GET /health.
|
||||
APP_BUILD=local
|
||||
@@ -81,7 +81,7 @@ class Config:
|
||||
|
||||
# Paramètres API
|
||||
API_TITLE = "Data Sentinel API"
|
||||
API_VERSION = "1.0.0"
|
||||
API_VERSION = "1.1.0"
|
||||
API_DESCRIPTION = "API de monitoring de la qualité des données — XEFI"
|
||||
|
||||
# Identifiant de build injecté par la CI : permet de vérifier quelle
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
-47
@@ -1,47 +0,0 @@
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Configuration
|
||||
BASE_URL = "http://127.0.0.1:8000"
|
||||
|
||||
def test_get_dashboard():
|
||||
print(f"--- Test de l'endpoint: {BASE_URL}/dashboard ---")
|
||||
|
||||
try:
|
||||
# 1. Envoi de la requête
|
||||
response = requests.get(f"{BASE_URL}/dashboard")
|
||||
|
||||
# 2. Vérification du code statut
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
|
||||
if not data:
|
||||
print("L'API a répondu avec succès, mais le tableau est vide (VUE_CONSO ne contient rien).")
|
||||
return
|
||||
|
||||
# 3. Affichage formaté du tableau
|
||||
print(f"{'ID':<5} | {'NOM DU MONITORING':<40} | {'ERREURS':<8} | {'SERVICE':<15}")
|
||||
print("-" * 75)
|
||||
|
||||
for item in data:
|
||||
print(f"{item['id_monito']:<5} | {item['nom_monito'][:38]:<40} | {item['nb_erreurs']:<8} | {item['service']:<15}")
|
||||
|
||||
print(f"\nTotal de lignes récupérées : {len(data)}")
|
||||
|
||||
else:
|
||||
print(f"Erreur lors de la requête : {response.status_code}")
|
||||
print(response.text)
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
print("Erreur : Impossible de se connecter à l'API. Est-ce qu'uvicorn est lancé ?")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Petit check de santé avant de tester les données
|
||||
print("Vérification de l'état de l'API...")
|
||||
health = requests.get(f"{BASE_URL}/health").json()
|
||||
print(f"Statut API : {health['api']} | Statut DB : {health['database']}\n")
|
||||
|
||||
if health['database'] == "ok":
|
||||
test_get_dashboard()
|
||||
else:
|
||||
print("Abandon du test : La base de données n'est pas accessible.")
|
||||
Reference in New Issue
Block a user