oc_p5-dev / app.py
ASI-Engineer's picture
Upload folder using huggingface_hub
51ec0fd verified
raw
history blame
4.84 kB
#!/usr/bin/env python3
"""
Interface Gradio pour tester le modèle Employee Turnover en production.
Déploiement sur Hugging Face Spaces pour tests rapides.
Version de démonstration - Interface complète en développement.
"""
import gradio as gr
from huggingface_hub import hf_hub_download
# Configuration
HF_MODEL_REPO = "ASI-Engineer/employee-turnover-model"
def load_model():
"""
Charge le modèle depuis Hugging Face Hub.
En production (HF Spaces), charge uniquement depuis HF Hub.
Le fallback MLflow local n'est disponible qu'en développement local.
"""
try:
import joblib
# Download model pickle from HF Hub
model_path = hf_hub_download(
repo_id=HF_MODEL_REPO, filename="model/model.pkl", repo_type="model"
)
model = joblib.load(model_path)
print(f"✅ Modèle chargé depuis HF Hub: {HF_MODEL_REPO}")
return model, "HF Hub"
except Exception as e:
print(f"❌ Erreur chargement depuis HF Hub: {e}")
return None, "Error"
# Charger le modèle au démarrage
try:
model, model_source = load_model()
MODEL_LOADED = model is not None
except Exception as e:
print(f"❌ Erreur lors du chargement du modèle: {e}")
MODEL_LOADED = False
model = None
model_source = "Error"
def get_model_info():
"""Retourne les informations sur le modèle."""
if not MODEL_LOADED:
return {
"status": "❌ Modèle non disponible",
"error": "Le modèle n'a pas pu être chargé",
"solution": "Vérifiez que le modèle est bien enregistré sur HF Hub ou entraîné localement",
}
try:
info = {
"status": "✅ Modèle chargé avec succès",
"source": model_source,
"model_type": type(model).__name__,
"features": "~50 features (après preprocessing)",
"algorithme": "XGBoost + SMOTE",
"hf_hub_repo": HF_MODEL_REPO,
}
info["info"] = "Interface de prédiction en développement - API FastAPI à venir"
return info
except Exception as e:
return {"status": "✅ Modèle chargé (info limitées)", "error": str(e)}
# Interface Gradio
with gr.Blocks( # type: ignore[attr-defined]
title="Employee Turnover Prediction - DEV", theme=gr.themes.Soft() # type: ignore[attr-defined]
) as demo:
gr.Markdown("# 🎯 Prédiction du Turnover - Employee Attrition") # type: ignore[attr-defined]
gr.Markdown("## Environment DEV - Test de déploiement CI/CD") # type: ignore[attr-defined]
gr.Markdown( # type: ignore[attr-defined]
"""
### 📊 Statut du projet
Ce Space est synchronisé automatiquement depuis GitHub (branche `dev`).
**Actuellement disponible :**
- ✅ Pipeline d'entraînement MLflow complet (`main.py`)
- ✅ Déploiement automatique CI/CD (GitHub Actions → HF Spaces)
- ✅ Tests unitaires et linting automatisés
**En développement :**
- 🚧 Interface de prédiction interactive
- 🚧 API FastAPI avec endpoints de prédiction
- 🚧 Intégration PostgreSQL pour tracking des prédictions
"""
)
with gr.Row(): # type: ignore[attr-defined]
with gr.Column(): # type: ignore[attr-defined]
gr.Markdown("### 🔍 Informations sur le modèle") # type: ignore[attr-defined]
check_btn = gr.Button("📊 Vérifier le statut du modèle", variant="primary") # type: ignore[attr-defined]
with gr.Column(): # type: ignore[attr-defined]
model_output = gr.JSON(label="Statut") # type: ignore[attr-defined]
check_btn.click(fn=get_model_info, inputs=[], outputs=model_output)
gr.Markdown("---") # type: ignore[attr-defined]
gr.Markdown( # type: ignore[attr-defined]
"""
### 🛠️ Prochaines étapes (selon etapes.txt)
1. **Étape 3** : Développement API FastAPI
- Endpoints de prédiction avec validation Pydantic
- Chargement dynamique des preprocessing artifacts (scaler, encoders)
- Documentation Swagger/OpenAPI automatique
2. **Étape 4** : Intégration PostgreSQL
- Stockage des inputs/outputs des prédictions
- Traçabilité complète des requêtes
3. **Étape 5** : Tests unitaires et fonctionnels
- Tests des endpoints API
- Tests de charge et performance
- Couverture de code avec pytest-cov
### 📚 Documentation
- **Repository GitHub** : [chaton59/OC_P5](https://github.com/chaton59/OC_P5)
- **MLflow Tracking** : Disponible en local (`./scripts/start_mlflow.sh`)
- **Métriques** : F1-Score optimisé, gestion classes déséquilibrées (SMOTE)
"""
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860, share=False)