#!/usr/bin/env python3 """ Robust launcher for Spaces: - Starts the FastAPI app (e.g. main:app) on 127.0.0.1:5350 using uvicorn as a subprocess. - Waits until the health endpoint responds. - Then execs the Gradio app file (gradio_app.py by default) so Gradio becomes the main foreground process. """ import os import time import requests import subprocess import sys from shutil import which TRYON_MODULE = os.getenv("TRYON_MODULE", "main:app") # your FastAPI module: main:app TRYON_HOST = os.getenv("TRYON_HOST", "127.0.0.1") TRYON_PORT = int(os.getenv("TRYON_PORT", "5350")) HEALTH_PATH = os.getenv("TRYON_HEALTH_PATH", "/api/v1/health") TRYON_HEALTH_URL = f"http://{TRYON_HOST}:{TRYON_PORT}{HEALTH_PATH}" # log level: set TRYON_LOG_LEVEL=debug to get verbose uvicorn logs TRYON_LOG_LEVEL = os.getenv("TRYON_LOG_LEVEL", "info").lower() if TRYON_LOG_LEVEL not in ("critical", "error", "warning", "info", "debug", "trace"): TRYON_LOG_LEVEL = "info" UVICORN_BIN = which("uvicorn") or "uvicorn" UVICORN_CMD = [ UVICORN_BIN, TRYON_MODULE, "--host", TRYON_HOST, "--port", str(TRYON_PORT), "--log-level", TRYON_LOG_LEVEL ] print("Starting try-on server:", " ".join(UVICORN_CMD)) proc = subprocess.Popen(UVICORN_CMD, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # Wait for health to respond timeout = int(os.getenv("TRYON_STARTUP_TIMEOUT", "30")) start = time.time() last_exception = None while True: try: r = requests.get(TRYON_HEALTH_URL, timeout=2) if r.status_code == 200: print("Try-on health OK:", TRYON_HEALTH_URL) break else: print("Try-on health returned:", r.status_code, r.text[:200]) except Exception as e: last_exception = e if time.time() - start > timeout: # Dump subprocess stdout/stderr for debugging print("Try-on failed to start within timeout. Dumping logs...") try: out, err = proc.communicate(timeout=2) print("try-on stdout:\n", out or "") print("try-on stderr:\n", err or "") except Exception: proc.kill() print("Could not communicate with try-on process; killed it.") raise RuntimeError(f"Try-on failed to start within {timeout}s. Last error: {last_exception}") time.sleep(0.5) # Exec Gradio app so it becomes PID1 (Spaces expects the main app in foreground) GRADIO_APP = os.getenv("GRADIO_APP_FILE", "gradio_app.py") print("Launching Gradio app:", GRADIO_APP) os.execv(sys.executable, [sys.executable, GRADIO_APP])