tubewatch/playlist-monitor/app/main.py

137 lines
3.7 KiB
Python

"""
Playlist Monitor Service - Main FastAPI Application
"""
import asyncio
import logging
from contextlib import asynccontextmanager
from typing import AsyncGenerator
import uvicorn
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from .api import playlists, videos, system
from .core.config import settings
from .core.database import engine, Base
from .core.scheduler import scheduler_manager
from .services.metube_client import MeTubeClient
# Configure logging
logging.basicConfig(
level=getattr(logging, settings.LOG_LEVEL),
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[
logging.StreamHandler(),
logging.FileHandler(settings.LOG_FILE) if settings.LOG_FILE else logging.NullHandler()
]
)
logger = logging.getLogger(__name__)
# Global MeTube client instance
metube_client: MeTubeClient | None = None
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
"""Application lifespan manager"""
global metube_client
logger.info("Starting Playlist Monitor Service...")
# Create database tables
logger.info("Creating database tables...")
Base.metadata.create_all(bind=engine)
# Initialize MeTube client
logger.info("Initializing MeTube client...")
metube_client = MeTubeClient(settings.METUBE_URL)
await metube_client.connect()
# Start scheduler
logger.info("Starting scheduler...")
scheduler_manager.start()
logger.info("Playlist Monitor Service started successfully")
yield
# Cleanup on shutdown
logger.info("Shutting down Playlist Monitor Service...")
# Stop scheduler
scheduler_manager.shutdown()
# Disconnect MeTube client
if metube_client:
await metube_client.disconnect()
logger.info("Playlist Monitor Service shut down complete")
# Create FastAPI app
app = FastAPI(
title="Playlist Monitor Service",
description="Automated playlist monitoring service for MeTube",
version="0.1.0",
lifespan=lifespan
)
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include routers
app.include_router(playlists.router, prefix="/api/playlists", tags=["playlists"])
app.include_router(videos.router, prefix="/api/videos", tags=["videos"])
app.include_router(system.router, prefix="/api", tags=["system"])
@app.get("/")
async def root():
"""Root endpoint"""
return {
"service": "Playlist Monitor Service",
"version": "0.1.0",
"status": "running",
"docs": "/docs"
}
@app.get("/health")
async def health_check():
"""Health check endpoint"""
try:
# Check database connection
from .core.database import SessionLocal
db = SessionLocal()
db.execute("SELECT 1")
db.close()
# Check MeTube connection
metube_status = await metube_client.health_check() if metube_client else False
return {
"status": "healthy",
"database": "connected",
"metube": "connected" if metube_status else "disconnected"
}
except Exception as e:
logger.error(f"Health check failed: {e}")
raise HTTPException(status_code=503, detail="Service unhealthy")
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
host=settings.HOST,
port=settings.PORT,
reload=settings.DEBUG,
log_level=settings.LOG_LEVEL.lower()
)