mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-14 05:06:33 +00:00
Merge pull request #22246 from BerriAI/revert-22238-litellm_supported_endpoints
Revert "[Feature] Add /public/supported_endpoints endpoint"
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user