mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
fix(openai): forward client headers on the text completion path (#30103)
* fix(openai): forward client headers on the text completion path litellm.completion() merges caller headers with extra_headers, but the text-completion-openai branch never passed the merged dict to openai_text_completions.completion(), and the handler only used its headers argument for logging. Pass the merged headers through the call site and set them as extra_headers on the outgoing request, mirroring the chat completion handler, so x-* client headers forwarded by the proxy reach the provider on /v1/completions. Fixes #27410. * Drop redundant extra_headers assignment and fix test module collision completion() merges extra_headers into headers before the text-completion-openai branch, and the handler now sets the merged headers as extra_headers on the request, so the branch-local optional_params["extra_headers"] assignment was a dead duplicate. Removing it keeps the assignment in one place while both entry paths (litellm.text_completion and direct handler callers) still forward headers; a new regression test pins the extra_headers kwarg path. Also rename the test module to test_completion_handler.py since its basename collided with tests/test_litellm/llms/bedrock/batches/ test_handler.py and broke pytest collection.
This commit is contained in:
parent
ca9284f8da
commit
2e579f543c
3 changed files with 96 additions and 3 deletions
|
|
@ -49,6 +49,8 @@ class OpenAITextCompletion(BaseLLM):
|
|||
headers: Optional[dict] = None,
|
||||
):
|
||||
try:
|
||||
if headers:
|
||||
optional_params = {**optional_params, "extra_headers": headers}
|
||||
if headers is None:
|
||||
headers = self.validate_environment(api_key=api_key)
|
||||
if model is None or messages is None:
|
||||
|
|
|
|||
|
|
@ -2135,9 +2135,6 @@ def completion( # type: ignore # noqa: PLR0915
|
|||
|
||||
headers = headers or litellm.headers
|
||||
|
||||
if extra_headers is not None:
|
||||
optional_params["extra_headers"] = extra_headers
|
||||
|
||||
## LOAD CONFIG - if set
|
||||
config = litellm.OpenAITextCompletionConfig.get_config()
|
||||
for k, v in config.items():
|
||||
|
|
@ -2163,6 +2160,7 @@ def completion( # type: ignore # noqa: PLR0915
|
|||
_response = openai_text_completions.completion(
|
||||
model=model,
|
||||
messages=messages,
|
||||
headers=headers,
|
||||
model_response=model_response,
|
||||
print_verbose=print_verbose,
|
||||
api_key=api_key,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
"""
|
||||
Tests that client headers are forwarded to the provider on the OpenAI
|
||||
text completion path.
|
||||
|
||||
Regression tests for https://github.com/BerriAI/litellm/issues/27410
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
import respx
|
||||
from httpx import Response
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../../../.."))
|
||||
|
||||
import litellm
|
||||
from litellm import atext_completion, text_completion
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_env(monkeypatch):
|
||||
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-fake-key")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_completions_endpoint():
|
||||
return respx.post("https://api.openai.com/v1/completions").mock(
|
||||
return_value=Response(
|
||||
200,
|
||||
json={
|
||||
"id": "cmpl-test123",
|
||||
"object": "text_completion",
|
||||
"created": 1677652288,
|
||||
"model": "gpt-3.5-turbo-instruct",
|
||||
"choices": [
|
||||
{
|
||||
"text": "hi",
|
||||
"index": 0,
|
||||
"logprobs": None,
|
||||
"finish_reason": "stop",
|
||||
}
|
||||
],
|
||||
"usage": {
|
||||
"prompt_tokens": 1,
|
||||
"completion_tokens": 1,
|
||||
"total_tokens": 2,
|
||||
},
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_completion_forwards_client_headers_to_provider(mock_completions_endpoint):
|
||||
text_completion(
|
||||
model="gpt-3.5-turbo-instruct",
|
||||
prompt="hello",
|
||||
max_tokens=5,
|
||||
headers={"x-mycorp-llmcall-id": "abc-123"},
|
||||
)
|
||||
|
||||
request_headers = mock_completions_endpoint.calls.last.request.headers
|
||||
assert request_headers["x-mycorp-llmcall-id"] == "abc-123"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_completion_forwards_extra_headers_to_provider(mock_completions_endpoint):
|
||||
text_completion(
|
||||
model="gpt-3.5-turbo-instruct",
|
||||
prompt="hello",
|
||||
max_tokens=5,
|
||||
extra_headers={"x-mycorp-llmcall-id": "abc-123"},
|
||||
)
|
||||
|
||||
request_headers = mock_completions_endpoint.calls.last.request.headers
|
||||
assert request_headers["x-mycorp-llmcall-id"] == "abc-123"
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_acompletion_forwards_client_headers_to_provider(
|
||||
mock_completions_endpoint, monkeypatch
|
||||
):
|
||||
monkeypatch.setattr(litellm, "disable_aiohttp_transport", True)
|
||||
await atext_completion(
|
||||
model="gpt-3.5-turbo-instruct",
|
||||
prompt="hello",
|
||||
max_tokens=5,
|
||||
headers={"x-mycorp-llmcall-id": "abc-123"},
|
||||
)
|
||||
|
||||
request_headers = mock_completions_endpoint.calls.last.request.headers
|
||||
assert request_headers["x-mycorp-llmcall-id"] == "abc-123"
|
||||
Loading…
Add table
Reference in a new issue