Skip to content

Commit 64c4cc7

Browse files
authored
Use custom ASGI app to serve SPA properly
1 parent cd2da37 commit 64c4cc7

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

server/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
from fastapi import FastAPI
55
from fastapi.routing import APIRoute
66
from starlette.middleware.cors import CORSMiddleware
7-
from starlette.staticfiles import StaticFiles
87

98
from events.router import events_router
109
from lifespan import lifespan
1110
from search.router import search_router
1211
from server_info.router import settings_router
1312
from settings import Settings
13+
from spa import SpaFiles
1414
from tasks.router import tasks_router
1515
from workers.router import workers_router
1616
from ws.router import ws_router
@@ -58,4 +58,4 @@ async def health_check():
5858
app.include_router(settings_router)
5959

6060
if Path("static").exists():
61-
app.mount("/", StaticFiles(directory="static", html=True), name="static")
61+
app.mount("/", SpaFiles("static", ignore_prefixes=["/api", "/docs", "/redoc", "/ws"]), name="static")

server/spa.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import os
2+
3+
from fastapi import HTTPException
4+
from starlette.exceptions import HTTPException as StarletteHTTPException
5+
from starlette.staticfiles import StaticFiles
6+
7+
8+
class SpaFiles(StaticFiles):
9+
def __init__(
10+
self,
11+
directory: os.PathLike[str],
12+
*,
13+
ignore_prefixes: list[str] | None = None,
14+
):
15+
super().__init__(
16+
directory=directory,
17+
packages=None,
18+
html=True,
19+
check_dir=True,
20+
follow_symlink=False,
21+
)
22+
self._ignore_prefixes = ignore_prefixes or []
23+
24+
def _is_ignored(self, path: str) -> bool:
25+
return any(path.startswith(prefix) for prefix in self._ignore_prefixes)
26+
27+
async def get_response(self, path: str, scope):
28+
if self._is_ignored(path):
29+
raise HTTPException(status_code=404)
30+
try:
31+
return await super().get_response(path, scope)
32+
except (HTTPException, StarletteHTTPException) as ex:
33+
if ex.status_code == 404:
34+
return await super().get_response("index.html", scope)
35+
else:
36+
raise ex

0 commit comments

Comments
 (0)