From 003004fca823129eda44f4b2b41fde405826e19d Mon Sep 17 00:00:00 2001 From: octo-patch <266937838+octo-patch@users.noreply.github.com> Date: Thu, 10 Sep 2026 12:24:40 +0800 Subject: [PATCH] fix(minimax): reuse shared async HTTP client --- .../minimax/voice_clone/transformation.py | 2 +- litellm/voice_clone/main.py | 44 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/litellm/llms/minimax/voice_clone/transformation.py b/litellm/llms/minimax/voice_clone/transformation.py index 52967e951b1..d803afc3fc2 100644 --- a/litellm/llms/minimax/voice_clone/transformation.py +++ b/litellm/llms/minimax/voice_clone/transformation.py @@ -35,7 +35,7 @@ class VoiceCloneResponse(TypedDict): class MinimaxVoiceCloneError(BaseLLMException): """Error raised when MiniMax rejects an upload or clone request.""" - def __init__(self, message: str, status_code: int = 0, headers: Mapping[str, str] | None = None): + def __init__(self, message: str, status_code: int = 0, headers: Mapping[str, str] | None = None) -> None: super().__init__(message=message, status_code=status_code, headers=headers) diff --git a/litellm/voice_clone/main.py b/litellm/voice_clone/main.py index 8adfc28021c..a019f6dc28b 100644 --- a/litellm/voice_clone/main.py +++ b/litellm/voice_clone/main.py @@ -7,11 +7,13 @@ ID can then be passed to MiniMax text-to-speech calls as the voice value. import httpx +from litellm.llms.custom_httpx.http_handler import get_async_httpx_client from litellm.llms.minimax.voice_clone.transformation import ( MinimaxVoiceCloneConfig, VoiceCloneResponse, ) from litellm.types.llms.openai import FileTypes +from litellm.types.utils import LlmProviders def _validate_provider(custom_llm_provider: str | None) -> None: @@ -98,25 +100,23 @@ async def avoice_clone( upload_files, upload_data = config.transform_upload_request(file=file, purpose=purpose) config.transform_clone_request(file_id="pending", voice_id=voice_id, model=model) timeout_value = timeout if timeout is not None else 600.0 - owns_client = client is None - http_client = client or httpx.AsyncClient(timeout=timeout_value) - try: - upload_response = await http_client.post( - config.get_complete_url(api_base=api_base, operation="upload"), - headers=headers, - files=upload_files, - data=upload_data, - timeout=timeout_value, - ) - file_id = config.transform_upload_response(upload_response) - clone_body = config.transform_clone_request(file_id=file_id, voice_id=voice_id, model=model) - clone_response = await http_client.post( - config.get_complete_url(api_base=api_base, operation="clone"), - headers={**headers, "Content-Type": "application/json"}, - json=clone_body, - timeout=timeout_value, - ) - return config.transform_clone_response(clone_response, file_id=file_id, model=model) - finally: - if owns_client: - await http_client.aclose() + http_client = client or get_async_httpx_client( + llm_provider=LlmProviders.MINIMAX, + params={"timeout": timeout_value}, + ) + upload_response = await http_client.post( + config.get_complete_url(api_base=api_base, operation="upload"), + headers=headers, + files=upload_files, + data=upload_data, + timeout=timeout_value, + ) + file_id = config.transform_upload_response(upload_response) + clone_body = config.transform_clone_request(file_id=file_id, voice_id=voice_id, model=model) + clone_response = await http_client.post( + config.get_complete_url(api_base=api_base, operation="clone"), + headers={**headers, "Content-Type": "application/json"}, + json=clone_body, + timeout=timeout_value, + ) + return config.transform_clone_response(clone_response, file_id=file_id, model=model)