Deploy Small Talk: Reachy Mini AI podcast (gradio.Server + three.js + LiveKit)
Browse files- app.py +18 -3
- frontend/dist/assets/index-D2asjf_Y.js +0 -0
- frontend/dist/index.html +1 -1
app.py
CHANGED
|
@@ -28,20 +28,35 @@ attach(app) # /api/* routes — registered before the static mounts below
|
|
| 28 |
# Gradio's own routes, so a simple per-folder static mount is enough.
|
| 29 |
from fastapi.staticfiles import StaticFiles # noqa: E402
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
for sub in ("assets", "robot-3d", "moves", "props"):
|
| 32 |
d = DIST / sub
|
| 33 |
if d.is_dir():
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
|
| 37 |
@app.get("/")
|
| 38 |
async def index():
|
| 39 |
-
return FileResponse(DIST / "index.html")
|
| 40 |
|
| 41 |
|
| 42 |
@app.get("/favicon.ico")
|
| 43 |
async def favicon():
|
| 44 |
-
return FileResponse(DIST / "index.html") # SPA injects an emoji favicon
|
| 45 |
|
| 46 |
|
| 47 |
if __name__ == "__main__":
|
|
|
|
| 28 |
# Gradio's own routes, so a simple per-folder static mount is enough.
|
| 29 |
from fastapi.staticfiles import StaticFiles # noqa: E402
|
| 30 |
|
| 31 |
+
class CachedStaticFiles(StaticFiles):
|
| 32 |
+
"""Hashed/immutable build artifacts: cache hard, forever."""
|
| 33 |
+
|
| 34 |
+
def file_response(self, *args, **kwargs):
|
| 35 |
+
resp = super().file_response(*args, **kwargs)
|
| 36 |
+
resp.headers["Cache-Control"] = "public, max-age=31536000, immutable"
|
| 37 |
+
return resp
|
| 38 |
+
|
| 39 |
+
|
| 40 |
for sub in ("assets", "robot-3d", "moves", "props"):
|
| 41 |
d = DIST / sub
|
| 42 |
if d.is_dir():
|
| 43 |
+
cls = CachedStaticFiles if sub == "assets" else StaticFiles
|
| 44 |
+
app.mount(f"/{sub}", cls(directory=str(d)), name=sub)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
# index.html must NEVER be cached: each deploy replaces the hashed bundle it
|
| 48 |
+
# points at, so a stale cached page 404s on its own JS and the app goes blank.
|
| 49 |
+
_NO_CACHE = {"Cache-Control": "no-cache, must-revalidate"}
|
| 50 |
|
| 51 |
|
| 52 |
@app.get("/")
|
| 53 |
async def index():
|
| 54 |
+
return FileResponse(DIST / "index.html", headers=_NO_CACHE)
|
| 55 |
|
| 56 |
|
| 57 |
@app.get("/favicon.ico")
|
| 58 |
async def favicon():
|
| 59 |
+
return FileResponse(DIST / "index.html", headers=_NO_CACHE) # SPA injects an emoji favicon
|
| 60 |
|
| 61 |
|
| 62 |
if __name__ == "__main__":
|
frontend/dist/assets/index-D2asjf_Y.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
frontend/dist/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
| 11 |
href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,300;12..96,400;12..96,500;12..96,600;12..96,700;12..96,800&family=Instrument+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600&family=JetBrains+Mono:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Playfair+Display:ital,wght@0,500;1,400;1,500;1,600&family=Orbitron:wght@500;700;900&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@300;500&family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400&family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,600&family=Inter+Tight:wght@200;300;400;600&family=Special+Elite&family=IBM+Plex+Sans+Condensed:wght@400;600&display=swap"
|
| 12 |
rel="stylesheet"
|
| 13 |
/>
|
| 14 |
-
<script type="module" crossorigin src="/assets/index-
|
| 15 |
<link rel="stylesheet" crossorigin href="/assets/index-B-4UIlgI.css">
|
| 16 |
</head>
|
| 17 |
<body>
|
|
|
|
| 11 |
href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,300;12..96,400;12..96,500;12..96,600;12..96,700;12..96,800&family=Instrument+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600&family=JetBrains+Mono:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Playfair+Display:ital,wght@0,500;1,400;1,500;1,600&family=Orbitron:wght@500;700;900&family=Share+Tech+Mono&family=Noto+Sans+JP:wght@300;500&family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400&family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,600&family=Inter+Tight:wght@200;300;400;600&family=Special+Elite&family=IBM+Plex+Sans+Condensed:wght@400;600&display=swap"
|
| 12 |
rel="stylesheet"
|
| 13 |
/>
|
| 14 |
+
<script type="module" crossorigin src="/assets/index-D2asjf_Y.js"></script>
|
| 15 |
<link rel="stylesheet" crossorigin href="/assets/index-B-4UIlgI.css">
|
| 16 |
</head>
|
| 17 |
<body>
|