mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
fix(speech): use the provider api key get_llm_provider resolves
speech() called get_llm_provider and then dropped its dynamic_api_key everywhere except the logging params, so a TTS deployment whose credential lives in a provider-specific env var fell through to OPENAI_API_KEY on the openai-compatible branch and to AZURE_OPENAI_API_KEY / AZURE_API_KEY on the azure branch, failing with a missing-credentials error naming variables the admin never configured. Fold dynamic_api_key into both branch key chains, right after an explicitly passed api_key, so a provider-scoped key is used while an explicit one stays authoritative.
This commit is contained in:
parent
658f50663d
commit
3ceaf793ac
2 changed files with 76 additions and 1 deletions
|
|
@ -8073,7 +8073,8 @@ def speech(
|
|||
# set API KEY
|
||||
api_key = (
|
||||
api_key
|
||||
or litellm.api_key # for deepinfra/perplexity/anyscale we check in get_llm_provider and pass in the api key from there
|
||||
or dynamic_api_key # for deepinfra/perplexity/anyscale we check in get_llm_provider and pass in the api key from there
|
||||
or litellm.api_key
|
||||
or litellm.openai_key
|
||||
or get_secret("OPENAI_API_KEY")
|
||||
)
|
||||
|
|
@ -8157,6 +8158,7 @@ def speech(
|
|||
|
||||
api_key = (
|
||||
api_key
|
||||
or dynamic_api_key
|
||||
or litellm.api_key
|
||||
or litellm.azure_key
|
||||
or get_secret("AZURE_OPENAI_API_KEY")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import asyncio
|
||||
import base64
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
import contextlib
|
||||
import copy
|
||||
import json
|
||||
|
|
@ -3259,3 +3261,74 @@ def test_stream_chunk_builder_leaves_xai_reported_cost_to_the_calculator(monkeyp
|
|||
assert getattr(response.usage, "cost", None) == pytest.approx(0.42)
|
||||
assert response._hidden_params.get("response_cost") is None
|
||||
assert logging_obj._response_cost_calculator(result=response) == pytest.approx(0.63)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _recording_tts_server():
|
||||
received: Final[list[Mapping[str, str]]] = []
|
||||
|
||||
class _Handler(BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
received.append({key.lower(): value for key, value in self.headers.items()})
|
||||
self.rfile.read(int(self.headers.get("Content-Length") or 0))
|
||||
body = b"ID3\x04\x00\x00\x00fake-mp3-payload"
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "audio/mpeg")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
return
|
||||
|
||||
server: Final = ThreadingHTTPServer(("127.0.0.1", 0), _Handler)
|
||||
thread: Final = threading.Thread(target=server.serve_forever, daemon=True)
|
||||
thread.start()
|
||||
try:
|
||||
yield f"http://127.0.0.1:{server.server_port}", received
|
||||
finally:
|
||||
server.shutdown()
|
||||
server.server_close()
|
||||
thread.join(timeout=5)
|
||||
|
||||
|
||||
def test_speech_openai_compatible_sends_the_provider_scoped_key(monkeypatch: pytest.MonkeyPatch):
|
||||
monkeypatch.setattr(litellm, "api_key", None)
|
||||
monkeypatch.setattr(litellm, "openai_key", None)
|
||||
monkeypatch.setattr(litellm, "api_base", None)
|
||||
monkeypatch.setenv("HOSTED_VLLM_API_KEY", "hosted-vllm-scoped-key")
|
||||
monkeypatch.setenv("OPENAI_API_KEY", "generic-openai-key")
|
||||
|
||||
with _recording_tts_server() as (api_base, received):
|
||||
response: Final = litellm.speech(
|
||||
model="hosted_vllm/tts-1",
|
||||
input="which key goes out",
|
||||
voice="alloy",
|
||||
api_base=api_base,
|
||||
)
|
||||
|
||||
assert response.content == b"ID3\x04\x00\x00\x00fake-mp3-payload"
|
||||
assert len(received) == 1
|
||||
assert received[0]["authorization"] == "Bearer hosted-vllm-scoped-key"
|
||||
|
||||
|
||||
def test_speech_azure_sends_the_provider_scoped_key(monkeypatch: pytest.MonkeyPatch):
|
||||
monkeypatch.setattr(litellm, "api_key", None)
|
||||
monkeypatch.setattr(litellm, "azure_key", None)
|
||||
monkeypatch.setattr(litellm, "api_base", None)
|
||||
monkeypatch.setenv("AZURE_AI_API_KEY", "azure-ai-scoped-key")
|
||||
monkeypatch.setenv("AZURE_OPENAI_API_KEY", "legacy-azure-openai-key")
|
||||
monkeypatch.setenv("AZURE_API_KEY", "legacy-azure-key")
|
||||
|
||||
with _recording_tts_server() as (api_base, received):
|
||||
response: Final = litellm.speech(
|
||||
model="azure_ai/tts-1",
|
||||
input="which key goes out",
|
||||
voice="alloy",
|
||||
api_base=api_base,
|
||||
api_version="2024-05-01-preview",
|
||||
)
|
||||
|
||||
assert response.content == b"ID3\x04\x00\x00\x00fake-mp3-payload"
|
||||
assert len(received) == 1
|
||||
assert received[0]["api-key"] == "azure-ai-scoped-key"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue