[Refactor] litellm/init.py: lazy-load AmazonConverseConfig (#18069)

- Add LLM_CONFIG_NAMES tuple and _lazy_import_llm_configs function in _lazy_imports.py
- Remove direct import of AmazonConverseConfig from __init__.py
- Add lazy loading handler in __getattr__ to dispatch LLM config imports
- Add type stub for AmazonConverseConfig in TYPE_CHECKING block
- Add test_llm_config_lazy_imports test to verify lazy loading works
- Follows same pattern as DOTPROMPT_NAMES for consistency
This commit is contained in:
Alexsander Hamir
2025-12-16 10:48:11 -08:00
committed by GitHub
parent 8be2eac816
commit 014c74fd06
4 changed files with 64 additions and 2 deletions
+10 -1
View File
@@ -1055,7 +1055,6 @@ from .utils import client
from .llms.bytez.chat.transformation import BytezChatConfig
from .llms.custom_llm import CustomLLM
from .llms.bedrock.chat.converse_transformation import AmazonConverseConfig
from .llms.openai_like.chat.handler import OpenAILikeChatConfig
from .llms.aiohttp_openai.chat.transformation import AiohttpOpenAIChatConfig
from .llms.galadriel.chat.transformation import GaladrielChatConfig
@@ -1551,6 +1550,9 @@ if TYPE_CHECKING:
module_level_aclient: AsyncHTTPHandler
module_level_client: HTTPHandler
# LLM config classes - lazy loaded only
AmazonConverseConfig: Type[Any]
def __getattr__(name: str) -> Any:
"""Lazy import handler"""
@@ -1565,6 +1567,7 @@ def __getattr__(name: str) -> Any:
CACHING_NAMES,
HTTP_HANDLER_NAMES,
DOTPROMPT_NAMES,
LLM_CONFIG_NAMES,
)
# Lazy load cost_calculator functions
@@ -1619,6 +1622,12 @@ def __getattr__(name: str) -> Any:
return _lazy_import_dotprompt(name)
# Lazy load LLM config classes
if name in LLM_CONFIG_NAMES:
from ._lazy_imports import _lazy_import_llm_configs
return _lazy_import_llm_configs(name)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
+21 -1
View File
@@ -154,6 +154,11 @@ DOTPROMPT_NAMES = (
"set_global_prompt_directory",
)
# LLM config classes that support lazy loading via _lazy_import_llm_configs
LLM_CONFIG_NAMES = (
"AmazonConverseConfig",
)
# Lazy import for utils module - imports only the requested item by name.
# Note: PLR0915 (too many statements) is suppressed because the many if statements
# are intentional - each attribute is imported individually only when requested,
@@ -611,4 +616,19 @@ def _lazy_import_dotprompt(name: str) -> Any:
_globals["set_global_prompt_directory"] = _set_global_prompt_directory
return _set_global_prompt_directory
raise AttributeError(f"Dotprompt lazy import: unknown attribute {name!r}")
raise AttributeError(f"Dotprompt lazy import: unknown attribute {name!r}")
def _lazy_import_llm_configs(name: str) -> Any:
"""Lazy import for LLM config classes."""
_globals = _get_litellm_globals()
if name == "AmazonConverseConfig":
from .llms.bedrock.chat.converse_transformation import (
AmazonConverseConfig as _AmazonConverseConfig,
)
_globals["AmazonConverseConfig"] = _AmazonConverseConfig
return _AmazonConverseConfig
raise AttributeError(f"LLM config lazy import: unknown attribute {name!r}")
+14
View File
@@ -8393,3 +8393,17 @@ def should_run_mock_completion(
if mock_response or mock_tool_calls or mock_timeout:
return True
return False
# Re-export encoding from main.py for backward compatibility
# This allows tests to import: from litellm.utils import encoding
# We use a lazy import to avoid loading main.py at utils.py import time
def __getattr__(name: str) -> Any:
"""Lazy import handler for utils module"""
if name == "encoding":
from litellm.main import encoding as _encoding
# Cache it in the module's __dict__ for subsequent accesses
import sys
sys.modules[__name__].__dict__["encoding"] = _encoding
return _encoding
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
+19
View File
@@ -29,6 +29,8 @@ from litellm._lazy_imports import (
_lazy_import_http_handlers,
DOTPROMPT_NAMES,
_lazy_import_dotprompt,
LLM_CONFIG_NAMES,
_lazy_import_llm_configs,
)
@@ -208,3 +210,20 @@ def test_unknown_attribute_raises_error():
with pytest.raises(AttributeError):
_lazy_import_types_utils("unknown")
with pytest.raises(AttributeError):
_lazy_import_llm_configs("unknown")
def test_llm_config_lazy_imports():
"""Test that LLM config classes can be lazy imported."""
for name in LLM_CONFIG_NAMES:
_clear_names_from_globals(LLM_CONFIG_NAMES)
obj = _lazy_import_llm_configs(name)
assert obj is not None
assert name in litellm.__dict__
# Config classes should be classes/types
assert isinstance(obj, type), f"{name} should be a class"
_verify_only_requested_name_imported(name, LLM_CONFIG_NAMES)