RoboMME / gradio-web /main.py
HongzeFu's picture
7860
c56d129
"""Main entry for Gradio app (single-instance mode for Hugging Face Spaces)."""
import logging
import os
import sys
import tempfile
from pathlib import Path
APP_DIR = Path(__file__).resolve().parent
PROJECT_ROOT = APP_DIR.parent
SRC_DIR = PROJECT_ROOT / "src"
VIDEOS_DIR = APP_DIR / "videos"
TEMP_DEMOS_DIR = PROJECT_ROOT / "temp_demos"
CWD_TEMP_DEMOS_DIR = Path.cwd() / "temp_demos"
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
if str(SRC_DIR) not in sys.path:
sys.path.insert(0, str(SRC_DIR))
def setup_logging() -> logging.Logger:
"""Configure structured logging for Spaces runtime."""
level_name = "DEBUG"
os.environ["LOG_LEVEL"] = level_name
level = logging.DEBUG
try:
sys.stdout.reconfigure(line_buffering=True)
sys.stderr.reconfigure(line_buffering=True)
except Exception:
pass
logging.basicConfig(
level=level,
format=(
"%(asctime)s | %(levelname)s | %(name)s | "
"pid=%(process)d tid=%(threadName)s | %(message)s"
),
stream=sys.stdout,
force=True,
)
for noisy_logger in [
"asyncio",
"httpx",
"httpcore",
"urllib3",
"matplotlib",
"PIL",
"h5py",
"trimesh",
"toppra",
]:
logging.getLogger(noisy_logger).setLevel(logging.WARNING)
logging.getLogger("robomme").setLevel(logging.DEBUG)
logger = logging.getLogger("robomme.main")
logger.info("Logging initialized with LOG_LEVEL=%s", level_name)
return logger
LOGGER = setup_logging()
def log_runtime_graphics_env():
"""Log graphics-related runtime env so Spaces diagnostics are visible in stdout."""
keys = [
"CUDA_VISIBLE_DEVICES",
"NVIDIA_VISIBLE_DEVICES",
"NVIDIA_DRIVER_CAPABILITIES",
"VK_ICD_FILENAMES",
"OMP_NUM_THREADS",
"SAPIEN_RENDER_DEVICE",
"MUJOCO_GL",
]
snapshot = {key: os.getenv(key) for key in keys}
LOGGER.info("Runtime graphics env: %s", snapshot)
def ensure_media_dirs():
"""Ensure media temp directories exist before first write."""
TEMP_DEMOS_DIR.mkdir(parents=True, exist_ok=True)
CWD_TEMP_DEMOS_DIR.mkdir(parents=True, exist_ok=True)
LOGGER.debug(
"Ensured media dirs: temp_demos=%s cwd_temp_demos=%s",
TEMP_DEMOS_DIR,
CWD_TEMP_DEMOS_DIR,
)
def build_allowed_paths():
"""Build Gradio file access allowlist (absolute, deduplicated)."""
candidates = [
Path.cwd(),
PROJECT_ROOT,
APP_DIR,
VIDEOS_DIR,
TEMP_DEMOS_DIR,
CWD_TEMP_DEMOS_DIR,
Path(tempfile.gettempdir()),
]
deduped = []
seen = set()
for path in candidates:
normalized = str(path.resolve())
if normalized not in seen:
seen.add(normalized)
deduped.append(normalized)
LOGGER.debug("Allowed paths resolved (%d): %s", len(deduped), deduped)
return deduped
def main():
from ui_layout import CSS, create_ui_blocks
LOGGER.info("Starting Gradio real environment entrypoint: %s", __file__)
log_runtime_graphics_env()
ensure_media_dirs()
os.environ.setdefault("ROBOMME_TEMP_DEMOS_DIR", str(TEMP_DEMOS_DIR))
allowed_paths = build_allowed_paths()
server_port = int(os.getenv("PORT", "7860"))
#server_port = 7862
LOGGER.info(
"Launching UI with server_name=%s server_port=%s ROBOMME_TEMP_DEMOS_DIR=%s",
"0.0.0.0",
server_port,
os.environ.get("ROBOMME_TEMP_DEMOS_DIR"),
)
LOGGER.debug("Python path head entries: %s", sys.path[:5])
demo = create_ui_blocks()
demo.launch(
server_name="0.0.0.0",
server_port=server_port,
allowed_paths=allowed_paths,
ssr_mode=False,
debug=True,
show_error=True,
quiet=False,
theme=getattr(demo, "theme", None),
css=CSS,
head=getattr(demo, "head", None),
)
if __name__ == "__main__":
main()