from contextlib import asynccontextmanager from fastapi import FastAPI import os from apscheduler.schedulers.asyncio import AsyncIOScheduler from app.api.eta import router as eta_router from app.services import simulation, notifications scheduler = AsyncIOScheduler() @asynccontextmanager async def lifespan(app: FastAPI): """ Maneja el ciclo de vida de la aplicación. """ print("Iniciando aplicación: Backend Sistema de Recolección...") # 1. Cargar datos de simulación simulation.load_data() simulation.start_simulation_state() # 2. Inicializar Firebase (o Mock si no hay credenciales) # Ruta relativa correcta cuando se ejecuta desde la carpeta /backend cred_path = os.environ.get("FIREBASE_CREDENTIALS_PATH", "secrets/firebase-adminsdk.json") notifications.init_firebase(cred_path) # 3. Arrancar el scheduler de simulación tick_seconds = int(os.environ.get("SIMULATION_TICK_SECONDS", 15)) scheduler.add_job(simulation.tick, 'interval', seconds=tick_seconds, id='simulation_tick') scheduler.start() print(f"Simulador de rutas iniciado. Avanzando cada {tick_seconds} segundos.") yield print("Apagando aplicación y deteniendo simulador...") scheduler.shutdown() app = FastAPI( title="API - Recolección Inteligente y Privada", description="Backend para el sistema de recolección de residuos con privacidad por diseño.", version="1.0.0", lifespan=lifespan ) # Incluir routers de la API app.include_router(eta_router) # Endpoints de prueba base @app.get("/") def read_root(): return { "status": "ok", "message": "Backend operativo. Regla Innegociable 1: NUNCA se devuelven coordenadas del camión al ciudadano." } @app.get("/health") def health_check(): return {"status": "healthy"}