| """Elysium — gradio.Server entrypoint (matches small-talk pattern).
|
|
|
| We use `gr.Server` (a FastAPI host with Gradio's backend) so our custom
|
| frontend (Canvas2D bioluminescent hypergraph) takes priority over any default
|
| Gradio UI. All inference happens via /api routes registered by backend.server.
|
| """
|
| import os
|
| import pathlib
|
| import gradio as gr
|
| from fastapi.responses import FileResponse
|
| from fastapi.staticfiles import StaticFiles
|
|
|
| from backend.server import attach
|
|
|
| DIST = pathlib.Path(__file__).parent / "frontend" / "dist"
|
|
|
| app = gr.Server()
|
| attach(app)
|
|
|
|
|
| class CachedStaticFiles(StaticFiles):
|
| """Hashed bundle assets — cache hard."""
|
| def file_response(self, *args, **kwargs):
|
| r = super().file_response(*args, **kwargs)
|
| r.headers["Cache-Control"] = "public, max-age=31536000, immutable"
|
| return r
|
|
|
|
|
|
|
| for sub in ("assets", "audio"):
|
| d = DIST / sub
|
| if d.is_dir():
|
| cls = CachedStaticFiles if sub == "assets" else StaticFiles
|
| app.mount(f"/{sub}", cls(directory=str(d)), name=sub)
|
|
|
|
|
| _NO_CACHE = {"Cache-Control": "no-cache, must-revalidate"}
|
|
|
|
|
| @app.get("/")
|
| async def index():
|
| return FileResponse(DIST / "index.html", headers=_NO_CACHE)
|
|
|
|
|
| @app.get("/favicon.ico")
|
| async def favicon():
|
| return FileResponse(DIST / "index.html", headers=_NO_CACHE)
|
|
|
|
|
| if __name__ == "__main__":
|
| port = int(os.environ.get("GRADIO_SERVER_PORT", os.environ.get("PORT", 7860)))
|
| app.launch(server_name="0.0.0.0", server_port=port)
|
|
|