mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
fix(ci): refresh vulnerable lock pins and docs key parsing
Upgrade locked anyio to 4.15.1 and soupsieve to 2.9.2 so osv-scanner clears GHSA-5p39-cfhj-2xmp, GHSA-82r6-8w77-94w6, GHSA-gjv8-xp57-g29c, and GHSA-j934-xhv5-fg8f. Read router setting names from the first column of the reference table, and mark the two hook-boundary patches as intentional test seams.
This commit is contained in:
parent
d7694c26fd
commit
3106c6c862
3 changed files with 41 additions and 40 deletions
|
|
@ -17,9 +17,7 @@ def get_init_params(cls: Type) -> list[str]:
|
|||
A list of parameter names.
|
||||
"""
|
||||
if not hasattr(cls, "__init__"):
|
||||
raise ValueError(
|
||||
f"The provided class {cls.__name__} does not have an __init__ method."
|
||||
)
|
||||
raise ValueError(f"The provided class {cls.__name__} does not have an __init__ method.")
|
||||
|
||||
init_method = cls.__init__
|
||||
argspec = inspect.getfullargspec(init_method)
|
||||
|
|
@ -28,6 +26,24 @@ def get_init_params(cls: Type) -> list[str]:
|
|||
return argspec.args[1:] # Exclude 'self'
|
||||
|
||||
|
||||
def documented_table_keys(table_content: str) -> set[str]:
|
||||
"""Return the first cell of each markdown table row.
|
||||
|
||||
A ``| a | b |`` search consumes the delimiter, so a 4-column reference table
|
||||
(odd pipe count) hides every other row's setting name.
|
||||
"""
|
||||
keys: set[str] = set()
|
||||
for line in table_content.splitlines():
|
||||
stripped = line.strip()
|
||||
if not stripped.startswith("|"):
|
||||
continue
|
||||
first_cell = stripped.strip("|").split("|", 1)[0].strip()
|
||||
if not first_cell or set(first_cell) <= {"-", ":"} or first_cell == "Name":
|
||||
continue
|
||||
keys.add(first_cell)
|
||||
return keys
|
||||
|
||||
|
||||
router_init_params = set(get_init_params(litellm.router.Router))
|
||||
print(router_init_params)
|
||||
router_init_params.remove("model_list")
|
||||
|
|
@ -36,29 +52,18 @@ router_init_params.remove("model_list")
|
|||
_test_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
_repo_root = os.path.abspath(os.path.join(_test_dir, "..", ".."))
|
||||
print(os.listdir(_repo_root))
|
||||
docs_path = os.path.join(
|
||||
_repo_root, "docs", "my-website", "docs", "proxy", "config_settings.md"
|
||||
)
|
||||
documented_keys = set()
|
||||
docs_path = os.path.join(_repo_root, "docs", "my-website", "docs", "proxy", "config_settings.md")
|
||||
documented_keys: set[str] = set()
|
||||
try:
|
||||
with open(docs_path, "r", encoding="utf-8") as docs_file:
|
||||
content = docs_file.read()
|
||||
|
||||
# Find the section titled "general_settings - Reference"
|
||||
general_settings_section = re.search(
|
||||
r"### router_settings - Reference(.*?)###", content, re.DOTALL
|
||||
)
|
||||
# Find the section titled "router_settings - Reference"
|
||||
general_settings_section = re.search(r"### router_settings - Reference(.*?)###", content, re.DOTALL)
|
||||
if general_settings_section:
|
||||
# Extract the table rows, which contain the documented keys
|
||||
table_content = general_settings_section.group(1)
|
||||
doc_key_pattern = re.compile(
|
||||
r"\|\s*([^\|]+?)\s*\|"
|
||||
) # Capture the key from each row of the table
|
||||
documented_keys.update(doc_key_pattern.findall(table_content))
|
||||
documented_keys.update(documented_table_keys(general_settings_section.group(1)))
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
f"Error reading documentation: {e}, \n repo base - {os.listdir(_repo_root)}"
|
||||
)
|
||||
raise Exception(f"Error reading documentation: {e}, \n repo base - {os.listdir(_repo_root)}")
|
||||
|
||||
|
||||
# Compare and find undocumented keys
|
||||
|
|
@ -70,12 +75,6 @@ for key in sorted(router_init_params):
|
|||
print(key)
|
||||
|
||||
if undocumented_keys:
|
||||
raise Exception(
|
||||
f"\nKeys not documented in 'router settings - Reference': {undocumented_keys}"
|
||||
)
|
||||
raise Exception(f"\nKeys not documented in 'router settings - Reference': {undocumented_keys}")
|
||||
else:
|
||||
print(
|
||||
"\nAll keys are documented in 'router settings - Reference'. - {}".format(
|
||||
router_init_params
|
||||
)
|
||||
)
|
||||
print("\nAll keys are documented in 'router settings - Reference'. - {}".format(router_init_params))
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ EXAMPLE_ANTHROPIC_MESSAGES_RESULT = {
|
|||
|
||||
|
||||
def mock_patch_anthropic_messages():
|
||||
return mock.patch(
|
||||
return mock.patch( # test-quality-ok: hook metadata is only observable on the router call this route forwards
|
||||
"litellm.proxy.proxy_server.llm_router.anthropic_messages",
|
||||
return_value=EXAMPLE_ANTHROPIC_MESSAGES_RESULT,
|
||||
)
|
||||
|
|
@ -107,10 +107,12 @@ async def test_experimental_anthropic_messages_runs_proxy_async_pre_call_hook(
|
|||
monkeypatch.setattr(litellm, "callbacks", [AnthropicMessagesPreCallHook()])
|
||||
monkeypatch.setattr(litellm, "use_chat_completions_url_for_anthropic_messages", True)
|
||||
|
||||
with mock.patch(
|
||||
"litellm.llms.anthropic.experimental_pass_through.messages.handler.anthropic_messages_handler",
|
||||
return_value=EXAMPLE_ANTHROPIC_MESSAGES_RESULT,
|
||||
) as mock_handler:
|
||||
with (
|
||||
mock.patch( # test-quality-ok: pre_call and pre_request mutations are only observable on the downstream handler kwargs
|
||||
"litellm.llms.anthropic.experimental_pass_through.messages.handler.anthropic_messages_handler",
|
||||
return_value=EXAMPLE_ANTHROPIC_MESSAGES_RESULT,
|
||||
) as mock_handler
|
||||
):
|
||||
response = await anthropic_messages(
|
||||
model="openai/gpt-4o-mini",
|
||||
max_tokens=100,
|
||||
|
|
|
|||
14
uv.lock
generated
14
uv.lock
generated
|
|
@ -315,16 +315,16 @@ vertex = [
|
|||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.13.0"
|
||||
version = "4.15.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
||||
{ name = "idna" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a9/d2/f4d173e22df740bc37b1db102b386ba719b66e95b0f0d751f556b387e6d2/anyio-4.15.1.tar.gz", hash = "sha256:9f28306018cbd6d329e64a36d58256edff76dd996fe423bc957326e578b82a94", size = 276966, upload-time = "2026-09-05T10:42:39.44Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/b8/4bd346e22b28902df4d651910f5242c28d84e4a5c2435ca5c3f797ed7e2e/anyio-4.15.1-py3-none-any.whl", hash = "sha256:6152fdbbf9a77fdec97731721bebf7c4c44f7c29b424b0065826173efc7ed101", size = 132079, upload-time = "2026-09-05T10:42:37.923Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -9080,11 +9080,11 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "soupsieve"
|
||||
version = "2.8.4"
|
||||
version = "2.9.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/47/2c/0a5f6f8ee0d5589e48c7640213ed5175d52cf540a06725b628cc1a45d6ce/soupsieve-2.8.4.tar.gz", hash = "sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e", size = 121110, upload-time = "2026-05-24T13:55:57.154Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/69/99/a6ca3beb3ccacb41fb3321d8a60e5566f9e6467601ef8eba6a17e1b89778/soupsieve-2.9.2.tar.gz", hash = "sha256:4a55d8cf158a9c2e587fa4922f1bbb91d68ac829e2d6f25403a85747c71daf74", size = 122445, upload-time = "2026-08-07T00:57:24.801Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/f5/0c41cb68dcae6b7de4fac4188a3a9589e21fb31df21ea3a2e888db95e6c9/soupsieve-2.8.4-py3-none-any.whl", hash = "sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65", size = 37304, upload-time = "2026-05-24T13:55:55.406Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/dc/ad025c1ee131eba60c69f4dd5779b18fcf1e6b21a343e2162a84d5d133c7/soupsieve-2.9.2-py3-none-any.whl", hash = "sha256:8089a26fd974ca7a1f30276d3d8492ab266ab15af581642dfe8aa162e0c1c823", size = 37370, upload-time = "2026-08-07T00:57:23.524Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue