o
    ưiB                     @   s  U d Z ddlZddlZddlmZmZmZmZ ddlm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z" de#fddZ$de#fd	d
Z%da&ee e'd< defddZ(da)ee e'd< defddZ*da+ee e'd< defddZ,da-ee#e.ee.gef f  e'd< de#e.ee.gef f fddZ/de.de#e.e0e.e.f f de.defddZ1de.defddZ2de.defddZ3de.defd d!Z4de.defd"d#Z5de.defd$d%Z6de.defd&d'Z7de.defd(d)Z8de.defd*d+Z9de.defd,d-Z:de.defd.d/Z;de.defd0d1Z<de.defd2d3Z=de.defd4d5Z>de.defd6d7Z?dS )8a  
Lazy Import System

This module implements lazy loading for LiteLLM attributes. Instead of importing
everything when the module loads, we only import things when they're actually used.

How it works:
1. When someone accesses `litellm.some_attribute`, Python calls __getattr__ in __init__.py
2. __getattr__ looks up the attribute name in a registry
3. The registry points to a handler function (like _lazy_import_utils)
4. The handler function imports the module and returns the attribute
5. The result is cached so we don't import it again

This makes importing litellm much faster because we don't load heavy dependencies
until they're actually needed.
    N)AnyOptionalcastCallable   )COST_CALCULATOR_NAMESLITELLM_LOGGING_NAMESUTILS_NAMESTOKEN_COUNTER_NAMESLLM_CLIENT_CACHE_NAMESBEDROCK_TYPES_NAMESTYPES_UTILS_NAMESCACHING_NAMESHTTP_HANDLER_NAMESDOTPROMPT_NAMESLLM_CONFIG_NAMESTYPES_NAMESLLM_PROVIDER_LOGIC_NAMESUTILS_MODULE_NAMES_UTILS_IMPORT_MAP_COST_CALCULATOR_IMPORT_MAP_TYPES_UTILS_IMPORT_MAP_TOKEN_COUNTER_IMPORT_MAP_BEDROCK_TYPES_IMPORT_MAP_CACHING_IMPORT_MAP_LITELLM_LOGGING_IMPORT_MAP_DOTPROMPT_IMPORT_MAP_TYPES_IMPORT_MAP_LLM_CONFIGS_IMPORT_MAP_LLM_PROVIDER_LOGIC_IMPORT_MAP_UTILS_MODULE_IMPORT_MAPreturnc                   C      t jd jS )z
    Get the globals dictionary of the litellm module.
    
    This is where we cache imported attributes so we don't import them twice.
    When you do `litellm.some_function`, it gets stored in this dictionary.
    litellmsysmodules__dict__ r(   r(   L/home/app/Keep/.python/lib/python3.10/site-packages/litellm/_lazy_imports.py_get_litellm_globals7      r*   c                   C   r"   )z
    Get the globals dictionary of the utils module.
    
    This is where we cache imported attributes so we don't import them twice.
    When you do `litellm.utils.some_function`, it gets stored in this dictionary.
    zlitellm.utilsr$   r(   r(   r(   r)   _get_utils_globalsA   r+   r,   _default_encodingc                  C      t du rddlm}  | a t S )aq  
    Lazily load and cache the default OpenAI encoding.
    
    This avoids importing `litellm.litellm_core_utils.default_encoding` (and thus tiktoken)
    at `litellm` import time. The encoding is cached after the first import.
    
    This is used internally by utils.py functions that need the encoding but shouldn't
    trigger its import during module load.
    Nr   encoding)r-   Z+litellm.litellm_core_utils.default_encodingr0   r/   r(   r(   r)   _get_default_encodingQ   s   r1   _get_modified_max_tokens_funcc                  C   r.   )ah  
    Lazily load and cache the get_modified_max_tokens function.
    
    This avoids importing `litellm.litellm_core_utils.token_counter` at `litellm` import time.
    The function is cached after the first import.
    
    This is used internally by utils.py functions that need the token counter but shouldn't
    trigger its import during module load.
    Nr   )get_modified_max_tokens)r2   (litellm.litellm_core_utils.token_counterr3   )Z!_get_modified_max_tokens_importedr(   r(   r)   _get_modified_max_tokensg      r5   _token_counter_new_funcc                  C   r.   )a}  
    Lazily load and cache the token_counter function (aliased as token_counter_new).
    
    This avoids importing `litellm.litellm_core_utils.token_counter` at `litellm` import time.
    The function is cached after the first import.
    
    This is used internally by utils.py functions that need the token counter but shouldn't
    trigger its import during module load.
    Nr   )token_counter)r7   r4   r8   )Z_token_counter_importedr(   r(   r)   _get_token_counter_new   r6   r9   _LAZY_IMPORT_REGISTRYc                  C   s  t du ri a tD ]} tt | < qtD ]} tt | < qtD ]} tt | < qtD ]} tt | < q#t	D ]} t
