mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(jina_ai): resolve the documented JINA_API_KEY as a fallback (#35992)
The Jina key fallback chain read JINA_AI_API_KEY three times in a row before falling through to JINA_AI_TOKEN, so two of the four slots were dead. Jina's own documentation publishes JINA_API_KEY, and litellm's rerank validate_environment already tells users to set that name, but nothing ever read it: a user who set only JINA_API_KEY got no key resolved and Jina answered AUTH_MISSING_API_KEY. Replace one of the repeats with JINA_API_KEY and drop the other. JINA_AI_API_KEY stays first so no install that resolves a key today changes which key it picks.
This commit is contained in:
parent
4562b539d8
commit
309e96c27b
2 changed files with 58 additions and 13 deletions
|
|
@ -82,10 +82,7 @@ class JinaAIEmbeddingConfig(BaseEmbeddingConfig):
|
|||
"""
|
||||
api_base = api_base or get_secret_str("JINA_AI_API_BASE") or "https://api.jina.ai/v1"
|
||||
dynamic_api_key: Final = api_key or (
|
||||
get_secret_str("JINA_AI_API_KEY")
|
||||
or get_secret_str("JINA_AI_API_KEY")
|
||||
or get_secret_str("JINA_AI_API_KEY")
|
||||
or get_secret_str("JINA_AI_TOKEN")
|
||||
get_secret_str("JINA_AI_API_KEY") or get_secret_str("JINA_API_KEY") or get_secret_str("JINA_AI_TOKEN")
|
||||
)
|
||||
return LlmProviders.JINA_AI.value, api_base, dynamic_api_key
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,20 @@ import os
|
|||
import sys
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath("../../../../../..")
|
||||
) # Adds the parent directory to the system path
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, os.path.abspath("../../../../../..")) # Adds the parent directory to the system path
|
||||
|
||||
from litellm.llms.jina_ai.embedding.transformation import JinaAIEmbeddingConfig
|
||||
|
||||
JINA_KEY_ENV_NAMES = ("JINA_AI_API_KEY", "JINA_API_KEY", "JINA_AI_TOKEN")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def no_jina_env(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
for name in JINA_KEY_ENV_NAMES:
|
||||
monkeypatch.delenv(name, raising=False)
|
||||
|
||||
|
||||
class TestJinaAIEmbeddingTransform:
|
||||
def setup_method(self):
|
||||
|
|
@ -54,9 +62,7 @@ class TestJinaAIEmbeddingTransform:
|
|||
headers={},
|
||||
)
|
||||
expected_input = [
|
||||
{
|
||||
"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
|
||||
}
|
||||
{"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="}
|
||||
]
|
||||
expected_result = {
|
||||
"model": self.model,
|
||||
|
|
@ -64,6 +70,50 @@ class TestJinaAIEmbeddingTransform:
|
|||
}
|
||||
assert result == expected_result
|
||||
|
||||
@pytest.mark.parametrize("env_name", JINA_KEY_ENV_NAMES)
|
||||
def test_every_accepted_env_name_resolves_a_key(
|
||||
self,
|
||||
env_name: str,
|
||||
no_jina_env: None,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
"""Each accepted spelling must be reachable on its own, not shadowed by a repeated read of another name."""
|
||||
sentinel = f"resolved-via-{env_name.lower()}"
|
||||
monkeypatch.setenv(env_name, sentinel)
|
||||
|
||||
_, _, dynamic_api_key = self.config._get_openai_compatible_provider_info(api_base=None, api_key=None)
|
||||
|
||||
assert dynamic_api_key == sentinel
|
||||
|
||||
def test_env_name_precedence_is_stable(
|
||||
self,
|
||||
no_jina_env: None,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
"""Earlier names in the chain win, so adding later fallbacks never re-points an already working install."""
|
||||
for name in JINA_KEY_ENV_NAMES:
|
||||
monkeypatch.setenv(name, f"resolved-via-{name.lower()}")
|
||||
|
||||
for expected_name in JINA_KEY_ENV_NAMES:
|
||||
_, _, dynamic_api_key = self.config._get_openai_compatible_provider_info(api_base=None, api_key=None)
|
||||
assert dynamic_api_key == f"resolved-via-{expected_name.lower()}"
|
||||
monkeypatch.delenv(expected_name)
|
||||
|
||||
def test_explicit_api_key_beats_every_env_name(
|
||||
self,
|
||||
no_jina_env: None,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
):
|
||||
"""An api_key passed by the caller short-circuits the whole environment chain."""
|
||||
for name in JINA_KEY_ENV_NAMES:
|
||||
monkeypatch.setenv(name, f"resolved-via-{name.lower()}")
|
||||
|
||||
_, _, dynamic_api_key = self.config._get_openai_compatible_provider_info(
|
||||
api_base=None, api_key="passed-in-by-caller"
|
||||
)
|
||||
|
||||
assert dynamic_api_key == "passed-in-by-caller"
|
||||
|
||||
def test_transform_embedding_request_mixed_input(self):
|
||||
"""Test transformation of a mixed text and image embedding request"""
|
||||
# a fake base64 string for testing purposes
|
||||
|
|
@ -77,9 +127,7 @@ class TestJinaAIEmbeddingTransform:
|
|||
)
|
||||
expected_input = [
|
||||
{"text": "hello world"},
|
||||
{
|
||||
"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
|
||||
},
|
||||
{"image": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="},
|
||||
]
|
||||
expected_result = {
|
||||
"model": self.model,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue