Add fastapi_vue.env accessor with FASTAPI_VUE prefix

This commit is contained in:
2026-09-13 21:24:51 +00:00
parent baab37ae2d
commit dec5191157
8 changed files with 142 additions and 35 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
"""FastAPI Vue integration - serve Vue frontend from FastAPI."""
from .environ import env
from .staticfiles import Frontend
__all__ = ["Frontend"]
__all__ = ["Frontend", "env"]
+46
View File
@@ -0,0 +1,46 @@
"""Access to the project's fastapi-vue environment variables.
The project entry point (generated __main__.py) sets FASTAPI_VUE to the
project-specific prefix (e.g. "MY_APP"). Project settings are then passed
as "<PREFIX>_*" environment variables; this module is the single place
that resolves those names.
"""
import os
PREFIX_VARIABLE = "FASTAPI_VUE"
class _Env:
"""Lazy accessors for the project's "<PREFIX>_*" environment variables.
Evaluated on each access. Value accessors return None when FASTAPI_VUE
or the variable itself is not set.
"""
@property
def prefix(self) -> str | None:
"""Return the project prefix from the FASTAPI_VUE environment variable."""
return os.environ.get(PREFIX_VARIABLE) or None
def _get(self, name: str) -> str | None:
prefix = self.prefix
return os.environ.get(f"{prefix}_{name}") if prefix else None
@property
def dev(self) -> bool:
"""Check whether running under the devserver (<PREFIX>_DEV=1)."""
return self._get("DEV") == "1"
@property
def vite_url(self) -> str | None:
"""Return the vite devserver URL (<PREFIX>_VITE_URL), if set."""
return self._get("VITE_URL")
@property
def backend_url(self) -> str | None:
"""Return the backend URL (<PREFIX>_BACKEND_URL), if set."""
return self._get("BACKEND_URL")
env = _Env()
+11 -4
View File
@@ -15,6 +15,7 @@ from uvicorn import Config, Server
from uvicorn.main import STARTUP_FAILURE
from uvicorn.supervisors import ChangeReload, Multiprocess
from .environ import env
from .hostutil import parse_endpoints
from .logging import (
install_access_log,
@@ -44,10 +45,16 @@ def _bind_hosts(host: str) -> list[str]:
def _connect_url(endpoints: list[dict]) -> str:
"""Return a URL the user can connect to for the first TCP endpoint."""
for key, value in sorted(os.environ.items()):
if key.endswith("_VITE_URL") and value:
return value
"""Return a URL the user can connect to for the first TCP endpoint.
When running under the devserver (<PREFIX>_VITE_URL is set), the vite
devserver URL is shown instead, as that is where the page is served.
Wildcard binds (0.0.0.0, ::) are shown as localhost, as that is the
address a user can actually open. Unix-socket-only setups show plain
http://localhost (the typical reverse-proxy target).
"""
if vite_url := env.vite_url:
return vite_url
for endpoint in endpoints:
host = endpoint.get("host")
if host is None:
+4 -1
View File
@@ -19,6 +19,8 @@ from starlette.exceptions import HTTPException
from starlette.routing import Route
from zstandard import ZstdCompressor
from .environ import env
logger = logging.getLogger("uvicorn.error") # Use FastAPI logging style
__all__ = ["Frontend"]
@@ -287,7 +289,8 @@ class Frontend:
def _devmode_respond(_request: Request, _name: str = "") -> JSONResponse:
"""Return error response directing to Vite server."""
at = f" at {env.vite_url}" if env.vite_url else ""
return JSONResponse(
status_code=409,
content={"detail": "[devmode] Use Vite devserver instead."},
content={"detail": f"[devmode] Use Vite devserver{at} instead."},
)