Pingul commited on
Commit
a78b1ef
·
verified ·
1 Parent(s): b7be716

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -111
app.py CHANGED
@@ -1,111 +1,111 @@
1
- from fastapi import FastAPI
2
- from fastapi.middleware.cors import CORSMiddleware
3
- from datetime import datetime
4
- from contextlib import asynccontextmanager
5
- import os
6
- from ExoMACModel import ExoMACModel
7
- from models.requests import PredictRequest
8
- from models.responses import PredictResponse
9
- from typing import Optional
10
- from fastapi import HTTPException
11
- import pandas as pd
12
-
13
- @asynccontextmanager
14
- async def lifespan(app: FastAPI):
15
- model = ExoMACModel(
16
- repo_id=os.getenv("EXOMAC_REPO", "ZapatoProgramming/ExoMAC-KKT"),
17
- local_dir=os.getenv("EXOMAC_LOCAL_DIR", "ExoMACModel/ExoMAC-KKT"),
18
- prefer_snapshot=True,
19
- always_download=False,
20
- verbose=True,
21
- )
22
- app.state.model = model
23
- yield
24
-
25
- app = FastAPI(
26
- title="NASA SpaceApp API",
27
- description="API para el proyecto NASA SpaceApp 2025",
28
- version="1.0.0",
29
- lifespan=lifespan
30
- )
31
-
32
- # Configurar CORS
33
- app.add_middleware(
34
- CORSMiddleware,
35
- allow_origins=["*"],
36
- allow_credentials=True,
37
- allow_methods=["*"],
38
- allow_headers=["*"],
39
- )
40
-
41
- @app.get("/")
42
- async def root():
43
- """Endpoint raíz de la API"""
44
- return {
45
- "message": "Bienvenido a NASA SpaceApp API",
46
- "version": "1.0.0",
47
- "docs": "/docs"
48
- }
49
-
50
- @app.get("/health")
51
- async def health():
52
- """Endpoint de health check"""
53
- return {
54
- "status": "healthy",
55
- "timestamp": datetime.now().isoformat(),
56
- "service": "NASA SpaceApp API"
57
- }
58
-
59
-
60
- @app.get("/test/predict")
61
- async def test_predict():
62
- """Endpoint de prueba para la predicción"""
63
- return {
64
- "status": 200,
65
- "message": "SOY EL CHESTNUT",
66
- }
67
-
68
- @app.post("/predict", response_model=PredictResponse)
69
- def predict(
70
- req: PredictRequest,
71
- ):
72
- m: Optional[ExoMACModel] = getattr(app.state, "model", None)
73
- if m is None:
74
- raise HTTPException(503, "Model not loaded")
75
-
76
- data = dict(req.features)
77
-
78
- try:
79
- label, probabilities = m.predict(
80
- data,
81
- return_proba=True,
82
- compute_engineered_if_missing=True,
83
- )
84
- except Exception as e:
85
- raise HTTPException(500, f"Prediction error")
86
-
87
- cols = m.feature_columns
88
- recognized = [c for c in cols if c in data]
89
- unknown = [k for k in data.keys() if k not in cols]
90
-
91
- used = m._ensure_engineered_features(dict(data))
92
- X = pd.DataFrame([used], dtype=float).reindex(columns=cols)
93
- missing = X.columns[X.iloc[0].isna()].tolist()
94
-
95
- # Engineered features: those added beyond the original input keys
96
- engineered_only = {k: used.get(k) for k in used.keys() if k not in data}
97
- # JSON-safe (convert NaN to None and numpy floats to float)
98
- engineered_json = {
99
- k: (None if pd.isna(v) else float(v)) if isinstance(v, (int, float)) or hasattr(v, "__float__") else None
100
- for k, v in engineered_only.items()
101
- }
102
-
103
- return PredictResponse(
104
- label=label,
105
- probabilities=probabilities,
106
- recognized=recognized,
107
- unknown=unknown,
108
- missing=missing,
109
- feature_order=cols,
110
- engineered=engineered_json,
111
- )
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from datetime import datetime
4
+ from contextlib import asynccontextmanager
5
+ import os
6
+ from ExoMACModel import ExoMACModel
7
+ from models.requests import PredictRequest
8
+ from models.responses import PredictResponse
9
+ from typing import Optional
10
+ from fastapi import HTTPException
11
+ import pandas as pd
12
+
13
+ @asynccontextmanager
14
+ async def lifespan(app: FastAPI):
15
+ model = ExoMACModel(
16
+ repo_id=os.getenv("EXOMAC_REPO", "ZapatoProgramming/ExoMAC-KKT"),
17
+ local_dir=os.getenv("EXOMAC_LOCAL_DIR", "ExoMACModel/ExoMAC-KKT"),
18
+ prefer_snapshot=True,
19
+ always_download=False,
20
+ verbose=True,
21
+ )
22
+ app.state.model = model
23
+ yield
24
+
25
+ app = FastAPI(
26
+ title="NASA SpaceApp API",
27
+ description="API para el proyecto NASA SpaceApp 2025",
28
+ version="1.0.0",
29
+ lifespan=lifespan
30
+ )
31
+
32
+ # Configurar CORS
33
+ app.add_middleware(
34
+ CORSMiddleware,
35
+ allow_origins=["https://nasa-space-app-2025-nine.vercel.app"],
36
+ allow_credentials=True,
37
+ allow_methods=["*"],
38
+ allow_headers=["*"],
39
+ )
40
+
41
+ @app.get("/")
42
+ async def root():
43
+ """Endpoint raíz de la API"""
44
+ return {
45
+ "message": "Bienvenido a NASA SpaceApp API",
46
+ "version": "1.0.0",
47
+ "docs": "/docs"
48
+ }
49
+
50
+ @app.get("/health")
51
+ async def health():
52
+ """Endpoint de health check"""
53
+ return {
54
+ "status": "healthy",
55
+ "timestamp": datetime.now().isoformat(),
56
+ "service": "NASA SpaceApp API"
57
+ }
58
+
59
+
60
+ @app.get("/test/predict")
61
+ async def test_predict():
62
+ """Endpoint de prueba para la predicción"""
63
+ return {
64
+ "status": 200,
65
+ "message": "SOY EL CHESTNUT",
66
+ }
67
+
68
+ @app.post("/predict", response_model=PredictResponse)
69
+ def predict(
70
+ req: PredictRequest,
71
+ ):
72
+ m: Optional[ExoMACModel] = getattr(app.state, "model", None)
73
+ if m is None:
74
+ raise HTTPException(503, "Model not loaded")
75
+
76
+ data = dict(req.features)
77
+
78
+ try:
79
+ label, probabilities = m.predict(
80
+ data,
81
+ return_proba=True,
82
+ compute_engineered_if_missing=True,
83
+ )
84
+ except Exception as e:
85
+ raise HTTPException(500, f"Prediction error")
86
+
87
+ cols = m.feature_columns
88
+ recognized = [c for c in cols if c in data]
89
+ unknown = [k for k in data.keys() if k not in cols]
90
+
91
+ used = m._ensure_engineered_features(dict(data))
92
+ X = pd.DataFrame([used], dtype=float).reindex(columns=cols)
93
+ missing = X.columns[X.iloc[0].isna()].tolist()
94
+
95
+ # Engineered features: those added beyond the original input keys
96
+ engineered_only = {k: used.get(k) for k in used.keys() if k not in data}
97
+ # JSON-safe (convert NaN to None and numpy floats to float)
98
+ engineered_json = {
99
+ k: (None if pd.isna(v) else float(v)) if isinstance(v, (int, float)) or hasattr(v, "__float__") else None
100
+ for k, v in engineered_only.items()
101
+ }
102
+
103
+ return PredictResponse(
104
+ label=label,
105
+ probabilities=probabilities,
106
+ recognized=recognized,
107
+ unknown=unknown,
108
+ missing=missing,
109
+ feature_order=cols,
110
+ engineered=engineered_json,
111
+ )