Spaces:
Configuration error
Configuration error
import json | |
import os | |
import sys | |
from datetime import datetime | |
from unittest.mock import AsyncMock, Mock, patch, MagicMock | |
from typing import Optional | |
from fastapi import Request | |
import pytest | |
import asyncio | |
sys.path.insert( | |
0, os.path.abspath("../..") | |
) # Adds the parent directory to the system path | |
import litellm | |
from litellm.proxy._types import UserAPIKeyAuth | |
from litellm.types.passthrough_endpoints.pass_through_endpoints import PassthroughStandardLoggingPayload | |
from litellm.integrations.custom_logger import CustomLogger | |
from litellm.proxy.pass_through_endpoints.pass_through_endpoints import pass_through_request | |
class TestCustomLogger(CustomLogger): | |
def __init__(self): | |
self.logged_kwargs: Optional[dict] = None | |
async def async_log_success_event(self, kwargs, response_obj, start_time, end_time): | |
print("in async log success event kwargs", json.dumps(kwargs, indent=4, default=str)) | |
self.logged_kwargs = kwargs | |
async def test_assistants_passthrough_logging(): | |
test_custom_logger = TestCustomLogger() | |
litellm._async_success_callback = [test_custom_logger] | |
TARGET_URL = "https://api.openai.com/v1/assistants" | |
REQUEST_BODY = { | |
"instructions": "You are a personal math tutor. When asked a question, write and run Python code to answer the question.", | |
"name": "Math Tutor", | |
"tools": [{"type": "code_interpreter"}], | |
"model": "gpt-4o" | |
} | |
TARGET_METHOD = "POST" | |
result = await pass_through_request( | |
request=Request( | |
scope={ | |
"type": "http", | |
"method": TARGET_METHOD, | |
"path": "/v1/assistants", | |
"query_string": b"", | |
"headers": [ | |
(b"content-type", b"application/json"), | |
(b"authorization", f"Bearer {os.getenv('OPENAI_API_KEY')}".encode()), | |
(b"openai-beta", b"assistants=v2") | |
] | |
}, | |
), | |
target=TARGET_URL, | |
custom_headers={ | |
"Content-Type": "application/json", | |
"Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}", | |
"OpenAI-Beta": "assistants=v2" | |
}, | |
user_api_key_dict=UserAPIKeyAuth( | |
api_key="test", | |
user_id="test", | |
team_id="test", | |
end_user_id="test", | |
), | |
custom_body=REQUEST_BODY, | |
forward_headers=False, | |
merge_query_params=False, | |
) | |
print("got result", result) | |
print("result status code", result.status_code) | |
print("result content", result.body) | |
await asyncio.sleep(1) | |
assert test_custom_logger.logged_kwargs is not None | |
passthrough_logging_payload: Optional[PassthroughStandardLoggingPayload] = test_custom_logger.logged_kwargs["passthrough_logging_payload"] | |
assert passthrough_logging_payload is not None | |
assert passthrough_logging_payload["url"] == TARGET_URL | |
assert passthrough_logging_payload["request_body"] == REQUEST_BODY | |
# assert that the response body content matches the response body content | |
client_facing_response_body = json.loads(result.body) | |
assert passthrough_logging_payload["response_body"] == client_facing_response_body | |
# assert that the request method is correct | |
assert passthrough_logging_payload["request_method"] == TARGET_METHOD | |
async def test_threads_passthrough_logging(): | |
test_custom_logger = TestCustomLogger() | |
litellm._async_success_callback = [test_custom_logger] | |
TARGET_URL = "https://api.openai.com/v1/threads" | |
REQUEST_BODY = {} | |
TARGET_METHOD = "POST" | |
result = await pass_through_request( | |
request=Request( | |
scope={ | |
"type": "http", | |
"method": TARGET_METHOD, | |
"path": "/v1/threads", | |
"query_string": b"", | |
"headers": [ | |
(b"content-type", b"application/json"), | |
(b"authorization", f"Bearer {os.getenv('OPENAI_API_KEY')}".encode()), | |
(b"openai-beta", b"assistants=v2") | |
] | |
}, | |
), | |
target=TARGET_URL, | |
custom_headers={ | |
"Content-Type": "application/json", | |
"Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}", | |
"OpenAI-Beta": "assistants=v2" | |
}, | |
user_api_key_dict=UserAPIKeyAuth( | |
api_key="test", | |
user_id="test", | |
team_id="test", | |
end_user_id="test", | |
), | |
custom_body=REQUEST_BODY, | |
forward_headers=False, | |
merge_query_params=False, | |
) | |
print("got result", result) | |
print("result status code", result.status_code) | |
print("result content", result.body) | |
await asyncio.sleep(1) | |
assert test_custom_logger.logged_kwargs is not None | |
passthrough_logging_payload = test_custom_logger.logged_kwargs["passthrough_logging_payload"] | |
assert passthrough_logging_payload is not None | |
# Fix for TypedDict access errors | |
assert passthrough_logging_payload.get("url") == TARGET_URL | |
assert passthrough_logging_payload.get("request_body") == REQUEST_BODY | |
# Fix for json.loads error with potential memoryview | |
response_body = result.body | |
client_facing_response_body = json.loads(response_body) | |
assert passthrough_logging_payload.get("response_body") == client_facing_response_body | |
assert passthrough_logging_payload.get("request_method") == TARGET_METHOD | |