Spaces:
Configuration error
Configuration error
File size: 6,968 Bytes
e01ce83 | 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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | from __future__ import annotations
import os
import secrets
import socket
import threading
import time
import warnings
from typing import Any
import httpx
import uvicorn
from uvicorn.config import Config
from trackio.launch_utils import colab_check, is_hosted_notebook
INITIAL_PORT_VALUE = int(os.getenv("GRADIO_SERVER_PORT", "7860"))
TRY_NUM_PORTS = int(os.getenv("GRADIO_NUM_PORTS", "100"))
LOCALHOST_NAME = os.getenv("GRADIO_SERVER_NAME", "127.0.0.1")
class _UvicornServer(uvicorn.Server):
def install_signal_handlers(self) -> None:
pass
def run_in_thread(self) -> None:
self.thread = threading.Thread(target=self.run, daemon=True)
self.thread.start()
start = time.time()
while not self.started:
time.sleep(1e-3)
if time.time() - start > 60:
raise RuntimeError(
"Server failed to start. Please check that the port is available."
)
def _bind_host(server_name: str) -> str:
if server_name.startswith("[") and server_name.endswith("]"):
return server_name[1:-1]
return server_name
def start_server(
app: Any,
server_name: str | None = None,
server_port: int | None = None,
ssl_keyfile: str | None = None,
ssl_certfile: str | None = None,
ssl_keyfile_password: str | None = None,
) -> tuple[str, int, str, _UvicornServer]:
server_name = server_name or LOCALHOST_NAME
url_host_name = "localhost" if server_name == "0.0.0.0" else server_name
host = _bind_host(server_name)
server_ports = (
[server_port]
if server_port is not None
else range(INITIAL_PORT_VALUE, INITIAL_PORT_VALUE + TRY_NUM_PORTS)
)
port_used = None
server = None
for port in server_ports:
try:
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((LOCALHOST_NAME, port))
s.close()
config = Config(
app=app,
port=port,
host=host,
log_level="warning",
ssl_keyfile=ssl_keyfile,
ssl_certfile=ssl_certfile,
ssl_keyfile_password=ssl_keyfile_password,
)
server = _UvicornServer(config=config)
server.run_in_thread()
port_used = port
break
except (OSError, RuntimeError):
continue
else:
raise OSError(
f"Cannot find empty port in range: {min(server_ports)}-{max(server_ports)}. "
"Set GRADIO_SERVER_PORT or pass server_port to trackio.show()."
)
assert port_used is not None and server is not None
if ssl_keyfile is not None:
path_to_local_server = f"https://{url_host_name}:{port_used}/"
else:
path_to_local_server = f"http://{url_host_name}:{port_used}/"
return server_name, port_used, path_to_local_server, server
def launch_trackio_dashboard(
starlette_app: Any,
*,
server_name: str | None = None,
server_port: int | None = None,
share: bool | None = None,
share_server_address: str | None = None,
share_server_protocol: str | None = None,
share_server_tls_certificate: str | None = None,
mcp_server: bool = False,
ssl_verify: bool = True,
quiet: bool = False,
) -> tuple[str | None, str | None, str | None, Any]:
from pathlib import Path
from trackio._vendor.networking import normalize_share_url, setup_tunnel
from trackio._vendor.tunneling import BINARY_PATH
is_colab = colab_check()
is_hosted_nb = is_hosted_notebook()
space_id = os.getenv("SPACE_ID")
if share is None:
if is_colab or is_hosted_nb:
if not quiet:
print(
"It looks like you are running Trackio on a hosted Jupyter notebook, which requires "
"`share=True`. Automatically setting `share=True` "
"(set `share=False` in `show()` to disable).\n"
)
share = True
else:
share = os.getenv("GRADIO_SHARE", "").lower() == "true"
sn = server_name
if sn is None and os.getenv("SYSTEM") == "spaces":
sn = "0.0.0.0"
elif sn is None:
sn = LOCALHOST_NAME
server_name_r, server_port_r, local_url, uv_server = start_server(
starlette_app,
server_name=sn,
server_port=server_port,
)
local_api_url = f"{local_url.rstrip('/')}/gradio_api/"
try:
httpx.get(f"{local_api_url}startup-events", verify=ssl_verify, timeout=10)
except Exception as e:
raise RuntimeError(
f"Could not reach startup-events at {local_api_url}startup-events: {e}"
) from e
if share and space_id:
warnings.warn("Setting share=True is not supported on Hugging Face Spaces")
share = False
share_url: str | None = None
if share:
try:
share_tok = secrets.token_urlsafe(32)
proto = share_server_protocol or (
"http" if share_server_address is not None else "https"
)
raw = setup_tunnel(
local_host=server_name_r,
local_port=server_port_r,
share_token=share_tok,
share_server_address=share_server_address,
share_server_tls_certificate=share_server_tls_certificate,
)
share_url = normalize_share_url(raw, proto)
if not quiet:
print(f"* Running on public URL: {share_url}")
print(
"\nThis share link expires in 1 week. For permanent hosting, deploy to Hugging Face Spaces."
)
except Exception as e:
share_url = None
if not quiet:
from trackio._vendor.gradio_exceptions import ChecksumMismatchError
if isinstance(e, ChecksumMismatchError):
print(
"\nCould not create share link. Checksum mismatch for frpc binary."
)
elif Path(BINARY_PATH).exists():
print(
"\nCould not create share link. Check your internet connection or https://status.gradio.app."
)
else:
print(
f"\nCould not create share link. Missing frpc at {BINARY_PATH}. {e}"
)
if not share_url and not quiet:
print("* To create a public link, set `share=True` in `trackio.show()`.")
if mcp_server and not quiet:
base = share_url or local_url.rstrip("/")
print(f"\n* MCP streamable HTTP: {base}/gradio_api/mcp/")
return local_url, share_url, local_api_url, uv_server
def url_ok_local(local_url: str) -> bool:
from trackio._vendor.networking import url_ok
return url_ok(local_url)
|