File size: 4,836 Bytes
5ff57b0
 
 
572fd8e
5ff57b0
 
 
7692d93
04e665f
572fd8e
04e665f
 
5ff57b0
 
 
04e665f
51ec0fd
04e665f
51ec0fd
 
04e665f
5ff57b0
3cabed9
 
 
04e665f
 
 
3cabed9
04e665f
 
5ff57b0
51ec0fd
 
5ff57b0
 
 
 
04e665f
5ff57b0
 
 
 
 
04e665f
5ff57b0
 
 
 
 
 
 
04e665f
 
5ff57b0
 
 
04e665f
 
 
 
 
 
51ec0fd
04e665f
 
 
 
 
 
 
5ff57b0
 
 
7692d93
 
5ff57b0
7692d93
 
5ff57b0
7692d93
5ff57b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7692d93
 
 
 
5ff57b0
7692d93
 
5ff57b0
 
 
7692d93
5ff57b0
7692d93
5ff57b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/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)