Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -108,6 +108,29 @@ def predict_single(features: Dict) -> Dict:
|
|
| 108 |
except Exception as e:
|
| 109 |
return {"error": str(e)}
|
| 110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
def predict_toi_realtime():
|
| 112 |
"""Función para TOI en tiempo real"""
|
| 113 |
try:
|
|
@@ -126,20 +149,64 @@ def predict_toi_realtime():
|
|
| 126 |
if toi_df.empty:
|
| 127 |
return "❌ No se encontraron objetos TOI"
|
| 128 |
|
| 129 |
-
#
|
| 130 |
toi_sample = toi_df.sample(min(3, len(toi_df)), random_state=7)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
|
| 132 |
-
|
| 133 |
results = []
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
|
| 144 |
result_df = pd.DataFrame(results)
|
| 145 |
return f"**Predicciones TOI:**\n\n{result_df.to_markdown(index=False)}"
|
|
@@ -147,17 +214,14 @@ def predict_toi_realtime():
|
|
| 147 |
except Exception as e:
|
| 148 |
return f"❌ Error: {str(e)}"
|
| 149 |
|
| 150 |
-
def predict_manual(
|
|
|
|
|
|
|
| 151 |
"""Función para predicción manual en Gradio"""
|
| 152 |
try:
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
"koi_steff": steff, "koi_slogg": slogg, "koi_smet": smet,
|
| 157 |
-
"koi_kepmag": kepmag, "koi_model_snr": snr, "koi_num_transits": num_transits
|
| 158 |
-
}
|
| 159 |
-
|
| 160 |
-
result = predict_single(features)
|
| 161 |
|
| 162 |
if "error" in result:
|
| 163 |
return f"❌ {result['error']}"
|
|
@@ -173,18 +237,11 @@ def predict_manual(period, duration, depth, prad, srad, teq, steff, slogg, smet,
|
|
| 173 |
|
| 174 |
# ==================== INTERFAZ GRADIO ====================
|
| 175 |
|
| 176 |
-
# Crear inputs para la interfaz
|
| 177 |
-
inputs = []
|
| 178 |
-
for feature in feature_columns:
|
| 179 |
-
default_value = train_medians.get(feature, 0)
|
| 180 |
-
inputs.append(gr.Number(label=feature, value=default_value))
|
| 181 |
-
|
| 182 |
-
# Crear la interfaz
|
| 183 |
with gr.Blocks(theme=gr.themes.Soft(), title="Eco Finder API") as demo:
|
| 184 |
gr.Markdown("# 🌌 Eco Finder API")
|
| 185 |
-
gr.Markdown("Clasificador de exoplanetas
|
| 186 |
|
| 187 |
-
with gr.Tab("🎯 API
|
| 188 |
gr.Markdown("### Endpoint para consumo desde frontend")
|
| 189 |
gr.Markdown("""
|
| 190 |
**URL:** `https://jarpalucas-echo-finder-api.hf.space/api/predict`
|
|
@@ -192,21 +249,28 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Eco Finder API") as demo:
|
|
| 192 |
**Método:** POST
|
| 193 |
**Content-Type:** application/json
|
| 194 |
|
| 195 |
-
**Ejemplo de uso:**
|
| 196 |
-
```
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 206 |
```
|
| 207 |
""")
|
| 208 |
|
| 209 |
-
# Inputs para API
|
| 210 |
with gr.Row():
|
| 211 |
with gr.Column():
|
| 212 |
period = gr.Number(label="koi_period", value=10.0)
|
|
@@ -224,11 +288,11 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Eco Finder API") as demo:
|
|
| 224 |
snr = gr.Number(label="koi_model_snr", value=10.0)
|
| 225 |
num_transits = gr.Number(label="koi_num_transits", value=3.0)
|
| 226 |
|
| 227 |
-
api_btn = gr.Button("🚀 Probar
|
| 228 |
api_output = gr.JSON()
|
| 229 |
|
| 230 |
api_btn.click(
|
| 231 |
-
fn=
|
| 232 |
inputs=[period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits],
|
| 233 |
outputs=api_output
|
| 234 |
)
|
|
@@ -249,11 +313,6 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Eco Finder API") as demo:
|
|
| 249 |
outputs=manual_output
|
| 250 |
)
|
| 251 |
|
| 252 |
-
# ==================== ENDPOINTS API ====================
|
| 253 |
-
|
| 254 |
-
# Gradio automáticamente crea endpoints en /api/predict
|
| 255 |
-
# cuando usamos funciones con inputs/outputs definidos
|
| 256 |
-
|
| 257 |
print("🎉 Aplicación iniciada correctamente!")
|
| 258 |
print("🌐 Interfaz disponible en: /")
|
| 259 |
print("🔗 Endpoint API disponible en: /api/predict")
|
|
|
|
| 108 |
except Exception as e:
|
| 109 |
return {"error": str(e)}
|
| 110 |
|
| 111 |
+
def predict_from_dict(
|
| 112 |
+
koi_period: float, koi_duration: float, koi_depth: float,
|
| 113 |
+
koi_prad: float, koi_srad: float, koi_teq: float,
|
| 114 |
+
koi_steff: float, koi_slogg: float, koi_smet: float,
|
| 115 |
+
koi_kepmag: float, koi_model_snr: float, koi_num_transits: float
|
| 116 |
+
) -> Dict:
|
| 117 |
+
"""Wrapper que toma parámetros individuales y los convierte a dict"""
|
| 118 |
+
features = {
|
| 119 |
+
"koi_period": koi_period,
|
| 120 |
+
"koi_duration": koi_duration,
|
| 121 |
+
"koi_depth": koi_depth,
|
| 122 |
+
"koi_prad": koi_prad,
|
| 123 |
+
"koi_srad": koi_srad,
|
| 124 |
+
"koi_teq": koi_teq,
|
| 125 |
+
"koi_steff": koi_steff,
|
| 126 |
+
"koi_slogg": koi_slogg,
|
| 127 |
+
"koi_smet": koi_smet,
|
| 128 |
+
"koi_kepmag": koi_kepmag,
|
| 129 |
+
"koi_model_snr": koi_model_snr,
|
| 130 |
+
"koi_num_transits": koi_num_transits
|
| 131 |
+
}
|
| 132 |
+
return predict_single(features)
|
| 133 |
+
|
| 134 |
def predict_toi_realtime():
|
| 135 |
"""Función para TOI en tiempo real"""
|
| 136 |
try:
|
|
|
|
| 149 |
if toi_df.empty:
|
| 150 |
return "❌ No se encontraron objetos TOI"
|
| 151 |
|
| 152 |
+
# Tomar muestra
|
| 153 |
toi_sample = toi_df.sample(min(3, len(toi_df)), random_state=7)
|
| 154 |
+
toi_sample.columns = [c.strip().lower() for c in toi_sample.columns]
|
| 155 |
+
|
| 156 |
+
# Mapeo de sinónimos
|
| 157 |
+
candidates_map = {
|
| 158 |
+
"koi_period": ["pl_orbper", "tce_period", "orbper", "period"],
|
| 159 |
+
"koi_duration": ["pl_trandurh", "tce_duration", "tran_dur", "trandur", "duration", "dur"],
|
| 160 |
+
"koi_depth": ["pl_trandep", "tce_depth", "depth", "trandep"],
|
| 161 |
+
"koi_prad": ["pl_rade", "prad", "rade", "planet_radius"],
|
| 162 |
+
"koi_srad": ["st_rad", "srad", "stellar_radius", "star_radius"],
|
| 163 |
+
"koi_teq": ["pl_eqt", "teq", "equilibrium_temp"],
|
| 164 |
+
"koi_steff": ["st_teff", "teff", "stellar_teff", "effective_temp"],
|
| 165 |
+
"koi_slogg": ["st_logg", "logg", "slogg"],
|
| 166 |
+
"koi_smet": ["st_met", "feh", "metallicity", "smet"],
|
| 167 |
+
"koi_kepmag": ["st_tmag", "tmag", "kepmag", "koi_kepmag"],
|
| 168 |
+
"koi_model_snr": ["tce_model_snr", "model_snr", "snr"],
|
| 169 |
+
"koi_num_transits": ["tce_num_transits", "num_transits", "ntransits", "tran_count"]
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
def first_present(candidates, cols_set):
|
| 173 |
+
for name in candidates:
|
| 174 |
+
if name in cols_set:
|
| 175 |
+
return name
|
| 176 |
+
for name in candidates:
|
| 177 |
+
found = [c for c in cols_set if name in c]
|
| 178 |
+
if found:
|
| 179 |
+
return found[0]
|
| 180 |
+
return None
|
| 181 |
|
| 182 |
+
cols_set = set(toi_sample.columns)
|
| 183 |
results = []
|
| 184 |
+
|
| 185 |
+
for idx, row in toi_sample.iterrows():
|
| 186 |
+
# Preparar características
|
| 187 |
+
features = {}
|
| 188 |
+
for feat in feature_columns:
|
| 189 |
+
src = first_present(candidates_map.get(feat, []), cols_set)
|
| 190 |
+
if src and src in row and pd.notna(row[src]):
|
| 191 |
+
features[feat] = float(row[src])
|
| 192 |
+
else:
|
| 193 |
+
features[feat] = train_medians.get(feat, 0)
|
| 194 |
+
|
| 195 |
+
# Predecir
|
| 196 |
+
result = predict_single(features)
|
| 197 |
+
|
| 198 |
+
if "error" not in result:
|
| 199 |
+
results.append({
|
| 200 |
+
"TOI": row.get('toi', f"TOI-{idx}"),
|
| 201 |
+
"Disposición": row.get('tfopwg_disp', 'Unknown'),
|
| 202 |
+
"Predicción": result['prediction'],
|
| 203 |
+
"P(Confirmado)": f"{result['probabilities']['CONFIRMED']:.3f}",
|
| 204 |
+
"P(Candidato)": f"{result['probabilities']['CANDIDATE']:.3f}",
|
| 205 |
+
"P(Falso Positivo)": f"{result['probabilities']['FALSE_POSITIVE']:.3f}"
|
| 206 |
+
})
|
| 207 |
+
|
| 208 |
+
if not results:
|
| 209 |
+
return "❌ No se pudieron generar predicciones"
|
| 210 |
|
| 211 |
result_df = pd.DataFrame(results)
|
| 212 |
return f"**Predicciones TOI:**\n\n{result_df.to_markdown(index=False)}"
|
|
|
|
| 214 |
except Exception as e:
|
| 215 |
return f"❌ Error: {str(e)}"
|
| 216 |
|
| 217 |
+
def predict_manual(
|
| 218 |
+
period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits
|
| 219 |
+
):
|
| 220 |
"""Función para predicción manual en Gradio"""
|
| 221 |
try:
|
| 222 |
+
result = predict_from_dict(
|
| 223 |
+
period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits
|
| 224 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
|
| 226 |
if "error" in result:
|
| 227 |
return f"❌ {result['error']}"
|
|
|
|
| 237 |
|
| 238 |
# ==================== INTERFAZ GRADIO ====================
|
| 239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
with gr.Blocks(theme=gr.themes.Soft(), title="Eco Finder API") as demo:
|
| 241 |
gr.Markdown("# 🌌 Eco Finder API")
|
| 242 |
+
gr.Markdown("Clasificador de exoplanetas")
|
| 243 |
|
| 244 |
+
with gr.Tab("🎯 Predicción API"):
|
| 245 |
gr.Markdown("### Endpoint para consumo desde frontend")
|
| 246 |
gr.Markdown("""
|
| 247 |
**URL:** `https://jarpalucas-echo-finder-api.hf.space/api/predict`
|
|
|
|
| 249 |
**Método:** POST
|
| 250 |
**Content-Type:** application/json
|
| 251 |
|
| 252 |
+
**Ejemplo de uso con curl:**
|
| 253 |
+
```bash
|
| 254 |
+
curl -X POST "https://jarpalucas-echo-finder-api.hf.space/api/predict" \\
|
| 255 |
+
-H "Content-Type: application/json" \\
|
| 256 |
+
-d '{
|
| 257 |
+
"koi_period": 10.0,
|
| 258 |
+
"koi_duration": 5.0,
|
| 259 |
+
"koi_depth": 1000.0,
|
| 260 |
+
"koi_prad": 2.0,
|
| 261 |
+
"koi_srad": 1.0,
|
| 262 |
+
"koi_teq": 1000.0,
|
| 263 |
+
"koi_steff": 6000.0,
|
| 264 |
+
"koi_slogg": 4.5,
|
| 265 |
+
"koi_smet": 0.0,
|
| 266 |
+
"koi_kepmag": 12.0,
|
| 267 |
+
"koi_model_snr": 10.0,
|
| 268 |
+
"koi_num_transits": 3.0
|
| 269 |
+
}'
|
| 270 |
```
|
| 271 |
""")
|
| 272 |
|
| 273 |
+
# Inputs para probar la API localmente
|
| 274 |
with gr.Row():
|
| 275 |
with gr.Column():
|
| 276 |
period = gr.Number(label="koi_period", value=10.0)
|
|
|
|
| 288 |
snr = gr.Number(label="koi_model_snr", value=10.0)
|
| 289 |
num_transits = gr.Number(label="koi_num_transits", value=3.0)
|
| 290 |
|
| 291 |
+
api_btn = gr.Button("🚀 Probar Predicción")
|
| 292 |
api_output = gr.JSON()
|
| 293 |
|
| 294 |
api_btn.click(
|
| 295 |
+
fn=predict_from_dict,
|
| 296 |
inputs=[period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits],
|
| 297 |
outputs=api_output
|
| 298 |
)
|
|
|
|
| 313 |
outputs=manual_output
|
| 314 |
)
|
| 315 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
print("🎉 Aplicación iniciada correctamente!")
|
| 317 |
print("🌐 Interfaz disponible en: /")
|
| 318 |
print("🔗 Endpoint API disponible en: /api/predict")
|