From ad83c98d36dec73178fd4006a3c23e01ddee43b4 Mon Sep 17 00:00:00 2001 From: bunnysayzz Date: Mon, 14 Sep 2026 12:53:46 +0530 Subject: [PATCH] fix(mcp): ruff format and lint nits on yaml openapi loader --- .../mcp_server/openapi_to_mcp_generator.py | 11 +++---- tests/mcp_tests/test_openapi_spec_path_url.py | 30 +++++++------------ 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py b/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py index 44a954d2a70..c94bec5bfa0 100644 --- a/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py +++ b/litellm/proxy/_experimental/mcp_server/openapi_to_mcp_generator.py @@ -65,8 +65,7 @@ def _import_yaml(): return _yaml except ImportError: raise ImportError( - "PyYAML is required to parse YAML OpenAPI specs. " - "Install it with: pip install pyyaml" + "PyYAML is required to parse YAML OpenAPI specs. Install it with: pip install pyyaml" ) from None @@ -183,9 +182,7 @@ def load_openapi_spec(filepath: str) -> dict[str, Any]: if lower.endswith((".yaml", ".yml")): return True # Check Content-Type header - if content_type and "yaml" in content_type: - return True - return False + return bool(content_type and "yaml" in content_type) async def load_openapi_spec_async(filepath: str, *, max_bytes: int | None = None) -> dict[str, Any]: @@ -205,7 +202,7 @@ async def load_openapi_spec_async(filepath: str, *, max_bytes: int | None = None # proper Content-Type headers (common with raw GitHub URLs). try: return r.json() - except Exception: + except ValueError: return _import_yaml().safe_load(r.text) # fallback: local file @@ -220,7 +217,7 @@ async def load_openapi_spec_async(filepath: str, *, max_bytes: int | None = None with open(filepath, "r", encoding="utf-8") as f: try: return json.load(f) - except Exception: + except ValueError: f.seek(0) return _import_yaml().safe_load(f) diff --git a/tests/mcp_tests/test_openapi_spec_path_url.py b/tests/mcp_tests/test_openapi_spec_path_url.py index 78e1ff91ae5..3e91bde0333 100644 --- a/tests/mcp_tests/test_openapi_spec_path_url.py +++ b/tests/mcp_tests/test_openapi_spec_path_url.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Dict +from typing import Any import httpx import pytest @@ -33,7 +33,7 @@ class _FakeAsyncHTTPHandler: def test_load_openapi_spec_supports_http_url(monkeypatch: pytest.MonkeyPatch) -> None: url = "http://example.local/openapi.json" - expected: Dict[str, Any] = { + expected: dict[str, Any] = { "openapi": "3.0.0", "info": {"title": "Test API", "version": "1.0.0"}, "paths": {}, @@ -44,7 +44,7 @@ def test_load_openapi_spec_supports_http_url(monkeypatch: pytest.MonkeyPatch) -> resp = httpx.Response(status_code=200, json=expected, request=req) calls = {"get_async_httpx_client": 0} - handler_holder: Dict[str, Any] = {} + handler_holder: dict[str, Any] = {} def fake_get_async_httpx_client(*args, **kwargs): calls["get_async_httpx_client"] += 1 @@ -56,9 +56,7 @@ def test_load_openapi_spec_supports_http_url(monkeypatch: pytest.MonkeyPatch) -> monkeypatch.setattr(gen, "get_async_httpx_client", fake_get_async_httpx_client) # Bypass SSRF validation in test (example.local doesn't resolve) - monkeypatch.setattr( - gen, "async_safe_get", lambda client, url, **kw: client.get(url) - ) + monkeypatch.setattr(gen, "async_safe_get", lambda client, url, **kw: client.get(url)) # Fail loudly if someone reintroduces direct httpx.get() def boom(*args, **kwargs): @@ -73,10 +71,8 @@ def test_load_openapi_spec_supports_http_url(monkeypatch: pytest.MonkeyPatch) -> assert handler_holder["handler"].calls == 1 -def test_load_openapi_spec_supports_local_file_path( - tmp_path, monkeypatch: pytest.MonkeyPatch -) -> None: - expected: Dict[str, Any] = { +def test_load_openapi_spec_supports_local_file_path(tmp_path, monkeypatch: pytest.MonkeyPatch) -> None: + expected: dict[str, Any] = { "openapi": "3.0.0", "info": {"title": "Local API", "version": "1.0.0"}, "paths": {}, @@ -90,9 +86,7 @@ def test_load_openapi_spec_supports_local_file_path( # For local files, shared client must NOT be used. def boom_client(*args, **kwargs): - raise AssertionError( - "get_async_httpx_client() must not be called for local file paths" - ) + raise AssertionError("get_async_httpx_client() must not be called for local file paths") monkeypatch.setattr(gen, "get_async_httpx_client", boom_client) @@ -100,11 +94,9 @@ def test_load_openapi_spec_supports_local_file_path( assert spec == expected -def test_load_openapi_spec_supports_yaml_file( - tmp_path, monkeypatch: pytest.MonkeyPatch -) -> None: +def test_load_openapi_spec_supports_yaml_file(tmp_path, monkeypatch: pytest.MonkeyPatch) -> None: """YAML OpenAPI spec files should be parsed correctly.""" - expected: Dict[str, Any] = { + expected: dict[str, Any] = { "openapi": "3.0.0", "info": {"title": "YAML API", "version": "1.0.0"}, "paths": {}, @@ -140,7 +132,7 @@ def test_load_openapi_spec_url_yaml_content_type( request=req, ) - handler_holder: Dict[str, Any] = {} + handler_holder: dict[str, Any] = {} def fake_get_async_httpx_client(*args, **kwargs): h = _FakeAsyncHTTPHandler(resp, expected_url=url) @@ -169,7 +161,7 @@ def test_load_openapi_spec_url_yaml_fallback( request=req, ) - handler_holder: Dict[str, Any] = {} + handler_holder: dict[str, Any] = {} def fake_get_async_httpx_client(*args, **kwargs): h = _FakeAsyncHTTPHandler(resp, expected_url=url)