mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
fix(proxy): read local config.yaml as utf-8 regardless of OS locale
ProxyConfig loaded the local config file with the locale default encoding, which crashes or silently corrupts UTF-8 configs on Windows (cp1252). The S3 and GCS config loaders already decode UTF-8 explicitly; this brings the local path in line. Includes are covered via _load_yaml_file.
This commit is contained in:
parent
f1f0a0bacd
commit
770b0da0b6
2 changed files with 34 additions and 2 deletions
|
|
@ -3804,7 +3804,7 @@ class ProxyConfig:
|
|||
Load and parse a YAML file
|
||||
"""
|
||||
try:
|
||||
with open(file_path, "r") as file:
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
return yaml.safe_load(file) or {}
|
||||
except Exception as e:
|
||||
raise Exception(f"Error loading yaml file {file_path}: {str(e)}")
|
||||
|
|
@ -3825,7 +3825,7 @@ class ProxyConfig:
|
|||
# Load existing config
|
||||
## Yaml
|
||||
if os.path.exists(f"{file_path}"):
|
||||
with open(f"{file_path}", "r") as config_file:
|
||||
with open(f"{file_path}", "r", encoding="utf-8") as config_file:
|
||||
config = yaml.safe_load(config_file)
|
||||
elif file_path is not None:
|
||||
raise Exception(f"Config file not found: {file_path}")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Pins covered:
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import builtins
|
||||
import json
|
||||
import os
|
||||
from types import SimpleNamespace
|
||||
|
|
@ -325,6 +326,24 @@ def test_ProxyConfig__load_yaml_file_raises_on_missing_file():
|
|||
pc._load_yaml_file("/no/such/file.yaml")
|
||||
|
||||
|
||||
def _open_with_ascii_default(real_open):
|
||||
def opener(file, mode="r", *args, encoding=None, **kwargs):
|
||||
if "b" not in mode and encoding is None:
|
||||
encoding = "ascii"
|
||||
return real_open(file, mode, *args, encoding=encoding, **kwargs)
|
||||
|
||||
return opener
|
||||
|
||||
|
||||
def test_ProxyConfig__load_yaml_file_reads_utf8_under_non_utf8_locale(tmp_path, monkeypatch):
|
||||
f = tmp_path / "c.yaml"
|
||||
f.write_text('general_settings:\n alerting_args:\n daily_report_note: "Pākīhi – café"\n', encoding="utf-8")
|
||||
monkeypatch.setattr(builtins, "open", _open_with_ascii_default(open))
|
||||
pc = ProxyConfig()
|
||||
result = pc._load_yaml_file(str(f))
|
||||
assert result == {"general_settings": {"alerting_args": {"daily_report_note": "Pākīhi – café"}}}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ProxyConfig._get_config_from_file
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -350,6 +369,19 @@ async def test_ProxyConfig__get_config_from_file_missing_path_raises():
|
|||
await pc._get_config_from_file(config_file_path="/no/such/file.yaml")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ProxyConfig__get_config_from_file_reads_utf8_under_non_utf8_locale(tmp_path, monkeypatch):
|
||||
f = tmp_path / "c.yaml"
|
||||
f.write_text(
|
||||
'model_list:\n - model_name: "summariser – bāsic"\n litellm_params:\n model: gpt-4o\n',
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setattr(builtins, "open", _open_with_ascii_default(open))
|
||||
pc = ProxyConfig()
|
||||
result = await pc._get_config_from_file(config_file_path=str(f))
|
||||
assert result == {"model_list": [{"model_name": "summariser – bāsic", "litellm_params": {"model": "gpt-4o"}}]}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ProxyConfig._process_includes
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue