mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-06 07:48:06 +00:00
fix(dashscope): keep a full DashScope image endpoint URL as given and type the brand tests
This commit is contained in:
parent
abb6b5f8b3
commit
2a48c69e3e
3 changed files with 49 additions and 3 deletions
|
|
@ -25,6 +25,7 @@ Response format:
|
|||
|
||||
from collections.abc import Iterable, Mapping
|
||||
from typing import TYPE_CHECKING, Any, Final
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import httpx
|
||||
from pydantic import ConfigDict, TypeAdapter
|
||||
|
|
@ -42,6 +43,7 @@ from litellm.types.utils import ImageObject, ImageResponse
|
|||
from ..common_utils import (
|
||||
DASHSCOPE_CHAT_COMPATIBLE_PATH,
|
||||
DASHSCOPE_IMAGE_PATH,
|
||||
DASHSCOPE_NATIVE_V1_PATH,
|
||||
resolve_dashscope_endpoints,
|
||||
)
|
||||
|
||||
|
|
@ -70,6 +72,10 @@ OPENAI_TO_DASHSCOPE_SIZE: Final[dict] = {
|
|||
}
|
||||
|
||||
|
||||
def _is_native_endpoint_url(api_base: str) -> bool:
|
||||
return urlparse(api_base).path.rstrip("/").startswith(f"{DASHSCOPE_NATIVE_V1_PATH}/")
|
||||
|
||||
|
||||
class DashScopeImageGenerationConfig(BaseImageGenerationConfig):
|
||||
"""
|
||||
Configuration for DashScope image generation (qwen-image-2.0, qwen-image-2.0-pro,
|
||||
|
|
@ -128,6 +134,8 @@ class DashScopeImageGenerationConfig(BaseImageGenerationConfig):
|
|||
configured_api_base: Final = api_base or self._configured_chat_api_base()
|
||||
if configured_api_base and configured_api_base.rstrip("/").endswith(DASHSCOPE_CHAT_COMPATIBLE_PATH):
|
||||
return image_env_api_base or self._default_image_api_base()
|
||||
if configured_api_base and _is_native_endpoint_url(configured_api_base):
|
||||
return configured_api_base
|
||||
endpoints: Final = resolve_dashscope_endpoints(configured_api_base)
|
||||
if endpoints is not None:
|
||||
return (None if api_base else image_env_api_base) or f"{endpoints.origin}{DASHSCOPE_IMAGE_PATH}"
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ import json
|
|||
import math
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
from typing import Final, Literal
|
||||
|
||||
import pytest
|
||||
from typing_extensions import ReadOnly, TypedDict
|
||||
|
||||
import litellm
|
||||
from litellm import completion, get_llm_provider
|
||||
|
|
@ -54,6 +55,23 @@ DASHSCOPE_FAMILY_ENV_VARS = [
|
|||
"QWEN_AI_PLATFORM_API_BASE_IMAGE",
|
||||
]
|
||||
|
||||
|
||||
|
||||
class BrandCase(TypedDict):
|
||||
provider: ReadOnly[str]
|
||||
display_name: ReadOnly[str]
|
||||
enum: ReadOnly[LlmProviders]
|
||||
key_env: ReadOnly[str]
|
||||
base_env: ReadOnly[str]
|
||||
default_base: ReadOnly[str]
|
||||
default_rerank_base: ReadOnly[str]
|
||||
default_image_base: ReadOnly[str]
|
||||
chat_config: ReadOnly[type[DashScopeChatConfig]]
|
||||
embedding_config: ReadOnly[type[DashScopeEmbeddingConfig]]
|
||||
rerank_config: ReadOnly[type[DashScopeRerankConfig]]
|
||||
image_config: ReadOnly[type[DashScopeImageGenerationConfig]]
|
||||
|
||||
|
||||
BRAND_CASES = [
|
||||
pytest.param(
|
||||
{
|
||||
|
|
@ -214,7 +232,9 @@ class TestQwenBrandDefaultUrls:
|
|||
|
||||
@pytest.mark.parametrize("brand", BRAND_CASES)
|
||||
@pytest.mark.parametrize(("config_key", "route"), [("chat_config", "chat/completions"), ("embedding_config", "embeddings")])
|
||||
def test_openai_routes_derive_from_a_domain_root(self, brand, config_key, route):
|
||||
def test_openai_routes_derive_from_a_domain_root(
|
||||
self, brand: BrandCase, config_key: Literal["chat_config", "embedding_config"], route: str
|
||||
) -> None:
|
||||
url: Final = brand[config_key]().get_complete_url(
|
||||
api_base="https://dashscope-intl.aliyuncs.com",
|
||||
api_key="sk-test",
|
||||
|
|
@ -263,7 +283,7 @@ class TestQwenBrandDefaultUrls:
|
|||
assert url == brand["default_image_base"]
|
||||
|
||||
@pytest.mark.parametrize("brand", BRAND_CASES)
|
||||
def test_image_generation_uses_its_own_configured_base(self, monkeypatch, brand):
|
||||
def test_image_generation_uses_its_own_configured_base(self, monkeypatch: pytest.MonkeyPatch, brand: BrandCase) -> None:
|
||||
monkeypatch.setenv("DASHSCOPE_API_BASE", "https://legacy.example.com/images")
|
||||
monkeypatch.setenv(brand["base_env"], "https://gateway.example.com/qwen/images")
|
||||
url: Final = brand["image_config"]().get_complete_url(
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ class TestDashScopeImageGenerationConfig:
|
|||
"https://llm-abc123.cn-beijing.maas.aliyuncs.com/apps/anthropic",
|
||||
"https://llm-abc123.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation",
|
||||
),
|
||||
(
|
||||
"https://dashscope-us.aliyuncs.com/api/v1/",
|
||||
"https://dashscope-us.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_get_complete_url_derives_from_the_domain(
|
||||
|
|
@ -105,6 +109,20 @@ class TestDashScopeImageGenerationConfig:
|
|||
url: Final = self.cfg.get_complete_url(api_base, None, "qwen-image-3.0", {}, {})
|
||||
assert url == expected
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"endpoint_url",
|
||||
[
|
||||
"https://dashscope.aliyuncs.com/api/v1/services/aigc/image-generation/generation",
|
||||
"https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis",
|
||||
],
|
||||
)
|
||||
def test_get_complete_url_keeps_a_full_dashscope_endpoint_url(
|
||||
self, monkeypatch: pytest.MonkeyPatch, endpoint_url: str
|
||||
):
|
||||
monkeypatch.setenv("DASHSCOPE_API_BASE_IMAGE", "https://images.example.com/generate")
|
||||
url: Final = self.cfg.get_complete_url(endpoint_url, None, "qwen-image-3.0", {}, {})
|
||||
assert url == endpoint_url
|
||||
|
||||
def test_validate_environment_sets_auth_header(self):
|
||||
headers = self.cfg.validate_environment(
|
||||
headers={},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue