Files
movie-night/app/main.py
T

60 lines
1.8 KiB
Python
Raw Normal View History

import asyncio
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.responses import Response as FastAPIResponse
from fastapi.staticfiles import StaticFiles
from app.database import init_database
from app.routers import auth, library, users
from app.services.jellyfin import get_poster
from app.services.library_sync import run_periodic_sync
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(name)s %(levelname)s %(message)s")
@asynccontextmanager
async def lifespan(app: FastAPI):
await init_database()
sync_task = asyncio.create_task(run_periodic_sync())
yield
sync_task.cancel()
try:
await sync_task
except asyncio.CancelledError:
pass
app = FastAPI(title="Movie Night", lifespan=lifespan)
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
app.include_router(library.router, prefix="/api/library", tags=["library"])
app.include_router(users.router, prefix="/api", tags=["users"])
# Mood router imported lazily to avoid circular imports during early phases
try:
from app.routers import mood
app.include_router(mood.router, prefix="/api", tags=["mood"])
except ImportError:
pass
@app.get("/api/poster/{item_id}")
async def poster_proxy(item_id: str, request: Request):
from app.routers.auth import get_current_user
await get_current_user(request)
image_data = await get_poster(item_id)
if image_data is None:
return FastAPIResponse(status_code=404)
return FastAPIResponse(
content=image_data,
media_type="image/jpeg",
headers={"Cache-Control": "public, max-age=86400"},
)
# Static files must be mounted last (catches all non-API routes)
app.mount("/", StaticFiles(directory="app/static", html=True), name="static")