Spaces:
Sleeping
Sleeping
Commit 路
fbae9a2
1
Parent(s): ab07c1c
feat: major changes v2
Browse files
api.py
CHANGED
|
@@ -7,36 +7,20 @@ from dotenv import load_dotenv
|
|
| 7 |
import os
|
| 8 |
import xgboost as xgb
|
| 9 |
import pandas as pd
|
| 10 |
-
import traceback
|
| 11 |
|
| 12 |
load_dotenv(override=True)
|
| 13 |
|
| 14 |
mlflow.set_tracking_uri("databricks")
|
| 15 |
client = MlflowClient()
|
| 16 |
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
try:
|
| 20 |
-
# ---
|
| 21 |
-
run_ = mlflow.search_runs(order_by=['Metrics.rmse ASC'],
|
| 22 |
-
output_format="list",
|
| 23 |
-
experiment_names=[EXPERIMENT_NAME]
|
| 24 |
-
)[0]
|
| 25 |
-
|
| 26 |
-
run_id = run_.info.run_id
|
| 27 |
-
run_uri = f"runs:/{run_id}/preprocessor"
|
| 28 |
-
|
| 29 |
-
client.download_artifacts(
|
| 30 |
-
run_id=run_id,
|
| 31 |
-
path='preprocessor',
|
| 32 |
-
dst_path='.'
|
| 33 |
-
)
|
| 34 |
-
|
| 35 |
-
# --- MI SOSPECHA EST脕 AQU脥 ---
|
| 36 |
-
# 驴Est谩s seguro de que es .b y no .pkl?
|
| 37 |
-
with open("preprocessor/preprocessor.b", "rb") as f_in:
|
| 38 |
-
dv = pickle.load(f_in)
|
| 39 |
-
|
| 40 |
model_name = "workspace.default.nyc-taxi-model"
|
| 41 |
alias = "champion"
|
| 42 |
model_uri = f"models:/{model_name}@{alias}"
|
|
@@ -44,34 +28,31 @@ try:
|
|
| 44 |
champion_model = mlflow.pyfunc.load_model(
|
| 45 |
model_uri=model_uri
|
| 46 |
)
|
| 47 |
-
print("Modelo
|
| 48 |
|
| 49 |
except Exception as e:
|
| 50 |
# Si la API falla al INICIAR, imprime el error
|
| 51 |
print(f"Error CR脥TICO al iniciar la API: {e}")
|
| 52 |
print(traceback.format_exc())
|
| 53 |
-
# Asignamos None para que la app sepa que fall贸
|
| 54 |
-
dv = None
|
| 55 |
champion_model = None
|
| 56 |
|
| 57 |
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
}
|
| 63 |
-
X = dv.transform([input_dict])
|
| 64 |
|
| 65 |
-
|
| 66 |
-
cols = dv.get_feature_names_out()
|
| 67 |
-
except AttributeError:
|
| 68 |
-
cols = dv.get_feature_names()
|
| 69 |
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
-
|
| 74 |
-
X_val = preprocess(input_data)
|
| 75 |
return champion_model.predict(X_val)
|
| 76 |
|
| 77 |
app = FastAPI()
|
|
@@ -86,25 +67,21 @@ class InputData(BaseModel):
|
|
| 86 |
def predict_endpoint(input_data: InputData):
|
| 87 |
|
| 88 |
# Verificamos si la carga inicial fall贸
|
| 89 |
-
if
|
| 90 |
raise HTTPException(
|
| 91 |
status_code=500,
|
| 92 |
-
detail="Error de configuraci贸n del servidor: El modelo
|
| 93 |
)
|
| 94 |
|
| 95 |
try:
|
| 96 |
-
# --- Este es el 煤nico c贸digo que queremos "probar" ---
|
| 97 |
result = predict(input_data)[0]
|
| 98 |
return {"prediction": float(result)}
|
| 99 |
|
| 100 |
except Exception as e:
|
| 101 |
-
#
|
| 102 |
-
# Si algo falla (ej. predict(), preprocess(), etc.)
|
| 103 |
-
# 1. Imprimimos el error COMPLETO en los logs del servidor
|
| 104 |
print(f"Error 500 - Ocurri贸 un error en 'predict_endpoint': {e}")
|
| 105 |
print(traceback.format_exc())
|
| 106 |
|
| 107 |
-
# 2. Devolvemos un error 500 claro al cliente
|
| 108 |
raise HTTPException(
|
| 109 |
status_code=500,
|
| 110 |
detail=f"Error interno del servidor al procesar la predicci贸n: {e}"
|
|
|
|
| 7 |
import os
|
| 8 |
import xgboost as xgb
|
| 9 |
import pandas as pd
|
| 10 |
+
import traceback
|
| 11 |
|
| 12 |
load_dotenv(override=True)
|
| 13 |
|
| 14 |
mlflow.set_tracking_uri("databricks")
|
| 15 |
client = MlflowClient()
|
| 16 |
|
| 17 |
+
# --- NO NECESITAMOS ESTO ---
|
| 18 |
+
# Ya no necesitamos buscar el "mejor run" ni descargar el preprocesador manualmente.
|
| 19 |
+
# El modelo "champion" de pyfunc ya lo contiene.
|
| 20 |
+
# ---------------------------
|
| 21 |
|
| 22 |
try:
|
| 23 |
+
# --- Carga solo el modelo ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
model_name = "workspace.default.nyc-taxi-model"
|
| 25 |
alias = "champion"
|
| 26 |
model_uri = f"models:/{model_name}@{alias}"
|
|
|
|
| 28 |
champion_model = mlflow.pyfunc.load_model(
|
| 29 |
model_uri=model_uri
|
| 30 |
)
|
| 31 |
+
print("Modelo (que incluye preprocesador) cargado exitosamente.")
|
| 32 |
|
| 33 |
except Exception as e:
|
| 34 |
# Si la API falla al INICIAR, imprime el error
|
| 35 |
print(f"Error CR脥TICO al iniciar la API: {e}")
|
| 36 |
print(traceback.format_exc())
|
|
|
|
|
|
|
| 37 |
champion_model = None
|
| 38 |
|
| 39 |
|
| 40 |
+
# --- ESTA FUNCI脫N YA NO ES NECESARIA ---
|
| 41 |
+
# def preprocess(input_data):
|
| 42 |
+
# ...
|
| 43 |
+
# ----------------------------------------
|
|
|
|
|
|
|
| 44 |
|
| 45 |
+
def predict(input_data):
|
|
|
|
|
|
|
|
|
|
| 46 |
|
| 47 |
+
# 1. Creamos el DataFrame *en crudo* que el pipeline pyfunc espera.
|
| 48 |
+
# Debe ser un DataFrame, por eso usamos listas [].
|
| 49 |
+
raw_data = {
|
| 50 |
+
'PU_DO': [input_data.PULocationID + "_" + input_data.DOLocationID],
|
| 51 |
+
'trip_distance': [input_data.trip_distance],
|
| 52 |
+
}
|
| 53 |
+
X_val = pd.DataFrame(raw_data)
|
| 54 |
|
| 55 |
+
# 2. El modelo pyfunc se encarga de PREPROCESAR y PREDECIR
|
|
|
|
| 56 |
return champion_model.predict(X_val)
|
| 57 |
|
| 58 |
app = FastAPI()
|
|
|
|
| 67 |
def predict_endpoint(input_data: InputData):
|
| 68 |
|
| 69 |
# Verificamos si la carga inicial fall贸
|
| 70 |
+
if champion_model is None:
|
| 71 |
raise HTTPException(
|
| 72 |
status_code=500,
|
| 73 |
+
detail="Error de configuraci贸n del servidor: El modelo no pudo cargarse. Revise los logs."
|
| 74 |
)
|
| 75 |
|
| 76 |
try:
|
|
|
|
| 77 |
result = predict(input_data)[0]
|
| 78 |
return {"prediction": float(result)}
|
| 79 |
|
| 80 |
except Exception as e:
|
| 81 |
+
# Capturamos cualquier error durante la predicci贸n
|
|
|
|
|
|
|
| 82 |
print(f"Error 500 - Ocurri贸 un error en 'predict_endpoint': {e}")
|
| 83 |
print(traceback.format_exc())
|
| 84 |
|
|
|
|
| 85 |
raise HTTPException(
|
| 86 |
status_code=500,
|
| 87 |
detail=f"Error interno del servidor al procesar la predicci贸n: {e}"
|