| | """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")) |
| | |
| | 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() |
| |
|