"""MusicFetch REST API. Plain HTTP behind an upstream TLS reverse proxy.""" import os from fastapi import Depends, FastAPI, Header, HTTPException from fastapi.responses import JSONResponse from . import actions, jobs, mf API_KEY = os.environ.get("MUSICFETCH_API_KEY", "") ROOT = os.environ.get("MUSICFETCH_ROOT", "/media/music") app = FastAPI(title="MusicFetch API") def require_key(x_api_key: str = Header(default="")): if not API_KEY or x_api_key != API_KEY: raise HTTPException(status_code=401, detail="Invalid API key.") @app.exception_handler(HTTPException) async def _http_exc(_req, exc: HTTPException): # Always return a Siri-speakable {"message": ...} body. return JSONResponse(status_code=exc.status_code, content={"message": exc.detail}) @app.get("/health") def health(): return {"status": "ok"} # Minimal stub so that auth tests can verify 401 behaviour before the real # /fetch implementation lands in Task 5. This route MUST carry require_key as # a dependency so unauthenticated / wrong-key requests are rejected here. @app.post("/fetch", dependencies=[Depends(require_key)]) def fetch_stub(q: str = ""): # Task 5 will replace this body with the full search-and-download logic. raise HTTPException(status_code=501, detail="Not yet implemented.")