Jarian Cottingham 7e09799859 fix: batch fix all issues
- Add auth middleware (API key) to protect API routes (#5, #7)
- Add WebSocket handlers and cleanup on disconnect (#3, #8)
- Add web Dockerfile (#1)
- Fix memory upload with streaming chunks (#10)
- Move lofi seed to startup, remove per-request seeding (#9)
- Document ffmpeg dependency in README and .env.example (#6)
- Fill in mobile app with API-connected UI (#4)
- Set GENIUS_API_KEY from env var with documentation (#2)
2026-07-05 21:36:59 +00:00

100 lines
2.5 KiB
Python

import os
import functools
from fastapi import FastAPI, Request, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from starlette.middleware.base import BaseHTTPMiddleware
import os
from .db.database import init_db
from .routers import (
songs,
playlists,
mood,
radio,
search,
lofi,
shareplay,
import_,
settings,
releases,
events,
account,
)
app = FastAPI(title="Music App API", version="1.0.0")
# CORS
origins = os.getenv("CORS_ORIGINS", "http://localhost:5173").split(",")
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Auth middleware
API_KEY = os.getenv("API_KEY", "")
class APIKeyMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
if not API_KEY:
return await call_next(request)
path = request.url.path
if path in ("/health", "/static") or path.startswith("/static"):
return await call_next(request)
header_key = request.headers.get("x-api-key", "")
query_key = request.query_params.get("api_key", "")
if header_key != API_KEY and query_key != API_KEY:
raise HTTPException(status_code=401, detail="Invalid or missing API key")
return await call_next(request)
app.add_middleware(APIKeyMiddleware)
def require_api_key(api_key: str = Depends(lambda: None)):
if not API_KEY:
return
raise HTTPException(status_code=401, detail="API key required")
# Static files
static_dir = os.getenv("STATIC_DIR", "./static")
os.makedirs(static_dir, exist_ok=True)
app.mount("/static", StaticFiles(directory=static_dir), name="static")
# Routers
app.include_router(songs.router)
app.include_router(playlists.router)
app.include_router(mood.router)
app.include_router(radio.router)
app.include_router(search.router)
app.include_router(lofi.router)
app.include_router(shareplay.router)
app.include_router(import_.router)
app.include_router(settings.router)
app.include_router(releases.router)
app.include_router(events.router)
app.include_router(account.router)
@app.on_event("startup")
def startup():
init_db()
from sqlalchemy.orm import Session
from .db.database import SessionLocal
db = SessionLocal()
try:
from .routers.lofi import _seed_channels
_seed_channels(db)
finally:
db.close()
@app.get("/health")
def health_check():
return {"status": "ok"}