fix: reconfigure stdout to UTF-8 on Windows to prevent UnicodeEncodeError on startup (#4493)
* fix: reconfigure stdout UTF-8 on Windows to prevent UnicodeEncodeError from emoji * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix: default frontend_path when None to fix blank page when venv is pre-activated * Restore Windows UTF-8 stdout fix dropped in earlier commit The cp1252 console encoding on Windows cannot render emoji characters used in startup messages (e.g. print("✅ Frontend loaded ...")). This causes UnicodeEncodeError and crashes the server before it starts. Place sys.stdout.reconfigure(encoding="utf-8", errors="replace") at the top of run_server(), unconditionally before any print() or structlog call, so all emoji output is covered -- including the frontend status messages and silent=True paths that the original placement missed. Guarded by sys.platform == "win32" and hasattr check, so it is a no-op on Linux/macOS and safe in non-standard stdout environments (Jupyter, piped IO). * fix: preserve run_server(None) as headless, fix CLI frontend kwarg Remove the frontend_path=None fallback in run_server() that changed None from "headless/API-only" to "mount bundled frontend", breaking backwards compatibility for embedders. The blank-page bug was actually caused by the CLI wrappers always passing frontend_path=frontend (even when frontend=None), which overrode run_server()'s default. Fix studio.py and ui.py to only pass frontend_path when the user explicitly sets --frontend. * fix: use timeout loop for shutdown event in ui command Match studio_default()'s shutdown loop that uses a 1-second timeout on Event.wait(). Without a timeout, the bare wait() blocks at the C level on Linux, preventing Python from delivering SIGINT (Ctrl+C). --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Daniel Han <danielhanchen@gmail.com>
This commit is contained in:
parent
96edad9c95
commit
981f477e31
3 changed files with 20 additions and 13 deletions
|
|
@ -175,6 +175,14 @@ def run_server(
|
|||
"""
|
||||
global _server, _shutdown_event
|
||||
|
||||
# On Windows the default console encoding (cp1252) cannot encode emoji.
|
||||
# Reconfigure stdout to UTF-8 so startup messages do not crash the server.
|
||||
if sys.platform == "win32" and hasattr(sys.stdout, "reconfigure"):
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding = "utf-8", errors = "replace")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
import nest_asyncio
|
||||
|
||||
nest_asyncio.apply()
|
||||
|
|
|
|||
|
|
@ -133,12 +133,10 @@ def studio_default(
|
|||
display_host = _resolve_external_ip() if host == "0.0.0.0" else host
|
||||
typer.echo(f"Starting Unsloth Studio on http://{display_host}:{port}")
|
||||
|
||||
run_server(
|
||||
host = host,
|
||||
port = port,
|
||||
frontend_path = frontend,
|
||||
silent = silent,
|
||||
)
|
||||
run_kwargs = dict(host = host, port = port, silent = silent)
|
||||
if frontend is not None:
|
||||
run_kwargs["frontend_path"] = frontend
|
||||
run_server(**run_kwargs)
|
||||
|
||||
from studio.backend.run import _shutdown_event
|
||||
|
||||
|
|
|
|||
|
|
@ -80,18 +80,19 @@ def ui(
|
|||
display_host = _resolve_external_ip() if host == "0.0.0.0" else host
|
||||
typer.echo(f"Starting Unsloth Studio on http://{display_host}:{port}")
|
||||
|
||||
run_server(
|
||||
host = host,
|
||||
port = port,
|
||||
frontend_path = frontend,
|
||||
silent = silent,
|
||||
)
|
||||
run_kwargs = dict(host = host, port = port, silent = silent)
|
||||
if frontend is not None:
|
||||
run_kwargs["frontend_path"] = frontend
|
||||
run_server(**run_kwargs)
|
||||
|
||||
from studio.backend.run import _shutdown_event
|
||||
|
||||
try:
|
||||
if _shutdown_event is not None:
|
||||
_shutdown_event.wait()
|
||||
# NOTE: Event.wait() without a timeout blocks at the C level
|
||||
# on Linux, preventing Python from delivering SIGINT (Ctrl+C).
|
||||
while not _shutdown_event.is_set():
|
||||
_shutdown_event.wait(timeout = 1)
|
||||
else:
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue