47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
from contextlib import asynccontextmanager
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.staticfiles import StaticFiles
|
|
from starlette.middleware.gzip import GZipMiddleware
|
|
|
|
from logsetup import setup_logging
|
|
|
|
setup_logging()
|
|
|
|
from config import FRONTEND_DIST, STORAGE_DIR
|
|
from database import init_db, close_db
|
|
from guide import reconcile_guides
|
|
from routes import router
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
(STORAGE_DIR / "themen").mkdir(parents=True, exist_ok=True)
|
|
await init_db()
|
|
await reconcile_guides()
|
|
yield
|
|
await close_db()
|
|
|
|
|
|
class CachedStatic(StaticFiles):
|
|
"""StaticFiles mit Cache-Control: gehashte Assets dauerhaft (immutable),
|
|
index.html nie cachen (verweist immer auf die aktuellen Asset-Hashes)."""
|
|
async def get_response(self, path, scope):
|
|
resp = await super().get_response(path, scope)
|
|
if path.startswith("assets/"):
|
|
resp.headers["Cache-Control"] = "public, max-age=31536000, immutable"
|
|
else:
|
|
resp.headers["Cache-Control"] = "no-cache"
|
|
return resp
|
|
|
|
|
|
app = FastAPI(title="Creator", lifespan=lifespan)
|
|
|
|
# gzip für JS/CSS-Bundle + große JSON-Antworten (~1,39 MB JS → ~400 KB).
|
|
app.add_middleware(GZipMiddleware, minimum_size=500)
|
|
|
|
app.include_router(router)
|
|
|
|
if FRONTEND_DIST.exists():
|
|
app.mount("/", CachedStatic(directory=FRONTEND_DIST, html=True), name="frontend")
|