physix / scripts /space_app.py
Pratyush-01's picture
Upload folder using huggingface_hub
0e24aff verified
"""Space entrypoint: physix.server.app:app + static UI mount.
Imported at runtime by the Dockerfile's CMD via ``uvicorn _space_app:app``.
What this wrapper adds on top of ``physix.server.app:app``:
1. ``GET /`` -> 302 to ``/web/`` (so the bare Space URL
doesn't 404 — OpenEnv's ``create_fastapi_app``
does NOT add a root redirect; that's only in
the higher-level wrapper which mounts Gradio
at ``/web`` and would clobber our React SPA).
2. ``GET /web`` -> 302 to ``/web/`` (same reason; users hit the
no-trailing-slash variant from outside links).
3. ``StaticFiles`` mount at ``/web/`` serving the built Vite SPA. The
vite build was run with ``--base=/web/`` so all asset URLs in the
emitted ``index.html`` already include the prefix.
Kept as a real .py file (not a heredoc inside the Dockerfile) so any
syntax error is caught by the build's static analysis rather than at
runtime — saved several deploy-fail loops in earlier iterations.
"""
from __future__ import annotations
from pathlib import Path
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from physix.server.app import app
_STATIC_DIR = Path("/app/static")
@app.get("/", include_in_schema=False)
async def _root_redirect() -> RedirectResponse:
return RedirectResponse(url="/web/")
@app.get("/web", include_in_schema=False)
async def _web_no_slash_redirect() -> RedirectResponse:
return RedirectResponse(url="/web/")
if _STATIC_DIR.is_dir():
# html=True makes StaticFiles serve index.html for directory hits and
# fall back to it for unknown sub-paths (so client-side React routing
# works). Mounted last so registered API routes (/web/metadata,
# /web/reset, /web/step from OpenEnv; /interactive/* from physix)
# always win over the static handler.
app.mount(
"/web",
StaticFiles(directory=str(_STATIC_DIR), html=True),
name="ui",
)