forked from phoenix/litellm-mirror
feat(langfuse_endpoints.py): support langfuse pass through endpoints by default
This commit is contained in:
parent
0ce476a7f6
commit
1701c48ad5
3 changed files with 122 additions and 1 deletions
|
@ -233,6 +233,9 @@ from litellm.proxy.utils import (
|
||||||
from litellm.proxy.vertex_ai_endpoints.google_ai_studio_endpoints import (
|
from litellm.proxy.vertex_ai_endpoints.google_ai_studio_endpoints import (
|
||||||
router as gemini_router,
|
router as gemini_router,
|
||||||
)
|
)
|
||||||
|
from litellm.proxy.vertex_ai_endpoints.langfuse_endpoints import (
|
||||||
|
router as langfuse_router,
|
||||||
|
)
|
||||||
from litellm.proxy.vertex_ai_endpoints.vertex_endpoints import router as vertex_router
|
from litellm.proxy.vertex_ai_endpoints.vertex_endpoints import router as vertex_router
|
||||||
from litellm.proxy.vertex_ai_endpoints.vertex_endpoints import set_default_vertex_config
|
from litellm.proxy.vertex_ai_endpoints.vertex_endpoints import set_default_vertex_config
|
||||||
from litellm.router import (
|
from litellm.router import (
|
||||||
|
@ -9738,6 +9741,7 @@ app.include_router(router)
|
||||||
app.include_router(fine_tuning_router)
|
app.include_router(fine_tuning_router)
|
||||||
app.include_router(vertex_router)
|
app.include_router(vertex_router)
|
||||||
app.include_router(gemini_router)
|
app.include_router(gemini_router)
|
||||||
|
app.include_router(langfuse_router)
|
||||||
app.include_router(pass_through_router)
|
app.include_router(pass_through_router)
|
||||||
app.include_router(health_router)
|
app.include_router(health_router)
|
||||||
app.include_router(key_management_router)
|
app.include_router(key_management_router)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
What is this?
|
What is this?
|
||||||
|
|
||||||
Google AI Studio Pass-Through Endpoints
|
Provider-specific Pass-Through Endpoints
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
117
litellm/proxy/vertex_ai_endpoints/langfuse_endpoints.py
Normal file
117
litellm/proxy/vertex_ai_endpoints/langfuse_endpoints.py
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
"""
|
||||||
|
What is this?
|
||||||
|
|
||||||
|
Logging Pass-Through Endpoints
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
1. Create pass-through endpoints for any LITELLM_BASE_URL/langfuse/<endpoint> map to LANGFUSE_BASE_URL/<endpoint>
|
||||||
|
"""
|
||||||
|
|
||||||
|
import ast
|
||||||
|
import asyncio
|
||||||
|
import base64
|
||||||
|
import traceback
|
||||||
|
from base64 import b64encode
|
||||||
|
from datetime import datetime, timedelta, timezone
|
||||||
|
from typing import List, Optional
|
||||||
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
|
import fastapi
|
||||||
|
import httpx
|
||||||
|
from fastapi import (
|
||||||
|
APIRouter,
|
||||||
|
Depends,
|
||||||
|
File,
|
||||||
|
Form,
|
||||||
|
Header,
|
||||||
|
HTTPException,
|
||||||
|
Request,
|
||||||
|
Response,
|
||||||
|
UploadFile,
|
||||||
|
status,
|
||||||
|
)
|
||||||
|
from starlette.datastructures import QueryParams
|
||||||
|
|
||||||
|
import litellm
|
||||||
|
from litellm._logging import verbose_proxy_logger
|
||||||
|
from litellm.batches.main import FileObject
|
||||||
|
from litellm.fine_tuning.main import vertex_fine_tuning_apis_instance
|
||||||
|
from litellm.proxy._types import *
|
||||||
|
from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
|
||||||
|
from litellm.proxy.pass_through_endpoints.pass_through_endpoints import (
|
||||||
|
create_pass_through_route,
|
||||||
|
)
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
default_vertex_config = None
|
||||||
|
|
||||||
|
|
||||||
|
def create_request_copy(request: Request):
|
||||||
|
return {
|
||||||
|
"method": request.method,
|
||||||
|
"url": str(request.url),
|
||||||
|
"headers": dict(request.headers),
|
||||||
|
"cookies": request.cookies,
|
||||||
|
"query_params": dict(request.query_params),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.api_route("/langfuse/{endpoint:path}", methods=["GET", "POST", "PUT", "DELETE"])
|
||||||
|
async def langfuse_proxy_route(
|
||||||
|
endpoint: str,
|
||||||
|
request: Request,
|
||||||
|
fastapi_response: Response,
|
||||||
|
):
|
||||||
|
## CHECK FOR LITELLM API KEY IN THE QUERY PARAMS - ?..key=LITELLM_API_KEY
|
||||||
|
api_key = request.headers.get("Authorization") or ""
|
||||||
|
|
||||||
|
## decrypt base64 hash
|
||||||
|
api_key = api_key.replace("Basic ", "")
|
||||||
|
|
||||||
|
decoded_bytes = base64.b64decode(api_key)
|
||||||
|
decoded_str = decoded_bytes.decode("utf-8")
|
||||||
|
api_key = decoded_str.split(":")[1]
|
||||||
|
|
||||||
|
user_api_key_dict = await user_api_key_auth(
|
||||||
|
request=request, api_key="Bearer {}".format(api_key)
|
||||||
|
)
|
||||||
|
|
||||||
|
base_target_url = os.getenv("LANGFUSE_HOST", "https://cloud.langfuse.com")
|
||||||
|
if not (
|
||||||
|
base_target_url.startswith("http://") or base_target_url.startswith("https://")
|
||||||
|
):
|
||||||
|
# add http:// if unset, assume communicating over private network - e.g. render
|
||||||
|
base_target_url = "http://" + base_target_url
|
||||||
|
|
||||||
|
encoded_endpoint = httpx.URL(endpoint).path
|
||||||
|
|
||||||
|
# Ensure endpoint starts with '/' for proper URL construction
|
||||||
|
if not encoded_endpoint.startswith("/"):
|
||||||
|
encoded_endpoint = "/" + encoded_endpoint
|
||||||
|
|
||||||
|
# Construct the full target URL using httpx
|
||||||
|
base_url = httpx.URL(base_target_url)
|
||||||
|
updated_url = base_url.copy_with(path=encoded_endpoint)
|
||||||
|
|
||||||
|
# Add or update query parameters
|
||||||
|
langfuse_public_key = litellm.utils.get_secret(secret_name="LANGFUSE_PUBLIC_KEY")
|
||||||
|
langfuse_secret_key = litellm.utils.get_secret(secret_name="LANGFUSE_SECRET_KEY")
|
||||||
|
|
||||||
|
langfuse_combined_key = "Basic " + b64encode(
|
||||||
|
f"{langfuse_public_key}:{langfuse_secret_key}".encode("utf-8")
|
||||||
|
).decode("ascii")
|
||||||
|
|
||||||
|
## CREATE PASS-THROUGH
|
||||||
|
endpoint_func = create_pass_through_route(
|
||||||
|
endpoint=endpoint,
|
||||||
|
target=str(updated_url),
|
||||||
|
custom_headers={"Authorization": langfuse_combined_key},
|
||||||
|
) # dynamically construct pass-through endpoint based on incoming path
|
||||||
|
received_value = await endpoint_func(
|
||||||
|
request,
|
||||||
|
fastapi_response,
|
||||||
|
user_api_key_dict,
|
||||||
|
)
|
||||||
|
|
||||||
|
return received_value
|
Loading…
Add table
Add a link
Reference in a new issue