mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-10 08:28:25 +00:00
fix(openai): read OPENAI_API_KEY from the env before raising for a missing key, as SDK 2 did
An Azure v1 deployment keyed only through OPENAI_API_KEY, and a Secrets Manager read that comes back empty while the env holds the key, both went from 200 to a local 401 because the helper raised before the SDK could read the env. Responses usage expectations in the integration suite now include cache_write_tokens.
This commit is contained in:
parent
10647ebfcb
commit
f9c87d4839
6 changed files with 42 additions and 4 deletions
|
|
@ -163,9 +163,10 @@ class OpenAISdkKeyParams(TypedDict, total=False):
|
|||
def openai_sdk_key_params(api_key: str | None) -> OpenAISdkKeyParams:
|
||||
if not _SDK_READS_ADMIN_KEY_ENV:
|
||||
return {"api_key": api_key}
|
||||
if not api_key:
|
||||
sdk_api_key: Final = os.environ.get("OPENAI_API_KEY") if api_key is None else api_key
|
||||
if not sdk_api_key:
|
||||
raise openai.OpenAIError(_MISSING_OPENAI_API_KEY_MESSAGE)
|
||||
return {"api_key": api_key, "admin_api_key": api_key}
|
||||
return {"api_key": sdk_api_key, "admin_api_key": sdk_api_key}
|
||||
|
||||
|
||||
_DECODED_JSON: Final = TypeAdapter(object)
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ def assert_compacted(compacted: CompactedResponse, model: str, text: str) -> Non
|
|||
"encrypted_content": COMPACT_STATE,
|
||||
}
|
||||
],
|
||||
"usage": dict(COMPACT_USAGE),
|
||||
"usage": {**COMPACT_USAGE, "input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0}},
|
||||
}, compacted.model_dump_json()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ def test_sdk_compact_reaches_the_compact_endpoint_with_its_full_body(gateway: Ga
|
|||
"output": [output_item],
|
||||
"usage": {
|
||||
"input_tokens": 7,
|
||||
"input_tokens_details": {"cached_tokens": 0},
|
||||
"input_tokens_details": {"cache_write_tokens": 0, "cached_tokens": 0},
|
||||
"output_tokens": 3,
|
||||
"output_tokens_details": {"reasoning_tokens": 0},
|
||||
"total_tokens": 10,
|
||||
|
|
|
|||
|
|
@ -577,6 +577,7 @@ GEMINI_3_5_FLASH_TEST_CASE: Final = TranslationTestCase(
|
|||
"image_tokens": None,
|
||||
"text_tokens": 10,
|
||||
"video_tokens": None,
|
||||
"cache_write_tokens": 0,
|
||||
},
|
||||
"output_tokens": 127,
|
||||
"output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 125, "text_tokens": 2},
|
||||
|
|
|
|||
|
|
@ -472,6 +472,7 @@ GEMINI_3_5_FLASH_TEST_CASE: Final = TranslationTestCase(
|
|||
"image_tokens": None,
|
||||
"text_tokens": 9,
|
||||
"video_tokens": None,
|
||||
"cache_write_tokens": 0,
|
||||
},
|
||||
"output_tokens": 86,
|
||||
"output_tokens_details": {"audio_tokens": None, "reasoning_tokens": 84, "text_tokens": 2},
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from unittest.mock import ANY, MagicMock, patch
|
|||
|
||||
import httpx
|
||||
import pytest
|
||||
import respx
|
||||
from openai import AsyncAzureOpenAI
|
||||
|
||||
import litellm
|
||||
|
|
@ -2652,3 +2653,37 @@ def test_azure_region_lookup_sends_the_key_and_bearer_headers(monkeypatch: pytes
|
|||
params: Final = LiteLLM_Params(model="azure/gpt-region", api_key="azure-key", api_base=api_base)
|
||||
|
||||
assert get_model_region(litellm_params=params, mode="chat") == "eastus"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_async", [False, True])
|
||||
@pytest.mark.asyncio
|
||||
async def test_azure_v1_deployment_keyed_only_by_the_openai_api_key_env_sends_that_key(
|
||||
monkeypatch: pytest.MonkeyPatch, respx_mock: respx.MockRouter, is_async: bool
|
||||
) -> None:
|
||||
for name in ("AZURE_API_KEY", "AZURE_OPENAI_API_KEY", "AZURE_AD_TOKEN", "AZURE_OPENAI_AD_TOKEN", "AZURE_CLIENT_ID"):
|
||||
monkeypatch.delenv(name, raising=False)
|
||||
monkeypatch.setenv("OPENAI_API_KEY", "azure-key-in-openai-env")
|
||||
monkeypatch.setenv("OPENAI_ADMIN_KEY", "sk-admin-key-for-org-apis")
|
||||
monkeypatch.setenv("DISABLE_AIOHTTP_TRANSPORT", "True")
|
||||
api_base: Final = f"https://envkey-{is_async}.openai.azure.com"
|
||||
route: Final = respx_mock.post(f"{api_base}/openai/v1/chat/completions").respond(
|
||||
200,
|
||||
json={
|
||||
"id": "chatcmpl-envkey",
|
||||
"object": "chat.completion",
|
||||
"created": 0,
|
||||
"model": "gpt-4o-mini",
|
||||
"choices": [{"index": 0, "finish_reason": "stop", "message": {"role": "assistant", "content": "hi"}}],
|
||||
},
|
||||
)
|
||||
request: Final = {
|
||||
"model": "azure/gpt-4o-mini",
|
||||
"messages": [{"role": "user", "content": "hi"}],
|
||||
"api_base": api_base,
|
||||
"api_version": "v1",
|
||||
}
|
||||
|
||||
response: Final = await litellm.acompletion(**request) if is_async else litellm.completion(**request)
|
||||
|
||||
assert response.choices[0].message.content == "hi"
|
||||
assert route.calls.last.request.headers["authorization"] == "Bearer azure-key-in-openai-env"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue