57 lines
1.6 KiB
Python
57 lines
1.6 KiB
Python
from pathlib import Path
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi import Response
|
|
from fastapi import status
|
|
from fastapi.responses import RedirectResponse
|
|
from fastapi.staticfiles import StaticFiles
|
|
|
|
|
|
def mount_docs_static(app: FastAPI, *, docs_route: str, site_dir: Path) -> None:
|
|
"""Mount the pre-built static docs site, or expose a clear missing-build response."""
|
|
normalized_route = docs_route.rstrip("/") or "/docs"
|
|
docs_root = f"{normalized_route}/"
|
|
|
|
async def redirect_to_docs_root() -> RedirectResponse:
|
|
return RedirectResponse(
|
|
url=docs_root, status_code=status.HTTP_307_TEMPORARY_REDIRECT
|
|
)
|
|
|
|
app.add_api_route(
|
|
normalized_route,
|
|
redirect_to_docs_root,
|
|
methods=["GET", "HEAD"],
|
|
include_in_schema=False,
|
|
)
|
|
|
|
if site_dir.is_dir():
|
|
app.mount(
|
|
normalized_route,
|
|
StaticFiles(directory=site_dir, html=True),
|
|
name="docs",
|
|
)
|
|
return
|
|
|
|
async def docs_not_built() -> Response:
|
|
return Response(
|
|
content=(
|
|
"Static docs have not been built yet. "
|
|
"Run `uv run zensical build` before using this route."
|
|
),
|
|
media_type="text/plain",
|
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
)
|
|
|
|
app.add_api_route(
|
|
normalized_route,
|
|
docs_not_built,
|
|
methods=["GET"],
|
|
include_in_schema=False,
|
|
)
|
|
app.add_api_route(
|
|
f"{normalized_route}/{{path:path}}",
|
|
docs_not_built,
|
|
methods=["GET"],
|
|
include_in_schema=False,
|
|
)
|