Spaces:
Running
Running
| # uvicorn app:app --reload | |
| import os | |
| import uvicorn | |
| from fastapi import Body, FastAPI, UploadFile, File, Response | |
| from fastapi.responses import JSONResponse | |
| from fastapi.middleware.cors import CORSMiddleware | |
| import traceback | |
| import numpy as np | |
| import json | |
| from detect import DengueDetector | |
| from municipal_predictor import DenguePredictor | |
| from state_predictor import StatePredictor | |
| def default_json_serializer(obj): | |
| if isinstance(obj, np.integer): | |
| return int(obj) | |
| elif isinstance(obj, np.floating): | |
| return float(obj) | |
| elif isinstance(obj, np.ndarray): | |
| return obj.tolist() | |
| raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable") | |
| detector: DengueDetector | None = None | |
| predictor: DenguePredictor | None = None | |
| state_predictor: StatePredictor | None = None | |
| # Se api irá utilizar datasets baixados do hugging face ou os locais | |
| ONLINE: bool = True | |
| app = FastAPI() | |
| async def startup_event(): | |
| global detector, predictor, state_predictor | |
| print("Executando evento de startup: Carregando os módulos de IA...") | |
| offline_flag = (not ONLINE) | |
| local_city_inf = None | |
| local_state_inf = None | |
| detector = DengueDetector() | |
| try: | |
| predictor = DenguePredictor( | |
| offline=offline_flag, | |
| local_inference_path=local_city_inf, | |
| ) | |
| except Exception as e: | |
| print("[WARN] DenguePredictor (municipal) não inicializado:", str(e)) | |
| # print full traceback to help debugging (was previously only printing str(e)) | |
| traceback.print_exc() | |
| predictor = None | |
| try: | |
| state_predictor = StatePredictor( | |
| offline=offline_flag, | |
| local_inference_path=local_state_inf, | |
| ) | |
| except Exception as e: | |
| print("[WARN] StatePredictor não inicializado:", str(e)) | |
| traceback.print_exc() | |
| state_predictor = None | |
| print("Módulos de IA carregados com sucesso. API pronta. Modo:", "online" if ONLINE else "offline") | |
| # --- CORS --- | |
| origins = ["https://previdengue.vercel.app", "http://localhost:3000", "*"] | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=origins, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| def health_check(): | |
| return { | |
| "status": "ok", | |
| "message": "API de Dengue rodando!", | |
| "mode": "online" if ONLINE else "offline", | |
| "online": ONLINE, | |
| } | |
| async def detect(file: UploadFile = File(...)): | |
| if detector is None: | |
| return JSONResponse(status_code=503, content={"error": "Detector ainda não foi inicializado."}) | |
| try: | |
| content = await file.read() | |
| result = detector.detect_image(content) | |
| return JSONResponse(content=result) | |
| except Exception as e: | |
| tb_str = traceback.format_exc() | |
| print(tb_str) | |
| return JSONResponse(status_code=500, content={"error": str(e)}) | |
| async def predict_dengue_route(payload: dict = Body(...)): | |
| if predictor is None: | |
| return JSONResponse(status_code=503, content={"error": "Preditor ainda não foi inicializado."}) | |
| try: | |
| ibge_code_str = payload.get("ibge_code") | |
| if ibge_code_str is None: | |
| raise ValueError("O campo 'ibge_code' é obrigatório.") | |
| ibge_code = int(ibge_code_str) | |
| result = predictor.predict(ibge_code) | |
| json_content = json.dumps(result, default=default_json_serializer) | |
| return Response(content=json_content, media_type="application/json") | |
| except Exception as e: | |
| tb_str = traceback.format_exc() | |
| print(tb_str) | |
| return JSONResponse(status_code=500, content={ | |
| "error": str(e), | |
| "traceback": tb_str, | |
| }) | |
| async def predict_dengue_state_route(payload: dict = Body(...)): | |
| global state_predictor | |
| if state_predictor is None: | |
| try: | |
| local_state_inf = None | |
| state_predictor = StatePredictor( | |
| offline=(not ONLINE), | |
| local_inference_path=local_state_inf, | |
| ) | |
| except Exception as e: | |
| return JSONResponse(status_code=503, content={"error": f"Preditor estadual ainda não foi inicializado: {str(e)}"}) | |
| try: | |
| state_sigla = payload.get("state") or payload.get("state_sigla") or payload.get("uf") | |
| year = payload.get("year") | |
| week = payload.get("week") | |
| if not state_sigla: | |
| raise ValueError("O campo 'state' (sigla) é obrigatório.") | |
| result = state_predictor.predict( | |
| str(state_sigla).upper(), | |
| year=int(year) if year is not None else None, | |
| week=int(week) if week is not None else None, | |
| ) | |
| json_content = json.dumps(result, default=default_json_serializer) | |
| return Response(content=json_content, media_type="application/json") | |
| except Exception as e: | |
| tb_str = traceback.format_exc() | |
| print(tb_str) | |
| return JSONResponse(status_code=500, content={ | |
| "error": str(e), | |
| "traceback": tb_str, | |
| }) | |