File size: 2,587 Bytes
e55366b 4b49311 e55366b 4b49311 e55366b 4b49311 e55366b 4b49311 e55366b 4b49311 e55366b 4b49311 e55366b 4b49311 e55366b 4b49311 e55366b 4b49311 e55366b 7d6df10 4b49311 e55366b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #!/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 "<no stdout>")
print("try-on stderr:\n", err or "<no stderr>")
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])
|