Better static files handling on backend, when in dev mode: fetch from vite.

This commit is contained in:
2025-12-04 02:30:02 +00:00
parent b9b1c995f9
commit a6591a1fbb
8 changed files with 65 additions and 20 deletions
+47 -1
View File
@@ -1,4 +1,7 @@
import asyncio
import atexit
import mimetypes
import os
import shutil
import signal
import subprocess
@@ -7,7 +10,11 @@ from pathlib import Path
from sys import stderr
from threading import Thread
__all__ = ["path", "file", "run_dev"]
import httpx
__all__ = ["path", "file", "read", "run_dev"]
DEV_SERVER = "http://localhost:4403"
NO_FRONTEND_TOOL = """\
┃ ⚠️ deno, npm or bunx needed to run the frontend server.
@@ -53,6 +60,45 @@ def file(*parts: str) -> Path:
return path.joinpath(*parts)
def _is_dev_mode() -> bool:
"""Check if we're running in dev mode (Vite frontend server)."""
return os.environ.get("PASSKEY_DEVMODE") == "1"
async def read(filepath: str) -> tuple[bytes, int, dict[str, str]]:
"""Read file content and return response tuple.
In dev mode, fetches from the Vite dev server.
In production, reads from the static build directory.
Args:
filepath: Path relative to frontend root, e.g. "/auth/index.html"
Returns:
Tuple of (content, status_code, headers) suitable for
FastAPI Response(*args) or Sanic raw response.
"""
if _is_dev_mode():
async with httpx.AsyncClient() as client:
resp = await client.get(f"{DEV_SERVER}{filepath}")
resp.raise_for_status()
mime = resp.headers.get("content-type", "application/octet-stream")
# Strip charset suffix if present
mime = mime.split(";")[0].strip()
return resp.content, resp.status_code, {"content-type": mime}
else:
# Production: read from static build
file_path = path / filepath.lstrip("/")
content = await _read_file_async(file_path)
mime, _ = mimetypes.guess_type(str(file_path))
return content, 200, {"content-type": mime or "application/octet-stream"}
async def _read_file_async(file_path: Path) -> bytes:
"""Read file asynchronously using asyncio.to_thread."""
return await asyncio.to_thread(file_path.read_bytes)
def run_dev():
"""Spawn the frontend dev server (deno, npm, or bunx) as a background process."""
devpath = Path(__file__).parent.parent.parent / "frontend"