t | < q,tD ]} tt | < q5tD ]} tt | < q>tD ]} tt | < qGtD ]} tt | < qPtD ]} tt | < qYtD ]} tt | < qbtD ]} tt | < qktD ]} tt | < qttD ]} tt | < q}t S )aG  
    Build the registry that maps attribute names to their handler functions.
    
    This is called once, the first time someone accesses a lazy-loaded attribute.
    After that, we just look up the handler function in this dictionary.
    
    Returns:
        Dictionary like {"ModelResponse": _lazy_import_utils, ...}
    N)r:   r   _lazy_import_cost_calculatorr   _lazy_import_litellm_loggingr	   _lazy_import_utilsr
   _lazy_import_token_counterr   _lazy_import_llm_client_cacher   _lazy_import_bedrock_typesr   _lazy_import_types_utilsr   _lazy_import_cachingr   _lazy_import_http_handlersr   _lazy_import_dotpromptr   _lazy_import_llm_configsr   _lazy_import_typesr   _lazy_import_llm_provider_logicr   _lazy_import_utils_modulenamer(   r(   r)   _get_lazy_import_registry   s>   













rK   rJ   
import_mapcategoryc                 C   sv   | |vrt | d| t }| |v r||  S ||  \}}|dr+tj|dd}nt|}t||}||| < |S )a  
    Generic function that handles lazy importing for most attributes.
    
    This is the workhorse function - it does the actual importing and caching.
    Most handler functions just call this with their specific import map.
    
    Steps:
    1. Check if the name exists in the import map (if not, raise error)
    2. Check if we've already imported it (if yes, return cached value)
    3. Look up where to find it (module_path and attr_name from the map)
    4. Import the module (Python caches this automatically)
    5. Get the attribute from the module
    6. Cache it in _globals so we don't import again
    7. Return it
    
    Args:
        name: The attribute name someone is trying to access (e.g., "ModelResponse")
        import_map: Dictionary telling us where to find each attribute
                   Format: {"ModelResponse": (".utils", "ModelResponse")}
        category: Just for error messages (e.g., "Utils", "Cost calculator")
    z  lazy import: unknown attribute .r#   package)AttributeErrorr*   
