Djohell commited on
Commit
2ca6909
·
verified ·
1 Parent(s): 5b19e6b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -43
app.py CHANGED
@@ -7,12 +7,13 @@ import mlflow.xgboost
7
  from fastapi import FastAPI, HTTPException, Body
8
  from fastapi.responses import RedirectResponse
9
  from dotenv import load_dotenv
10
- from processing import prepare_input, calculate_survival_risk, map_statut_expert, get_sigma
 
 
11
 
12
  # --- 1. CONFIGURATION MLFLOW ---
13
  load_dotenv()
14
 
15
- # MLflow utilise automatiquement MLFLOW_TRACKING_USERNAME et MLFLOW_TRACKING_PASSWORD
16
  mlflow.set_tracking_uri(os.getenv("MLFLOW_TRACKING_URI"))
17
 
18
  RUN_ID = "674d07aab0b0493a838310da47c71a95"
@@ -25,7 +26,6 @@ app = FastAPI(
25
  version="3.5.0"
26
  )
27
 
28
- # Variables globales pour le modèle et Sigma
29
  model = None
30
  SIGMA = None
31
 
@@ -35,30 +35,25 @@ async def load_model():
35
  try:
36
  print(f"🚀 Connexion à MLflow : {os.getenv('MLFLOW_TRACKING_URI')}")
37
 
38
- # 1. On charge l'objet
39
  loaded_model = mlflow.xgboost.load_model(MODEL_URI)
40
 
41
- # 2. Gestion du format Booster vs Wrapper
42
  if isinstance(loaded_model, xgb.Booster):
43
  model = loaded_model
44
  else:
45
  model = loaded_model.get_booster()
46
 
47
- # 3. On extrait Sigma
48
  SIGMA = get_sigma(model)
49
-
50
  print(f"✅ Modèle chargé avec succès (Sigma: {round(SIGMA, 4)})")
51
  except Exception as e:
52
  print(f"❌ Erreur lors du chargement : {e}")
53
 
54
  # --- 3. ROUTES ---
55
 
56
- # Redirection automatique vers la doc Swagger à l'ouverture de l'URL
57
  @app.get("/", include_in_schema=False)
58
  def home():
59
  return RedirectResponse(url="/docs")
60
 
61
- # Route de santé pour vérifier le statut sans redirection
62
  @app.get("/health", tags=["Système"])
63
  def health():
64
  return {
@@ -67,34 +62,23 @@ def health():
67
  "run_id": RUN_ID
68
  }
69
 
70
- @app.post("/predict", tags=["Prédiction"])
71
- async def predict(
72
- data: dict = Body(..., example={
73
- "age_estime": 4.5,
74
- "Tranche_effectif_num": 3,
75
- "code_departement": "26",
76
- "code_ape": "43",
77
- "categorie_juridique": "5499",
78
- "is_ess": 0
79
- })
80
- ):
81
- """
82
- Simule le risque de fermeture d'une entreprise à 1, 2 et 3 ans.
83
- """
84
- if model is None:
85
- raise HTTPException(status_code=503, detail="Modèle non chargé")
86
-
87
  try:
88
- # 1. Préparation des données
 
 
 
89
  dmatrix = prepare_input(data)
90
 
91
- # 2. Inférence (Score MU)
92
  mu = float(model.predict(dmatrix)[0])
 
93
 
94
- # 3. Calcul des probabilités
95
- p1 = calculate_survival_risk(mu, 1, SIGMA)
96
- p2 = calculate_survival_risk(mu, 2, SIGMA)
97
- p3 = calculate_survival_risk(mu, 3, SIGMA)
98
 
99
  return {
100
  "diagnostic": {
@@ -106,23 +90,23 @@ async def predict(
106
  "2_ans": f"{p2}%",
107
  "3_ans": f"{p3}%"
108
  },
109
- "entrees_reçues": {
110
- "division_ape": data.get("code_ape"),
111
- "departement": data.get("code_departement")
 
 
 
 
112
  },
113
  "metadonnees": {
114
- "run_id": RUN_ID,
115
- "sigma_utilise": round(SIGMA, 6)
116
  }
117
  }
118
-
119
  except Exception as e:
120
- raise HTTPException(
121
- status_code=500,
122
- detail=f"Erreur interne lors du calcul : {str(e)}"
123
- )
124
 
125
  if __name__ == "__main__":
126
  import uvicorn
127
- # Important : sur HF, le port par défaut attendu est 7860
128
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
7
  from fastapi import FastAPI, HTTPException, Body
8
  from fastapi.responses import RedirectResponse
9
  from dotenv import load_dotenv
10
+
11
+ # On importe tout, y compris FEATURES pour le debug
12
+ from processing import prepare_input, calculate_survival_risk, map_statut_expert, get_sigma, FEATURES
13
 
14
  # --- 1. CONFIGURATION MLFLOW ---
15
  load_dotenv()
16
 
 
17
  mlflow.set_tracking_uri(os.getenv("MLFLOW_TRACKING_URI"))
18
 
19
  RUN_ID = "674d07aab0b0493a838310da47c71a95"
 
26
  version="3.5.0"
27
  )
28
 
 
29
  model = None
30
  SIGMA = None
31
 
 
35
  try:
36
  print(f"🚀 Connexion à MLflow : {os.getenv('MLFLOW_TRACKING_URI')}")
37
 
38
+ # Chargement du modèle
39
  loaded_model = mlflow.xgboost.load_model(MODEL_URI)
40
 
 
41
  if isinstance(loaded_model, xgb.Booster):
42
  model = loaded_model
43
  else:
44
  model = loaded_model.get_booster()
45
 
 
46
  SIGMA = get_sigma(model)
 
47
  print(f"✅ Modèle chargé avec succès (Sigma: {round(SIGMA, 4)})")
48
  except Exception as e:
49
  print(f"❌ Erreur lors du chargement : {e}")
50
 
51
  # --- 3. ROUTES ---
52
 
 
53
  @app.get("/", include_in_schema=False)
54
  def home():
55
  return RedirectResponse(url="/docs")
56
 
 
57
  @app.get("/health", tags=["Système"])
58
  def health():
59
  return {
 
62
  "run_id": RUN_ID
63
  }
64
 
65
+ @app.post("/predict")
66
+ async def predict(data: dict):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  try:
68
+ if model is None:
69
+ raise HTTPException(status_code=503, detail="Modèle non chargé")
70
+
71
+ # 1. Préparation
72
  dmatrix = prepare_input(data)
73
 
74
+ # 2. Prédiction
75
  mu = float(model.predict(dmatrix)[0])
76
+ s = get_sigma(model)
77
 
78
+ # 3. Risques
79
+ p1 = calculate_survival_risk(mu, 1, s)
80
+ p2 = calculate_survival_risk(mu, 2, s)
81
+ p3 = calculate_survival_risk(mu, 3, s)
82
 
83
  return {
84
  "diagnostic": {
 
90
  "2_ans": f"{p2}%",
91
  "3_ans": f"{p3}%"
92
  },
93
+ "debug_internal": {
94
+ "features_count": len(FEATURES),
95
+ "first_feature": FEATURES[0] if FEATURES else "None",
96
+ "input_received": {
97
+ "age": data.get("age_estime"),
98
+ "dep": data.get("code_departement")
99
+ }
100
  },
101
  "metadonnees": {
102
+ "run_id": os.urandom(8).hex(),
103
+ "sigma_utilise": s
104
  }
105
  }
 
106
  except Exception as e:
107
+ # Correction de la parenthèse ici
108
+ return {"error": str(e)}
 
 
109
 
110
  if __name__ == "__main__":
111
  import uvicorn
 
112
  uvicorn.run(app, host="0.0.0.0", port=7860)