File size: 2,823 Bytes
5a3e94e
 
 
 
 
 
 
 
 
 
 
3606d66
5a3e94e
2f86ae7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3606d66
 
 
 
5a3e94e
 
 
 
 
05712d4
5a3e94e
 
 
05712d4
5a3e94e
05712d4
 
 
 
5a3e94e
3606d66
5a3e94e
3606d66
 
 
 
 
5a3e94e
3606d66
5a3e94e
3606d66
 
 
5a3e94e
 
 
 
3606d66
 
 
 
 
 
5a3e94e
 
3606d66
5a3e94e
 
 
 
 
 
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
# app.py

import joblib
import pandas as pd
from pydantic import BaseModel
from fastapi import FastAPI, HTTPException
from huggingface_hub import hf_hub_download 

# --- KONFIGURASI HF HUB ---
HF_REPO_ID = "aephidayatuloh/bank-model" 
HF_MODEL_FILENAME = "random_forest_bank_marketing_pipeline.joblib"
# app.py (atau index.py)

# --- SETUP MODEL (DIJALANKAN SEKALI SAAT STARTUP) ---
app = FastAPI(title="Bank Deposit Prediction (Docker)")

@app.on_event("startup")
def load_model():
    global MODEL_PIPELINE
    try:
        # Download model dari HF Hub (direkomendasikan)
        downloaded_model_path = hf_hub_download(
            repo_id=HF_REPO_ID, 
            filename=HF_MODEL_FILENAME
        )
        MODEL_PIPELINE = joblib.load(downloaded_model_path)
        print("βœ… Model berhasil dimuat dari Hugging Face Hub.")
    except Exception as e:
        print(f"❌ Gagal memuat model: {e}")
        MODEL_PIPELINE = None


# --- ENDPOINT PREDIKSI ---

@app.get("/")
def home():
    return {"status": "ok", "message": "FastAPI is running inside Docker on HF Spaces."}

# --- 1. Definisi Skema Fitur (Data Mentah) ---
# Model ini mendefinisikan struktur objek yang ada di dalam key "features"
class FeaturesSchema(BaseModel):
    """Skema Pydantic untuk data fitur internal."""
    age: int
    job: str
    marital: str
    education: str
    default: str
    balance: int
    housing: str
    loan: str
    contact: str
    day: int
    month: str
    # duration: int
    campaign: int
    pdays: int
    previous: int
    poutcome: str
    # Pastikan semua 15 fitur ada di sini, sesuai urutan.

# --- 2. Definisi Skema Payload (Wrapper) ---
# Model ini mendefinisikan struktur payload keseluruhan (yang memiliki key "features")
class PredictionPayload(BaseModel):
    """Skema Pydantic untuk payload yang dikirim."""
    features: FeaturesSchema # πŸ’‘ PERUBAHAN UTAMA DI SINI

# --- 3. Perubahan pada Endpoint ---
@app.post("/predict")
# Ganti nama model input di endpoint dari 'PredictionInput' menjadi 'PredictionPayload'
def predict(payload_data: PredictionPayload): 
    
    if MODEL_PIPELINE is None:
        raise HTTPException(status_code=500, detail="Model gagal dimuat.")

    try:
        # πŸ’‘ PERUBAHAN PADA PENGAMBILAN DATA
        # Ambil data fitur dari wrapper 'payload_data'
        input_dict = payload_data.features.dict() 
        input_df = pd.DataFrame([input_dict])

        # ... sisa kode prediksi tetap sama ...
        prediction = MODEL_PIPELINE.predict(input_df)[0]
        prediction_proba = MODEL_PIPELINE.predict_proba(input_df)[0].tolist()
        
        return {
            "prediction_class": int(prediction),
            "probability": prediction_proba
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Prediction error: {e}")