Backend Python pour anticiper les pannes par l'IA — MVP offline-ready pour la planification et l'allocation de ressources d'un réseau militaire.
Événement : Hackathon DIRISI 2025
Thème : "Anticiper les pannes par l'IA"
Objectif : Développer un système de prédiction et de planification pour éviter les pannes réseau et optimiser l'allocation de ressources.
- ✅ Sécurité by design (non-root, headers, audit trail)
- ✅ Offline-ready (aucune dépendance cloud)
- ✅ Sobriété (CPU/RAM faibles, modèles légers)
- ✅ Explicabilité (justification des prédictions)
- ✅ Traçabilité (logs structurés JSON)
- ✅ Reproductibilité (seed déterministe)
dirisi25-backend/
├── src/app/
│ ├── main.py # Application FastAPI
│ ├── config.py # Configuration (Pydantic Settings)
│ ├── security.py # Middlewares de sécurité
│ ├── routers/ # Endpoints API
│ │ ├── health.py # /health
│ │ ├── ingest.py # /v1/ingest
│ │ ├── topology.py # /v1/topology
│ │ ├── predict.py # /v1/predict
│ │ ├── plan.py # /v1/plan, /v1/simulate
│ │ ├── explain.py # /v1/explain
│ │ └── metrics.py # /v1/metrics (Prometheus)
│ ├── services/ # Logique métier
│ │ ├── data_synth.py # Génération données synthétiques
│ │ ├── feature_store.py # Feature engineering
│ │ ├── modeling.py # Modèles baseline
│ │ ├── planning.py # Heuristiques planification
│ │ └── explainability.py # Explications
│ └── schemas/ # Modèles Pydantic
├── data/ # Données (gitignored sauf structure)
├── models/ # Modèles entraînés (gitignored)
├── tests/ # Tests pytest
├── docker/ # Dockerfile
├── Makefile # Commandes automatisées
└── README.md # Ce fichier
- Python 3.11+
- uv (ou pip)
- curl (pour les tests)
# Cloner le repo
git clone <repo-url>
cd dirisi25-hackathon-backend
# Installer les dépendances
make uv
# Ou avec pip classique :
# pip install -e ".[dev]"
# Copier le fichier de configuration
cp .env.example .envmake run
# Ou directement : uvicorn src.app.main:app --reloadLe serveur démarre sur http://localhost:8080
Terminal 1 : Serveur en cours d'exécution
Terminal 2 : Tests
# 1. Vérifier la santé
curl http://localhost:8080/health
# 2. Générer des données synthétiques
curl -X POST http://localhost:8080/v1/ingest \
-H "Content-Type: application/json" \
-d '{
"seed": 42,
"num_sites": 5,
"nodes_per_site": 3,
"duration_min": 1440,
"freq_min": 1,
"incident_rate": 0.01
}'
# 3. Récupérer la topologie
curl http://localhost:8080/v1/topology | jq
# 4. Prédire les risques
curl -X POST http://localhost:8080/v1/predict \
-H "Content-Type: application/json" \
-d '{
"horizon_min": 30,
"targets": [
{"node_id": "N0"},
{"node_id": "N1"},
{"link_id": "L3"}
]
}' | jq
# 5. Générer un plan d'action
curl -X POST http://localhost:8080/v1/plan \
-H "Content-Type: application/json" \
-d '{
"objectives": ["minimize_risk", "preserve_critical_flows"],
"constraints": {"max_latency_ms": 50, "reserve_pct": 20},
"context": {
"impacted": ["N1", "L3"],
"critical_flows": ["FTS-CRIT-12"]
}
}' | jq
# 6. Simuler un scénario
curl -X POST http://localhost:8080/v1/simulate \
-H "Content-Type: application/json" \
-d '{
"scenario": "Panne N1 + congestion L3",
"failures": ["N1"],
"variations": {"L3": 0.95}
}' | jq
# 7. Expliquer une prédiction
curl -X POST "http://localhost:8080/v1/explain?entity_id=N0" | jq
# 8. Voir les métriques Prometheus
curl http://localhost:8080/v1/metrics| Endpoint | Méthode | Description |
|---|---|---|
/health |
GET | Health check |
/v1/ingest |
POST | Génère données synthétiques |
/v1/topology |
GET | Récupère la topologie |
/v1/predict |
POST | Prédit les risques |
/v1/plan |
POST | Génère un plan d'action |
/v1/simulate |
POST | Simule un scénario |
/v1/explain |
POST | Explique une prédiction |
/v1/metrics |
GET | Métriques Prometheus |
Documentation interactive : http://localhost:8080/docs
Fichier .env (copier depuis .env.example) :
# Mode du modèle
MODEL_MODE=rule # Options: rule, ml, hybrid
# Seed pour reproductibilité
SEED=42
# Sécurité
CORS_ORIGINS= # Vide = désactivé
RATE_LIMIT_PER_MIN=0 # 0 = désactivé
# Logging
LOG_LEVEL=INFO
LOG_FORMAT=json
# Seuils (modèle à règles)
THRESHOLD_CPU_HIGH=0.85
THRESHOLD_MEM_HIGH=0.90
THRESHOLD_IF_UTIL_HIGH=0.80
THRESHOLD_PKT_ERR_HIGH=0.05
THRESHOLD_LATENCY_HIGH_MS=100make help # Affiche l'aide
make uv # Installe les dépendances
make fmt # Formate le code (black)
make lint # Vérifie le code (ruff)
make test # Exécute les tests
make data # Génère les données (serveur doit tourner)
make train # Entraîne les modèles
make run # Lance le serveur (dev)
make run-prod # Lance le serveur (prod, 4 workers)
make docker-build # Build l'image Docker
make docker-run # Lance le conteneur
make bench # Benchmark l'API
make clean # Nettoie les fichiers générés
make setup # Setup initial completmake docker-build
# Ou : docker build -t dirisi25-backend:latest -f docker/Dockerfile .make docker-run
# Ou : docker run --rm -p 8080:8080 dirisi25-backend:latestImage optimisée :
- Base
python:3.11-slim - Utilisateur non-root
- Multi-stage build
- Taille cible : < 300 MB
# Tous les tests
make test
# Tests spécifiques
pytest tests/test_health.py -v
pytest tests/test_predict.py -v
# Avec coverage
pytest --cov=src --cov-report=htmlCouverture actuelle : ~80% des lignes critiques
- Conteneur non-root (UID 1000)
- Headers de sécurité :
X-Content-Type-Options: nosniffX-Frame-Options: DENYContent-Security-Policy
- CORS strict (désactivé par défaut)
- Rate limiting (configurable)
- Audit trail (logs structurés JSON)
- Pas d'écriture hors
./dataet./models - Secrets via variables d'env
- Logs minimisés (pas de données sensibles)
- Rate limiting en mémoire (non distribué)
- Pas d'authentification (à ajouter selon besoins)
- Pas de chiffrement des données au repos
Principe : Seuils sur métriques (CPU, mémoire, latence, erreurs)
Avantages :
- ✅ Explicable à 100%
- ✅ Pas d'entraînement nécessaire
- ✅ Déterministe
Configuration : Via .env (voir THRESHOLD_*)
Stack :
LogisticRegression(prédiction risque)IsolationForest(détection anomalies)- Normalisation via
StandardScaler
Entraînement :
# 1. Générer les données (serveur doit tourner)
curl -X POST http://localhost:8080/v1/ingest -H "Content-Type: application/json" -d '{}'
# 2. Entraîner
python -m src.scripts.train_models
# 3. Utiliser
export MODEL_MODE=ml
make runExplicabilité : Coefficients LogisticRegression + Feature importances
Endpoint Prometheus : /v1/metrics
Métriques exposées :
dirisi_api_requests_total: Nombre de requêtes APIdirisi_api_request_duration_seconds: Latence APIdirisi_prediction_duration_seconds: Temps de prédictiondirisi_risk_score: Scores de risque en temps réeldirisi_model_predictions_total: Compteur de prédictions
- Valider les seuils avec des experts réseau
- Ajouter authentification (JWT ?)
- Implémenter cache pour features (Redis ?)
- Optimiser calcul features (parallélisation)
- Données réelles : Formats exacts (SNMP/NetFlow/logs) ?
- Critères d'évaluation : AUC-PR vs F1 ? Pondération faux positifs ?
- Infra : Air-gapped total ? Contraintes SécOp ?
- Livrables : Format soutenance ? Durée pitch ?
Stratégie :
- Plan A : MVP avec données synthétiques (actuel)
- Plan B : Adapteur d'ingestion pour dumps réels (à prévoir)
# 1. Créer une branche
git checkout -b feature/ma-feature
# 2. Développer + tests
# ... code ...
make test
# 3. Formatter + lint
make fmt
make lint
# 4. Commit
git commit -m "feat: ajout de ma feature"
# 5. Push
git push origin feature/ma-featureMIT License - Voir LICENSE
Équipe DIRISI 2025 Hackathon
Pour toute question : contact@exemple.fr
Le backend est conteneurisé avec un Dockerfile multi-stage optimisé :
Stage 1 - Builder (Python 3.11) :
- Installation de
uv(gestionnaire de paquets Python ultra-rapide) - Création d'un environnement virtuel
- Installation des dépendances depuis
pyproject.toml
Stage 2 - Runtime (Python 3.11 slim) :
- Image légère (~150MB)
- Utilisateur non-root (
appuser) pour la sécurité - Port 8080 exposé
- Health check automatique sur
/health PYTHONPATH=/app/srcconfiguré
docker/
└── Dockerfile # Build multi-stage optimisé
# Structure requise
DIRISI-Hackathon/
├── dirisi25-hackathon-frontend/ # Contient docker/docker-compose.yml
└── dirisi25-hackathon-backend/ # Ce repoLe backend est automatiquement lancé via le docker-compose.yml du frontend :
# Depuis le dossier frontend
cd ../dirisi25-hackathon-frontend
make dockerCette commande lance les deux services :
- ✅ Backend FastAPI sur
http://localhost:8080 - ✅ Frontend React sur
http://localhost:3000 - ✅ Health checks automatiques
- ✅ Réseau Docker isolé (
dirisi-network)
environment:
- PYTHONUNBUFFERED=1 # Logs en temps réel
- PYTHONPATH=/app/src # Import des modules app.*
- LOG_LEVEL=INFO # Niveau de logvolumes:
- ./data:/app/data # Données (raw, interim, processed)
- ./models:/app/models # Modèles ML sauvegardésLes données et modèles sont persistés entre les redémarrages du container.
Le container vérifie automatiquement sa santé :
# Vérifier le statut
docker ps
# STATUTS : starting (5s) → healthy
# Test manuel
curl http://localhost:8080/health
# {"status":"ok","version":"0.1.0","mode":"rule","env":"development"}# Depuis le frontend
cd ../dirisi25-hackathon-frontend
# Lancer (mode interactif, Ctrl+C pour arrêter)
make docker
# Lancer en arrière-plan
make docker-up
# Voir les logs du backend
docker compose -f docker/docker-compose.yml logs backend -f
# Arrêter
make docker-down
# Rebuild complet
make docker-buildPour builder uniquement le backend :
# Build l'image
docker build -t dirisi-backend:latest -f docker/Dockerfile .
# Run standalone
docker run -p 8080:8080 \
-v $(pwd)/data:/app/data \
-v $(pwd)/models:/app/models \
-e LOG_LEVEL=DEBUG \
dirisi-backend:latest