File size: 3,520 Bytes
e76cfc1
9f7cc3a
2a14360
e76cfc1
9f7cc3a
e76cfc1
9f7cc3a
 
368b63a
e76cfc1
 
2a14360
 
 
 
 
 
1a46170
 
 
 
 
 
 
 
 
 
 
 
 
 
e2ccfa6
2a14360
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e76cfc1
368b63a
e76cfc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f7cc3a
e76cfc1
9f7cc3a
e76cfc1
 
9f7cc3a
e76cfc1
 
9f7cc3a
e76cfc1
 
 
 
 
 
 
 
 
 
 
 
9f7cc3a
e76cfc1
 
 
 
7ba4981
f485b9e
9f7cc3a
a046c28
e76cfc1
 
 
a046c28
e76cfc1
 
 
9f7cc3a
b779c27
b7cb626
e76cfc1
 
 
b779c27
 
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
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Literal
import pandas as pd
import boto3
import joblib
import os
import io

# === Initialisation FastAPI ===
app = FastAPI(
    title="🚗 Getaround Price Prediction API",
    description="""
### 🎯 Description  
Cette API prédit le **prix de location journalier** d’un véhicule.

👉 Pour certaines colonnes (`model_key`, `fuel`, `car_type`, `paint_color`), **choisir une valeur parmi les critères listés**.  
ModelKey =
    "Citroën", "Peugeot", "PGO", "Renault", "Audi", "BMW", "Ford", "Mercedes","Opel", "Porsche", "Volkswagen", "KIA Motors", "Alfa Romeo", "Ferrari", "Fiat",
    "Lamborghini", "Maserati", "Lexus", "Honda", "Mazda", "Mini", "Mitsubishi","Nissan", "SEAT", "Subaru", "Suzuki", "Toyota", "Yamaha"

Mileage = Renseigner des valeurs entre 0 et 400000

EnginePower = Renseigner des valeurs entre 10 et 300

Fuel = "diesel", "petrol", "hybrid_petrol", "electro"

PaintColor = "black", "grey", "white", "red", "silver", "blue", "orange","beige", "brown", "green"

CarType = "convertible", "coupe", "estate", "hatchback", "sedan", "subcompact", "suv", "van"

👉 Pour les autres options (`private_parking_available`, `has_gps`, etc.), utiliser **true pour Oui** et **false pour Non**.

Exemple :  
```json
{
  "model_key": "Audi",
  "mileage": 100000,
  "engine_power": 120,
  "fuel": "diesel",
  "paint_color": "black",
  "car_type": "estate",
  "private_parking_available": true,
  "has_gps": true,
  "has_air_conditioning": false,
  "automatic_car": false,
  "has_getaround_connect": true,
  "has_speed_regulator": false,
  "winter_tires": true
}
""",
version="1.0"
)

# === Schéma attendu pour l'entrée ===
class InputData(BaseModel):
    model_key: str
    mileage: int
    engine_power: int
    fuel: str
    paint_color: str
    car_type: str
    private_parking_available: bool
    has_gps: bool
    has_air_conditioning: bool
    automatic_car: bool
    has_getaround_connect: bool
    has_speed_regulator: bool
    winter_tires: bool

# === Configuration S3 ===
S3_BUCKET = os.getenv("S3_BUCKET")
MODEL_KEY = os.getenv("MODEL_KEY", "mlflow/models/xgboost_model.joblib")
s3 = boto3.client("s3")

# === Chargement du modèle depuis S3 au démarrage ===
model = None

@app.on_event("startup")
def load_model():
    global model
    try:
        print(f"Téléchargement du modèle depuis s3://{S3_BUCKET}/{MODEL_KEY}")
        response = s3.get_object(Bucket=S3_BUCKET, Key=MODEL_KEY)
        model_bytes = io.BytesIO(response["Body"].read())
        model = joblib.load(model_bytes)
        print("✅ Modèle chargé avec succès")
    except Exception as e:
        print(f"❌ Erreur chargement modèle : {e}")
        raise RuntimeError(f"Impossible de charger le modèle : {e}")

# === Routes ===
@app.get("/")
def home():
    return {"message": "Bienvenue sur l'API Getaround 🚗 - Utilisez /predict pour faire une prédiction"}

@app.post("/predict")
def predict(data: InputData):
    try:
        # Convertir les données en DataFrame avec colonnes correctes
        df = pd.DataFrame([data.dict()])
        print("📥 Données reçues :", df.to_dict())

        # Faire la prédiction
        prediction = model.predict(df)
        price = float(prediction[0])

        return {"predicted_price_per_day": [round(float(prediction), 2)]}

    except Exception as e:
        print(f"❌ Erreur prédiction : {e}")
        raise HTTPException(status_code=500, detail=str(e))