Download app/main.py from zeltrox/gitwire: direct link, hf CLI and curl.
- Browser
- Download file 3.29 kB
-
https://huggingface.co/spaces/zeltrox/gitwire/resolve/main/app/main.py
- Command line
-
hf download hf://spaces/zeltrox/gitwire/app/main.py
-
curl -L -o main.py https://huggingface.co/spaces/zeltrox/gitwire/resolve/main/app/main.py
3.29 kB
| from __future__ import annotations | |
| from pathlib import Path | |
| from typing import Any, Union | |
| import joblib | |
| import pandas as pd | |
| from fastapi import FastAPI, HTTPException | |
| from pydantic import BaseModel, Field | |
| MODEL_PATH = Path(__file__).resolve().parent.parent / "xg_bost.pkl" | |
| # LabelEncoder-style mappings (alphabetical order) for categorical features. | |
| CATEGORICAL_MAPPINGS = { | |
| "weather_condition": { | |
| "Clear": 0.0, | |
| "Cloudy": 1.0, | |
| "Fog": 2.0, | |
| "Rain": 3.0, | |
| "Snow": 4.0, | |
| "Windy": 5.0, | |
| }, | |
| "traffic_level": { | |
| "High": 0.0, | |
| "Low": 1.0, | |
| "Medium": 2.0, | |
| "Very High": 3.0, | |
| "Very Low": 4.0, | |
| }, | |
| "vehicle_type": { | |
| "car": 0.0, | |
| "cycle": 1.0, | |
| "ev": 2.0, | |
| "motorcycle": 3.0, | |
| "scooter": 4.0, | |
| }, | |
| "order_type": { | |
| "Buffet": 0.0, | |
| "Drinks": 1.0, | |
| "Meal": 2.0, | |
| "Snack": 3.0, | |
| "Unknown": 4.0, | |
| }, | |
| } | |
| model = joblib.load(MODEL_PATH) | |
| FEATURE_ORDER = list(model.feature_names_in_) | |
| class PredictInput(BaseModel): | |
| distance_km: float = Field(..., example=7.93) | |
| weather_condition: Union[str, float, int] = Field(..., example="Windy") | |
| traffic_level: Union[str, float, int] = Field(..., example="Low") | |
| vehicle_type: Union[str, float, int] = Field(..., example="scooter") | |
| temperature_c: float = Field(..., example=23.0) | |
| humidity_pct: float = Field(..., example=55.0) | |
| precipitation_mm: float = Field(..., example=0.0) | |
| preparation_time_min: float = Field(..., example=12.0) | |
| courier_experience_yrs: float = Field(..., example=1.0) | |
| worker_age: float = Field(..., example=29.0) | |
| worker_rating: float = Field(..., example=4.7) | |
| order_type: Union[str, float, int] = Field(..., example="Unknown") | |
| weather_risk: float = Field(..., example=7.0) | |
| traffic_risk: float = Field(..., example=25.0) | |
| def _encode_categorical(feature_name: str, value: Any) -> float: | |
| if isinstance(value, (int, float)) and not isinstance(value, bool): | |
| return float(value) | |
| mapping = CATEGORICAL_MAPPINGS[feature_name] | |
| raw = str(value).strip() | |
| if raw in mapping: | |
| return mapping[raw] | |
| lower_map = {k.lower(): v for k, v in mapping.items()} | |
| if raw.lower() in lower_map: | |
| return lower_map[raw.lower()] | |
| allowed = ", ".join(mapping.keys()) | |
| raise HTTPException( | |
| status_code=422, | |
| detail=f"Unknown value '{value}' for '{feature_name}'. Allowed values: {allowed}", | |
| ) | |
| def _prepare_features(payload: PredictInput) -> pd.DataFrame: | |
| values = payload.model_dump() | |
| row: dict[str, float] = {} | |
| for feature in FEATURE_ORDER: | |
| value = values[feature] | |
| if feature in CATEGORICAL_MAPPINGS: | |
| row[feature] = _encode_categorical(feature, value) | |
| else: | |
| row[feature] = float(value) | |
| return pd.DataFrame([row], columns=FEATURE_ORDER) | |
| app = FastAPI(title="Gitwire XGBoost Inference API", version="1.0.0") | |
| def health() -> dict[str, str]: | |
| return {"status": "ok"} | |
| def predit(payload: PredictInput) -> dict[str, float]: | |
| features = _prepare_features(payload) | |
| prediction = float(model.predict(features)[0]) | |
| return {"prediction": prediction} | |