From 9b440caac2d39e0d5b416196cd6b50e4259d8cba Mon Sep 17 00:00:00 2001 From: Alexsander Hamir Date: Tue, 16 Dec 2025 12:28:33 -0800 Subject: [PATCH] Lazy load ImageEditRequestUtils in images/main.py to avoid heavy import (#18074) - Remove direct import of ImageEditRequestUtils from images.utils - Add __getattr__ handler to lazy load ImageEditRequestUtils when accessed - Create _get_ImageEditRequestUtils() helper function with caching - Use importlib instead of sys to avoid importing sys inside functions - Update image_edit() to use helper function for accessing ImageEditRequestUtils - Add TYPE_CHECKING import for proper type hints This defers the heavy import from images.utils until ImageEditRequestUtils is actually needed, improving import time when from .images.main import * is executed. --- litellm/images/main.py | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/litellm/images/main.py b/litellm/images/main.py index ca2d4e0b911..7ab496db0b7 100644 --- a/litellm/images/main.py +++ b/litellm/images/main.py @@ -1,7 +1,11 @@ import asyncio import contextvars +import importlib from functools import partial -from typing import Any, Coroutine, Dict, List, Literal, Optional, Union, cast, overload +from typing import TYPE_CHECKING, Any, Coroutine, Dict, List, Literal, Optional, Union, cast, overload + +if TYPE_CHECKING: + from litellm.images.utils import ImageEditRequestUtils import httpx @@ -50,7 +54,20 @@ from litellm.utils import ( get_optional_params_image_gen, ) -from .utils import ImageEditRequestUtils +# Cache for ImageEditRequestUtils to avoid repeated __getattr__ calls +_ImageEditRequestUtils_cache: Optional["ImageEditRequestUtils"] = None + + +def _get_ImageEditRequestUtils() -> "ImageEditRequestUtils": + """Get ImageEditRequestUtils, loading it lazily if needed.""" + global _ImageEditRequestUtils_cache + if _ImageEditRequestUtils_cache is None: + # Access via module to trigger __getattr__ if not cached + module = importlib.import_module(__name__) + _ImageEditRequestUtils_cache = module.ImageEditRequestUtils + assert _ImageEditRequestUtils_cache is not None # Type narrowing for type checker + return _ImageEditRequestUtils_cache + ##### Image Generation ####################### @@ -769,12 +786,12 @@ def image_edit( local_vars.update(kwargs) # Get ImageEditOptionalRequestParams with only valid parameters image_edit_optional_params: ImageEditOptionalRequestParams = ( - ImageEditRequestUtils.get_requested_image_edit_optional_param(local_vars) + _get_ImageEditRequestUtils().get_requested_image_edit_optional_param(local_vars) ) # Get optional parameters for the responses API image_edit_request_params: Dict = ( - ImageEditRequestUtils.get_optional_params_image_edit( + _get_ImageEditRequestUtils().get_optional_params_image_edit( model=model, image_edit_provider_config=image_edit_provider_config, image_edit_optional_params=image_edit_optional_params, @@ -898,3 +915,15 @@ async def aimage_edit( completion_kwargs=local_vars, extra_kwargs=kwargs, ) + + +def __getattr__(name: str) -> Any: + """Lazy import handler for images.main module""" + if name == "ImageEditRequestUtils": + # Lazy load ImageEditRequestUtils to avoid heavy import from images.utils at module load time + from .utils import ImageEditRequestUtils as _ImageEditRequestUtils + # Cache it in the module's __dict__ for subsequent accesses + module = importlib.import_module(__name__) + module.__dict__["ImageEditRequestUtils"] = _ImageEditRequestUtils + return _ImageEditRequestUtils + raise AttributeError(f"module {__name__!r} has no attribute {name!r}")