Spaces:
Runtime error
Runtime error
| import pandas as pd | |
| import joblib | |
| import uvicorn | |
| from fastapi import FastAPI, Body, Request | |
| from fastapi.responses import JSONResponse, RedirectResponse | |
| from fastapi.exceptions import RequestValidationError | |
| from pydantic import BaseModel, Field | |
| from typing import Literal | |
| # Charger le modèle | |
| model = joblib.load("get_around_v1.pkl") | |
| # Classe Pydantic pour les entrées | |
| class CarData(BaseModel): | |
| mileage: float = Field(..., ge=0, description="Kilométrage doit être >= 0") | |
| engine_power: float = Field(..., ge=45, le=423, description="Puissance moteur entre 45 et 423") | |
| car_brand: Literal[ | |
| "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" | |
| ] | |
| fuel: Literal["diesel", "petrol", "hybrid_petrol", "electro"] | |
| paint_color: Literal[ | |
| "black", "grey", "white", "red", "silver", "blue", | |
| "orange", "beige", "brown", "green" | |
| ] | |
| car_type: Literal[ | |
| "sedan", "convertible", "coupe", "estate", "hatchback", "subcompact", "suv", "van" | |
| ] | |
| 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 | |
| # Initialisation FastAPI | |
| app = FastAPI( | |
| title="🚙🚕 API de Prédiction de Prix GetAround 🚗🚑 ", | |
| docs_url="/docs", | |
| description=""" | |
| Bienvenue sur l'API de prédiction de prix de location de véhicules GetAround ! | |
| Grâce à notre modèle prédictif entraîné sur les données du partenaire GetAround, vous pouvez estimer rapidement le prix journalier d'un véhicule en fournissant ses caractéristiques. | |
| 📌 **Règles pour certaines colonnes :** | |
| - **car_brand** : choisissez parmi les marques listées : | |
| "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". | |
| - **fuel** : "diesel", "petrol", "hybrid_petrol", "electro". | |
| - **paint_color** : "black", "grey", "white", "red", "silver", "blue", | |
| "orange", "beige", "brown", "green". | |
| - **car_type** : "convertible", "coupe", "estate", "hatchback", "sedan", | |
| "subcompact", "suv", "van". | |
| ✅ Pour les autres options (private_parking_available, has_gps, etc.), utilisez **true** pour Oui et **false** pour Non. | |
| 💡 Exemple d'utilisation : | |
| ```json | |
| { | |
| "car_brand": "Renault", | |
| "mileage": 50000, | |
| "engine_power": 120, | |
| "fuel": "diesel", | |
| "paint_color": "white", | |
| "car_type": "estate", | |
| "private_parking_available": false, | |
| "has_gps": true, | |
| "has_air_conditioning": false, | |
| "automatic_car": false, | |
| "has_getaround_connect": false, | |
| "has_speed_regulator": false, | |
| "winter_tires": true | |
| } | |
| """, | |
| version="1.0" | |
| ) | |
| def root(): | |
| return RedirectResponse(url="/docs") | |
| # Gestionnaire d'erreurs personnalisé | |
| async def validation_exception_handler(request: Request, exc: RequestValidationError): | |
| errors = [] | |
| for e in exc.errors(): | |
| field = e.get("loc")[-1] | |
| expected = e.get("ctx", {}).get("expected") | |
| msg = e.get("msg") | |
| if expected: | |
| errors.append({ | |
| "field": field, | |
| "message": f"Valeur incorrecte pour '{field}'. Valeurs possibles : {expected}" | |
| }) | |
| else: | |
| errors.append({ | |
| "field": field, | |
| "message": f"Erreur sur '{field}': {msg}" | |
| }) | |
| return JSONResponse( | |
| status_code=422, | |
| content={ | |
| "error": "Certaines valeurs ne sont pas valides", | |
| "details": errors | |
| } | |
| ) | |
| # Endpoint de prédiction | |
| def predict( | |
| data: CarData = Body( | |
| ..., | |
| examples={ | |
| "valid_example": { | |
| "summary": "Exemple valide", | |
| "value": { | |
| "mileage": 120000, | |
| "engine_power": 100, | |
| "car_brand": "Citroën", | |
| "fuel": "diesel", | |
| "paint_color": "white", | |
| "car_type": "sedan", | |
| "private_parking_available": True, | |
| "has_gps": True, | |
| "has_air_conditioning": True, | |
| "automatic_car": True, | |
| "has_getaround_connect": True, | |
| "has_speed_regulator": True, | |
| "winter_tires": True | |
| } | |
| } | |
| } | |
| ) | |
| ): | |
| df = pd.DataFrame([data.model_dump()]) | |
| df.rename(columns={'car_brand': 'model_key'}, inplace=True) | |
| prediction = model.predict(df) | |
| return {"prediction": round(float(prediction[0]), 2)} | |
| # Lancer localement (utile pour tests) | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |