mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-12 08:42:18 +00:00
fix(proxy): stop prepending SERVER_ROOT_PATH to the UI config path on every restart
The proxy rewrites the packaged UI files in place on each start. For a SERVER_ROOT_PATH ending in /litellm (e.g. /foo/litellm), the rewritten config path still contains the original one, so every restart prepended the root path again (/foo/foo/litellm/.well-known/litellm-ui-config), the request 404'd and the UI stayed on "Loading...". Leave already-rewritten paths alone so the rewrite is idempotent. Fixes #44517
This commit is contained in:
parent
c0ca4a51f7
commit
aeb333273d
2 changed files with 39 additions and 4 deletions
|
|
@ -2365,6 +2365,20 @@ try:
|
|||
except (PermissionError, OSError) as e:
|
||||
return False, str(e)
|
||||
|
||||
def _rewrite_ui_config_path(content: str, server_root_path: str) -> str:
|
||||
"""
|
||||
Point the UI's config request at server_root_path, keeping already-rewritten paths.
|
||||
|
||||
The UI files are rewritten in place on every startup, and when server_root_path ends
|
||||
in /litellm the rewritten path still contains the original one, so a plain replace
|
||||
would prepend the root path again on each restart.
|
||||
"""
|
||||
ui_config_path = f"{server_root_path}/.well-known/litellm-ui-config"
|
||||
return ui_config_path.join(
|
||||
part.replace("/litellm/.well-known/litellm-ui-config", ui_config_path)
|
||||
for part in content.split(ui_config_path)
|
||||
)
|
||||
|
||||
# Use a writable runtime UI directory whenever possible.
|
||||
# This prevents mutating the packaged UI directory (e.g. site-packages or the repo checkout)
|
||||
# and ensures extensionless routes like /ui/login work via <route>/index.html.
|
||||
|
|
@ -2480,10 +2494,7 @@ try:
|
|||
)
|
||||
|
||||
# Replace the /.well-known/litellm-ui-config with the server root path
|
||||
modified_content = modified_content.replace(
|
||||
"/litellm/.well-known/litellm-ui-config",
|
||||
f"{server_root_path}/.well-known/litellm-ui-config",
|
||||
)
|
||||
modified_content = _rewrite_ui_config_path(modified_content, server_root_path)
|
||||
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write(modified_content)
|
||||
|
|
|
|||
24
tests/unit/proxy/proxy_server/test_ui_config_path.py
Normal file
24
tests/unit/proxy/proxy_server/test_ui_config_path.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
"""SERVER_ROOT_PATH rewrite of the UI's config request (#44517)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from litellm.proxy.proxy_server import _rewrite_ui_config_path
|
||||
|
||||
# The two shapes the config path takes in the packaged UI bundle
|
||||
PACKAGED_UI_CHUNK = (
|
||||
'fetch(`${g}/litellm/.well-known/litellm-ui-config`);const u={url:"/litellm/.well-known/litellm-ui-config"}'
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("server_root_path", ["/foo", "/litellm", "/foo/litellm"])
|
||||
def test_restarts_keep_a_single_root_path_prefix(server_root_path: str) -> None:
|
||||
rewritten = PACKAGED_UI_CHUNK
|
||||
for _ in range(3): # the proxy rewrites the same UI files on every start
|
||||
rewritten = _rewrite_ui_config_path(rewritten, server_root_path)
|
||||
|
||||
assert rewritten == (
|
||||
f"fetch(`${{g}}{server_root_path}/.well-known/litellm-ui-config`);"
|
||||
f'const u={{url:"{server_root_path}/.well-known/litellm-ui-config"}}'
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue