AichaFaHugFace commited on
Commit
72cc372
·
verified ·
1 Parent(s): 6c942ae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -45
app.py CHANGED
@@ -4,32 +4,30 @@ API de prédiction du prix de location - Projet Getaround
4
  Cette API expose un point de terminaison /predict qui renvoie le prix
5
  de location journalier suggéré pour un véhicule, à partir de ses
6
  caractéristiques.
7
-
8
- Auteur : Projet déploiement
9
  """
10
 
11
  from typing import List, Union
12
  from pathlib import Path
13
  import joblib
14
- import numpy as np
15
  import pandas as pd
16
  from fastapi import FastAPI, HTTPException
17
- from fastapi.responses import HTMLResponse
18
  from pydantic import BaseModel, Field
19
 
20
  # ---------------------------------------------------------------------------
21
  # Configuration de l'application
22
  # ---------------------------------------------------------------------------
23
- APP_TITLE = "Getaround - API de prédiction du prix de location"
24
- APP_DESCRIPTION = (
25
- "Cette API expose un modèle de Machine Learning entraîné pour suggérer "
26
- "le prix journalier optimal d'une location de véhicule, à partir de ses "
27
- "caractéristiques techniques et de ses équipements."
28
- )
 
 
 
29
  APP_VERSION = "1.0.0"
30
  MODEL_PATH = Path(__file__).resolve().parent / "best_model.joblib"
31
 
32
- # Colonnes attendues dans l'ordre du modèle
33
  FEATURE_COLUMNS = [
34
  "model_key", "mileage", "engine_power", "fuel", "paint_color",
35
  "car_type", "private_parking_available", "has_gps",
@@ -37,29 +35,16 @@ FEATURE_COLUMNS = [
37
  "has_speed_regulator", "winter_tires"
38
  ]
39
 
40
- # Modalités acceptées (à titre informatif)
41
- ACCEPTED_MODELS = [
42
- "Citroën", "Renault", "BMW", "Peugeot", "Audi", "Nissan", "Mitsubishi",
43
- "Mercedes", "Volkswagen", "Toyota", "SEAT", "Subaru", "Opel", "PGO",
44
- "Ferrari", "Other"
45
- ]
46
- ACCEPTED_FUELS = ["diesel", "petrol", "hybrid_petrol", "electro"]
47
- ACCEPTED_COLORS = ["black", "grey", "white", "red", "silver", "blue",
48
- "orange", "beige", "brown", "green"]
49
- ACCEPTED_CAR_TYPES = ["convertible", "coupe", "estate", "hatchback",
50
- "sedan", "subcompact", "suv", "van"]
51
-
52
  # ---------------------------------------------------------------------------
53
  # Initialisation
54
  # ---------------------------------------------------------------------------
55
  app = FastAPI(
56
  title=APP_TITLE,
57
  description=APP_DESCRIPTION,
58
- version=APP_VERSION,
59
- redoc_url="/redoc" # On laisse FastAPI gérer automatiquement Swagger sur /docs
60
  )
61
 
62
- # Chargement du modèle une fois au démarrage
63
  try:
64
  model = joblib.load(MODEL_PATH)
65
  MODEL_LOADED = True
@@ -72,7 +57,6 @@ except Exception as exc:
72
  # Schémas Pydantic
73
  # ---------------------------------------------------------------------------
74
  class PredictionInput(BaseModel):
75
- """Schéma d'entrée acceptant une liste de listes de caractéristiques."""
76
  input: List[List[Union[str, int, float, bool]]] = Field(
77
  ...,
78
  examples=[[[
@@ -89,13 +73,12 @@ class PredictionOutput(BaseModel):
89
  # ---------------------------------------------------------------------------
90
  @app.get("/", tags=["Accueil"])
91
  async def root():
92
- """Point d'entrée par défaut. Vérifie que l'API est opérationnelle."""
93
  return {
94
  "message": "API Getaround opérationnelle",
95
  "version": APP_VERSION,
96
  "model_loaded": MODEL_LOADED,
97
- "documentation": "/docs",
98
- "presentation_html": "/about"
99
  }
100
 
101
  @app.get("/health", tags=["Accueil"])
@@ -110,31 +93,24 @@ async def health():
110
  async def predict(payload: PredictionInput):
111
  """Renvoie la prédiction du prix de location journalier (EUR/jour)."""
112
  if not MODEL_LOADED:
113
- raise HTTPException(status_code=503,
114
- detail="Modèle non chargé sur le serveur.")
115
  try:
116
  df_input = pd.DataFrame(payload.input, columns=FEATURE_COLUMNS)
117
 
118
- # Conversion explicite des booléens en entiers (0 ou 1)
119
- bool_cols = ["private_parking_available", "has_gps",
120
- "has_air_conditioning", "automatic_car",
121
- "has_getaround_connect", "has_speed_regulator",
122
- "winter_tires"]
123
  for c in bool_cols:
124
  df_input[c] = df_input[c].astype(int)
125
 
126
- # Conversion des numériques
127
  df_input["mileage"] = df_input["mileage"].astype(int)
128
  df_input["engine_power"] = df_input["engine_power"].astype(int)
129
 
130
  preds = model.predict(df_input)
131
  return {"prediction": [round(float(p), 2) for p in preds]}
132
  except Exception as exc:
133
- raise HTTPException(status_code=400,
134
- detail=f"Erreur lors de la prédiction : {exc}")
135
 
136
- # ---------------------------------------------------------------------------
137
- # Documentation HTML personnalisée déplacée à /about
138
- # ---------------------------------------------------------------------------
139
- @app.get("/about", response_class=HTMLResponse, include_in_schema=False)
140
- async def custom_
 
4
  Cette API expose un point de terminaison /predict qui renvoie le prix
5
  de location journalier suggéré pour un véhicule, à partir de ses
6
  caractéristiques.
 
 
7
  """
8
 
9
  from typing import List, Union
10
  from pathlib import Path
11
  import joblib
 
12
  import pandas as pd
13
  from fastapi import FastAPI, HTTPException
 
14
  from pydantic import BaseModel, Field
15
 
16
  # ---------------------------------------------------------------------------
17
  # Configuration de l'application
18
  # ---------------------------------------------------------------------------
19
+ APP_TITLE = "API Getaround - Prédiction du prix de location"
20
+ APP_DESCRIPTION = """
21
+ Cette API met à disposition un modèle de Machine Learning entraîné pour suggérer le prix journalier optimal d'une location de véhicule sur la plateforme Getaround.
22
+
23
+ ### Performances du modèle (XGBoost Regressor) :
24
+ * **Erreur absolue moyenne (MAE) :** 9,18 EUR
25
+ * **RMSE :** 12,82 EUR
26
+ * **R² :** 0,846
27
+ """
28
  APP_VERSION = "1.0.0"
29
  MODEL_PATH = Path(__file__).resolve().parent / "best_model.joblib"
30
 
 
31
  FEATURE_COLUMNS = [
32
  "model_key", "mileage", "engine_power", "fuel", "paint_color",
33
  "car_type", "private_parking_available", "has_gps",
 
35
  "has_speed_regulator", "winter_tires"
36
  ]
37
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  # ---------------------------------------------------------------------------
39
  # Initialisation
40
  # ---------------------------------------------------------------------------
41
  app = FastAPI(
42
  title=APP_TITLE,
43
  description=APP_DESCRIPTION,
44
+ version=APP_VERSION
 
45
  )
46
 
47
+ # Chargement du modèle
48
  try:
49
  model = joblib.load(MODEL_PATH)
50
  MODEL_LOADED = True
 
57
  # Schémas Pydantic
58
  # ---------------------------------------------------------------------------
59
  class PredictionInput(BaseModel):
 
60
  input: List[List[Union[str, int, float, bool]]] = Field(
61
  ...,
62
  examples=[[[
 
73
  # ---------------------------------------------------------------------------
74
  @app.get("/", tags=["Accueil"])
75
  async def root():
76
+ """Point d'entrée par défaut."""
77
  return {
78
  "message": "API Getaround opérationnelle",
79
  "version": APP_VERSION,
80
  "model_loaded": MODEL_LOADED,
81
+ "documentation": "/docs"
 
82
  }
83
 
84
  @app.get("/health", tags=["Accueil"])
 
93
  async def predict(payload: PredictionInput):
94
  """Renvoie la prédiction du prix de location journalier (EUR/jour)."""
95
  if not MODEL_LOADED:
96
+ raise HTTPException(status_code=503, detail="Modèle non chargé sur le serveur.")
 
97
  try:
98
  df_input = pd.DataFrame(payload.input, columns=FEATURE_COLUMNS)
99
 
100
+ # Conversion des types
101
+ bool_cols = ["private_parking_available", "has_gps", "has_air_conditioning",
102
+ "automatic_car", "has_getaround_connect", "has_speed_regulator", "winter_tires"]
 
 
103
  for c in bool_cols:
104
  df_input[c] = df_input[c].astype(int)
105
 
 
106
  df_input["mileage"] = df_input["mileage"].astype(int)
107
  df_input["engine_power"] = df_input["engine_power"].astype(int)
108
 
109
  preds = model.predict(df_input)
110
  return {"prediction": [round(float(p), 2) for p in preds]}
111
  except Exception as exc:
112
+ raise HTTPException(status_code=400, detail=f"Erreur lors de la prédiction : {exc}")
 
113
 
114
+ if __name__ == "__main__":
115
+ import uvicorn
116
+ uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=False)