From d1529b1466dec0e40f5825e25e7a6d96dae4df9e Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Wed, 24 Jun 2026 03:49:19 -0700 Subject: [PATCH] Tidy verbose Studio launch messages (#6628) * Tidy verbose Studio launch messages The reachability failure hint, the loopback deploy block, and the stop hint were several lines longer than they needed to be, and the banner printed a Tip line that just repeated the URL already shown above. Shorten them while keeping the useful detail (cloud provider names, the SSH local-forward workaround, the relaunch command, the trusted-network and macOS Ctrl+C notes). No behavior change, output wording only. * Refine launch-message wording after review Apply review feedback so the launch messages read well for both experts and general users: - reachability hint: restore the 'from your own computer' cue and put the ssh command on its own line so it stops wrapping, name the cloud rules precisely (GCP firewall / Azure NSG rule), and restore 'in your browser' - loopback banner: add the missing colon, drop the Ctrl+C duplication (the stop hint already covers it), and explain the exposure in plain language instead of 'exposes the API on every interface' - stop hint: trim so it fits an 80-column terminal without wrapping - replace two pre-existing em dashes with -- --- studio/backend/run.py | 29 +++++++---------------------- studio/backend/startup_banner.py | 29 ++++++++--------------------- 2 files changed, 15 insertions(+), 43 deletions(-) diff --git a/studio/backend/run.py b/studio/backend/run.py index bb57db9bcb..481fd623f3 100644 --- a/studio/backend/run.py +++ b/studio/backend/run.py @@ -340,34 +340,19 @@ def _verify_global_reachability(display_host: str, port: int) -> None: f"the public internet ({err_nodes}/{total} probe nodes failed).{reset}", flush = True, ) - print(f"{dim} Common causes:{reset}", flush = True) print( - f"{dim} * AWS -- the instance's Security Group doesn't " - f"allow inbound TCP {port}.{reset}", + f"{dim} Usually a cloud firewall (AWS security group, " + f"GCP firewall / Azure NSG rule) or home router isn't " + f"allowing inbound TCP {port}.{reset}", flush = True, ) print( - f"{dim} * GCP -- no firewall rule allowing TCP {port} " - f"for the instance's network tag.{reset}", + f"{dim} No firewall change needed -- SSH local-forward " + f"from your own computer:{reset}", flush = True, ) print( - f"{dim} * Azure / other clouds -- equivalent NSG / " - f"firewall rule missing.{reset}", - flush = True, - ) - print( - f"{dim} * Home -- your router isn't port-forwarding " - f"{port} to this machine.{reset}", - flush = True, - ) - print( - f"{dim} Workaround that needs no firewall changes -- " - f"SSH local-forward from your laptop:{reset}", - flush = True, - ) - print( - f"{dim} ssh -L {port}:localhost:{port} " f"@{display_host}{reset}", + f"{dim} ssh -L {port}:localhost:{port} @{display_host}{reset}", flush = True, ) print( @@ -622,7 +607,7 @@ def _graceful_shutdown(server = None): Windows where atexit handlers are unreliable after Ctrl+C. """ _remove_pid_file() - logger.info("Graceful shutdown initiated — cleaning up subprocesses...") + logger.info("Graceful shutdown initiated -- cleaning up subprocesses...") # 1. Shut down uvicorn (releases the listening socket). if server is not None: diff --git a/studio/backend/startup_banner.py b/studio/backend/startup_banner.py index 52ac8cb012..13d6f8ef5e 100644 --- a/studio/backend/startup_banner.py +++ b/studio/backend/startup_banner.py @@ -3,7 +3,7 @@ """Terminal banner for Studio startup. -Stdlib only — safe to import without the rest of the backend. +Stdlib only -- safe to import without the rest of the backend. """ from __future__ import annotations @@ -49,10 +49,10 @@ def print_studio_stop_hint() -> None: [ "", style( - " To stop Unsloth Studio: press Ctrl+C in this terminal.", + " To stop Unsloth Studio: press Ctrl+C " + "(Control+C, not Command+C, on macOS).", stop_hint_style, ), - style(" (On macOS this is Control+C, not Command+C.)", dim), style("─" * 52, dim), "", ] @@ -101,7 +101,6 @@ def print_studio_access_banner( # Use the loopback URL only when reachable on loopback; otherwise show # the actual bound address. primary_url = loopback_url if listen_all or loopback_bind else external_url - tip_url = alt_local if listen_all or loopback_bind else external_url api_base = primary_url lines: list[str] = [ @@ -145,10 +144,6 @@ def print_studio_access_banner( style(f" {api_base}/api", secondary), style(f" {api_base}/api/health", secondary), style("─" * 52, dim), - style( - f" Tip: if you are on this computer, open {tip_url}/ in your browser.", - dim, - ), ] ) @@ -157,23 +152,15 @@ def print_studio_access_banner( [ "", style( - " Studio is only reachable on this machine (bound to 127.0.0.1).", + " Reachable on this machine only (bound to 127.0.0.1).", secondary, ), style( - " To deploy and access globally:", + f" To expose it, stop and relaunch with: unsloth studio -H 0.0.0.0 -p {port}", secondary, ), style( - " 1. press Ctrl+C to stop Studio", - secondary, - ), - style( - f" 2. relaunch with: unsloth studio -H 0.0.0.0 -p {port}", - secondary, - ), - style( - " Only do this on trusted networks -- it exposes the API on every interface.", + " Only on trusted networks -- anyone who reaches this machine can use Studio.", secondary, ), ] @@ -184,10 +171,10 @@ def print_studio_access_banner( [ "", style( - " To stop Unsloth Studio: press Ctrl+C in this terminal.", + " To stop Unsloth Studio: press Ctrl+C " + "(Control+C, not Command+C, on macOS).", stop_hint_style, ), - style(" (On macOS this is Control+C, not Command+C.)", dim), style("─" * 52, dim), "", ]