startswith	importlibimport_modulegetattr)rJ   rL   rM   _globalsmodule_path	attr_namemodulevaluer(   r(   r)   _generic_lazy_import   s   


r[   c                 C      t | tdS )zHHandler for utils module attributes (ModelResponse, token_counter, etc.)ZUtils)r[   r   rI   r(   r(   r)   r=        r=   c                 C   r\   )zMHandler for cost calculator functions (completion_cost, cost_per_token, etc.)zCost calculator)r[   r   rI   r(   r(   r)   r;     r]   r;   c                 C   r\   )z#Handler for token counter utilitieszToken counter)r[   r   rI   r(   r(   r)   r>     r]   r>   c                 C   r\   )z Handler for Bedrock type aliaseszBedrock types)r[   r   rI   r(   r(   r)   r@     r]   r@   c                 C   r\   )zLHandler for types from litellm.types.utils (BudgetConfig, ImageObject, etc.)zTypes utils)r[   r   rI   r(   r(   r)   rA   #  r]   rA   c                 C   r\   )z@Handler for caching classes (Cache, DualCache, RedisCache, etc.)ZCaching)r[   r   rI   r(   r(   r)   rB   (  r]   rB   c                 C   r\   )z)Handler for dotprompt integration globalsZ	Dotprompt)r[   r   rI   r(   r(   r)   rD   ,  r]   rD   c                 C   r\   )z.Handler for type classes (GuardrailItem, etc.)ZTypes)r[   r   rI   r(   r(   r)   rF   1  r]   rF   c                 C   r\   )zLHandler for LLM config classes (AnthropicConfig, OpenAILikeChatConfig, etc.)z
LLM config)r[   r   rI   r(   r(   r)   rE   6  r]   rE   c                 C   r\   )z@Handler for litellm_logging module (Logging, modify_integration)zLitellm logging)r[   r   rI   r(   r(   r)   r<   :  r]   r<   c                 C   r\   )zAHandler for LLM provider logic functions (get_llm_provider, etc.)zLLM provider logic)r[   r   rI   r(   r(   r)   rG   ?  r]   rG   c                 C   sr   | t vrtd| t }| |v r||  S t |  \}}|dr)tj|dd}nt|}t||}||| < |S )z
    Handler for utils module lazy imports.
    
    This uses a custom implementation because utils module needs to use
    _get_utils_globals() instead of _get_litellm_globals() for caching.
    z,Utils module lazy import: unknown attribute rN   r#   rO   )r    rQ   r,   rR   rS   rT   rU   )rJ   rV   rW   rX   rY   rZ   r(   r(   r)   rH   D  s   


rH   c                 C   sf   t  }| |v r||  S td}t|d}| dkr||d< |S | dkr,| }||d< |S td| )a!  
    Handler for LLM client cache - has special logic for singleton instance.
    
    This one is different because:
    - "LLMClientCache" is the class itself
    - "in_memory_llm_clients_cache" is a singleton instance of that class
    So we need custom logic to handle both cases.
    z#litellm.caching.llm_caching_handlerLLMClientCacheZin_memory_llm_clients_cachez0LLM client cache lazy import: unknown attribute )r*   rS   rT   rU   rQ   )rJ   rV   rY   r^   instancer(   r(   r)   r?   m  s   	

r?   c           	      C   s   t  }| dkr(ddlm} |d}|dd}ttd}|||d}||d< |S | d	krBdd
lm} |d}||d}||d	< |S td| )a]  
    Handler for HTTP clients - has special logic for creating client instances.
    
    This one is different because:
    - These aren't just imports, they're actual client instances that need to be created
    - They need configuration (timeout, etc.) from the module globals
    - They use factory functions instead of direct instantiation
    Zmodule_level_aclientr   )get_async_httpx_clientrequest_timeoutzmodule level aclient)timeoutZclient_aliasZlitellm_module_level_client)Zllm_providerparamsZmodule_level_client)HTTPHandler)rb   z-HTTP handlers lazy import: unknown attribute )r*   Z&litellm.llms.custom_httpx.http_handlerr`   getr   r   rd   rQ   )	rJ   rV   r`   rb   rc   Zprovider_idZasync_clientrd   Zsync_clientr(   r(   r)   rC     s&   	




rC   )@__doc__rS   r%   typingr   r   r   r   Z_lazy_imports_registryr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    dictr*   r,   r-   __annotations__r1   r2   r5   r7   r9   r:   strrK   tupler[   r=   r;   r>   r@   rA   rB   rD   rF   rE   r<   rG   rH   r?   rC   r(   r(   r(   r)   <module>   s<    p 
" *1A)!