Merge pull request #22246 from BerriAI/revert-22238-litellm_supported_endpoints

Revert "[Feature] Add /public/supported_endpoints endpoint"
This commit is contained in:
yuneng-jiang
2026-02-26 17:21:53 -08:00
committed by GitHub
7 changed files with 4 additions and 137 deletions
@@ -404,7 +404,7 @@ This release has a known issue...
- **New Providers** - Provider name, supported endpoints, description
- **New LLM API Endpoints** (optional) - Endpoint, method, description, documentation link
- Only include major new provider integrations, not minor provider updates
- **IMPORTANT**: When adding new providers, also update `provider_endpoints_support.json` (see Section 13)
- **IMPORTANT**: When adding new providers, also update `provider_endpoints_support.json` in the repository root (see Section 13)
### 12. Section Header Counts
@@ -442,7 +442,7 @@ This release has a known issue...
### 13. Update provider_endpoints_support.json
**When adding new providers or endpoints, you MUST also update `litellm/proxy/public_endpoints/provider_endpoints_support.json`.**
**When adding new providers or endpoints, you MUST also update `provider_endpoints_support.json` in the repository root.**
This file tracks which endpoints are supported by each LiteLLM provider and is used to generate documentation.
@@ -1,6 +1,5 @@
import json
import os
import re
from typing import List
import litellm
@@ -24,16 +23,11 @@ from litellm.types.proxy.public_endpoints.public_endpoints import (
AgentCreateInfo,
ProviderCreateInfo,
PublicModelHubInfo,
SupportedEndpointInfo,
SupportedEndpointsResponse,
SupportedProviderInfo,
)
from litellm.types.utils import LlmProviders
router = APIRouter()
_supported_endpoints_cache: SupportedEndpointsResponse | None = None
@router.get(
"/public/model_hub",
@@ -231,68 +225,6 @@ async def get_litellm_blog_posts():
return BlogPostsResponse(posts=posts)
@router.get(
"/public/supported_endpoints",
tags=["public", "providers"],
response_model=SupportedEndpointsResponse,
)
async def get_provider_supported_endpoints() -> SupportedEndpointsResponse:
"""
Return all supported endpoints and which providers support them.
Reads from provider_endpoints_support.json at the repo root.
Result is cached for the lifetime of the process.
"""
global _supported_endpoints_cache
if _supported_endpoints_cache is not None:
return _supported_endpoints_cache
provider_endpoints_support_path = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
"proxy",
"public_endpoints",
"provider_endpoints_support.json",
)
with open(provider_endpoints_support_path, "r") as f:
data = json.load(f)
schema_endpoints = data["_schema"]["provider_slug"]["endpoints"]
endpoints = []
for key, description in schema_endpoints.items():
path_match = re.search(r"(/[\w/{}.()*-]+)", description)
endpoint_path = path_match.group(1) if path_match else f"/{key}"
display_name = key.replace("_", " ").title()
endpoints.append(
SupportedEndpointInfo(
key=key,
display_name=display_name,
endpoint=endpoint_path,
)
)
providers = []
for slug, provider_data in data["providers"].items():
supported = [
endpoint_key
for endpoint_key, supported in provider_data["endpoints"].items()
if supported
]
providers.append(
SupportedProviderInfo(
slug=slug,
display_name=provider_data["display_name"],
supported=supported,
)
)
_supported_endpoints_cache = SupportedEndpointsResponse(
endpoints=endpoints, providers=providers
)
return _supported_endpoints_cache
@router.get(
"/public/agents/fields",
tags=["public", "[beta] Agents"],
@@ -52,20 +52,3 @@ class AgentCreateInfo(BaseModel):
credential_fields: List[AgentCredentialField]
litellm_params_template: Optional[Dict[str, str]] = None
model_template: Optional[str] = None
class SupportedEndpointInfo(BaseModel):
key: str
display_name: str
endpoint: str
class SupportedProviderInfo(BaseModel):
slug: str
display_name: str
supported: List[str]
class SupportedEndpointsResponse(BaseModel):
endpoints: List[SupportedEndpointInfo]
providers: List[SupportedProviderInfo]
@@ -99,7 +99,7 @@ def extract_endpoints_from_sidebars() -> Dict[str, str]:
def load_provider_endpoints_file() -> Dict:
"""Load the provider_endpoints_support.json file."""
repo_root = get_repo_root()
file_path = repo_root / "litellm" / "proxy" / "public_endpoints" / "provider_endpoints_support.json"
file_path = repo_root / "provider_endpoints_support.json"
if not file_path.exists():
print(
@@ -65,7 +65,7 @@ def get_llm_provider_folders() -> Set[str]:
def load_provider_endpoints_file() -> Dict:
"""Load the provider_endpoints_support.json file."""
repo_root = get_repo_root()
file_path = repo_root / "litellm" / "proxy" / "public_endpoints" / "provider_endpoints_support.json"
file_path = repo_root / "provider_endpoints_support.json"
if not file_path.exists():
print(
@@ -87,54 +87,6 @@ def test_get_litellm_model_cost_map_returns_cost_map():
assert "input_cost_per_token" in sample_model_data or "output_cost_per_token" in sample_model_data
def test_get_provider_supported_endpoints():
"""Test /public/supported_endpoints returns correct structure with endpoints and providers."""
app = FastAPI()
app.include_router(router)
client = TestClient(app)
response = client.get("/public/supported_endpoints")
assert response.status_code == 200
data = response.json()
# Check top-level structure
assert "endpoints" in data
assert "providers" in data
assert isinstance(data["endpoints"], list)
assert isinstance(data["providers"], list)
# Verify endpoints structure
assert len(data["endpoints"]) > 0
for endpoint in data["endpoints"]:
assert "key" in endpoint
assert "display_name" in endpoint
assert "endpoint" in endpoint
assert isinstance(endpoint["key"], str)
assert isinstance(endpoint["display_name"], str)
assert endpoint["endpoint"].startswith("/")
# Verify providers structure
assert len(data["providers"]) > 0
for provider in data["providers"]:
assert "slug" in provider
assert "display_name" in provider
assert "supported" in provider
assert isinstance(provider["slug"], str)
assert isinstance(provider["display_name"], str)
assert isinstance(provider["supported"], list)
# Verify some expected endpoints exist
endpoint_keys = {e["key"] for e in data["endpoints"]}
assert "chat_completions" in endpoint_keys
assert "embeddings" in endpoint_keys
assert "responses" in endpoint_keys
# Verify some expected providers exist
provider_slugs = {p["slug"] for p in data["providers"]}
assert "openai" in provider_slugs
def test_watsonx_provider_fields():
"""Test that Watsonx provider has all required credential fields including multiple auth options."""
app = FastAPI()