Audiofy – Musikwünsche für Partys
Server (Website, Admin-Bereich, Player-API) und Player (raspotify + Controller) mit Install-Skripten für Debian-Systeme. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"""Audiofy-Web – FastAPI-Anwendung.
|
||||
|
||||
Start (Server): uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 1 --no-access-log
|
||||
Caddy terminiert HTTPS und leitet an 127.0.0.1:8000 weiter.
|
||||
"""
|
||||
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from . import admin, db, gaeste, player_api
|
||||
from .config import konfig
|
||||
|
||||
# Streng: nur eigene Skripte/Styles, Cover-Bilder vom Spotify-CDN, Turnstile von Cloudflare
|
||||
CSP = ("default-src 'self'; script-src 'self' https://challenges.cloudflare.com; style-src 'self'; "
|
||||
"img-src 'self' https://i.scdn.co data:; frame-src https://challenges.cloudflare.com; "
|
||||
"connect-src 'self'; frame-ancestors 'none'; base-uri 'none'; form-action 'self'")
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
k = konfig()
|
||||
db.initialisieren(k.db_pfad, k.playlist_id)
|
||||
yield
|
||||
|
||||
|
||||
# Keine automatische API-Doku öffentlich ausliefern
|
||||
app = FastAPI(title="Audiofy – Musikwünsche", lifespan=lifespan, docs_url=None, redoc_url=None, openapi_url=None)
|
||||
|
||||
|
||||
@app.middleware("http")
|
||||
async def sicherheits_header(request: Request, call_next):
|
||||
antwort = await call_next(request)
|
||||
antwort.headers.setdefault("Content-Security-Policy", CSP)
|
||||
if request.url.path.startswith("/api/"):
|
||||
antwort.headers.setdefault("Cache-Control", "no-store")
|
||||
return antwort
|
||||
|
||||
|
||||
app.include_router(player_api.router, prefix="/api/player")
|
||||
app.include_router(player_api.router, prefix="/api/pi", include_in_schema=False) # alter Pfad, für ältere Player
|
||||
app.include_router(gaeste.router)
|
||||
app.include_router(admin.router)
|
||||
app.mount("/static", StaticFiles(directory=gaeste.STATIC), name="static")
|
||||
|
||||
|
||||
@app.get("/healthz")
|
||||
def healthz() -> dict:
|
||||
return {"ok": True}
|
||||
Reference in New Issue
Block a user