68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
import logging
|
||
import asyncio
|
||
import os
|
||
from contextlib import asynccontextmanager
|
||
from fastapi import FastAPI
|
||
from fastapi.staticfiles import StaticFiles
|
||
|
||
from app.core.database import init_db, async_session
|
||
from app.core.scheduler import start_scheduler
|
||
from app.core.state import state_manager, discovery_service
|
||
from sqlalchemy import select
|
||
from app.models.device import GroupModel
|
||
from app.api.routes import devices, control, schedules
|
||
|
||
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
|
||
|
||
logging.basicConfig(level=LOG_LEVEL, format="%(asctime)s | %(levelname)s | %(message)s")
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
@asynccontextmanager
|
||
async def lifespan(app: FastAPI):
|
||
# 1. БД и Планировщик
|
||
await init_db()
|
||
await start_scheduler()
|
||
|
||
# 2. Загрузка групп
|
||
async with async_session() as session:
|
||
result = await session.execute(select(GroupModel))
|
||
for g in result.scalars().all():
|
||
state_manager.groups[g.id] = g
|
||
logger.info(f"📂 Загружена группа: {g.name}")
|
||
|
||
# 3. Фоновый Discovery
|
||
discovery_task = asyncio.create_task(
|
||
discovery_service.start_background_discovery(state_manager)
|
||
)
|
||
|
||
yield
|
||
|
||
discovery_task.cancel()
|
||
logger.info("🛑 Ignis Core остановлен")
|
||
|
||
|
||
app = FastAPI(title="Ignis Core API", lifespan=lifespan)
|
||
|
||
# Регистрация роутеров
|
||
app.include_router(devices.router, prefix="/devices", tags=["Devices & Groups"])
|
||
app.include_router(control.router, prefix="/control", tags=["Control"])
|
||
app.include_router(schedules.router, prefix="/schedules", tags=["Schedules"])
|
||
|
||
# Статика
|
||
# Мы убираем html=True из корня, чтобы 404-е ошибки API не превращались в загрузку index.html
|
||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||
|
||
|
||
@app.get("/")
|
||
async def read_index():
|
||
from fastapi.responses import FileResponse
|
||
|
||
return FileResponse("static/index.html")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
import uvicorn
|
||
|
||
uvicorn.run(app, host="0.0.0.0", port=8000)
|