Files
llm-monitor/main.py
T
2026-04-25 15:25:32 +02:00

113 lines
3.2 KiB
Python

"""
LLM Monitor - Dashboard per controllare i modelli caricati in Ollama
Entry point dell'applicazione FastAPI
"""
import logging
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import get_redoc_html
from pathlib import Path
import os
# Configurazione logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Importare le rotte
from app.api.health import router as health_router
from app.api.models import router as models_router
from app.config import settings
# Creare l'app FastAPI
app = FastAPI(
title="LLM Monitor API",
description="Dashboard per il monitoraggio dei modelli LLM in Ollama",
version="1.0.0",
docs_url="/docs",
redoc_url=None,
openapi_url="/openapi.json"
)
# Configurare CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS.split(","),
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Registrare le rotte API
app.include_router(health_router, prefix="/api/v1", tags=["health"])
app.include_router(models_router, prefix="/api/v1", tags=["models"])
# Servire i file statici
static_path = Path(__file__).parent / "app" / "web" / "static"
if static_path.exists():
app.mount("/static", StaticFiles(directory=static_path), name="static")
# Servire la dashboard web
templates_path = Path(__file__).parent / "app" / "web" / "templates"
@app.get("/")
async def root():
"""Pagina principale: modelli residenti in memoria (ollama ps)."""
return FileResponse(templates_path / "models_running.html")
@app.get("/dashboard")
async def dashboard():
"""Alias legacy della pagina principale."""
return FileResponse(templates_path / "models_running.html")
@app.get("/models-available")
async def models_available_page():
"""Pagina modelli disponibili su disco."""
return FileResponse(templates_path / "index.html")
@app.get("/models-running")
async def models_running_page():
"""Pagina dedicata ai modelli residenti in memoria (ollama ps)."""
return FileResponse(templates_path / "models_running.html")
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
"""Documentazione ReDoc con bundle stabile (evita dipendenza da redoc@next)."""
return get_redoc_html(
openapi_url=app.openapi_url,
title=f"{app.title} - ReDoc",
redoc_js_url="https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js",
with_google_fonts=False,
)
@app.get("/favicon.ico", include_in_schema=False)
async def favicon():
"""Favicon dell'applicazione."""
return FileResponse(static_path / "favicon.ico")
# Event hooks
@app.on_event("startup")
async def startup_event():
logger.info("🚀 LLM Monitor avviato")
logger.info(f"📊 Ollama host: {settings.OLLAMA_HOST}")
@app.on_event("shutdown")
async def shutdown_event():
logger.info("🛑 LLM Monitor arrestato")
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"main:app",
host=settings.API_HOST,
port=settings.API_PORT,
reload=settings.ENVIRONMENT == "development",
log_level=settings.LOG_LEVEL.lower()
)