
    g.                         d dl Z d dlZd dlmZmZmZmZmZ d dlm	Z	 d dl
Z
d dl
mZmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ  G d d      Z G d de      Zy)    N)ListLiteralOptionalTupleUnion)HTTPException)ModelResponseRouter)verbose_proxy_logger)	DualCache)CustomLogger)UserAPIKeyAuth)ModelGroupInfo)get_utc_datetimec                   F    e Zd ZdZdeddfdZdedee   fdZ	dede
fd	Zy)
DynamicRateLimiterCachezh
    Thin wrapper on DualCache for this file.

    Track number of active projects calling a model.
    cachereturnNc                      || _         d| _        y )N<   )r   ttl)selfr   s     ]/var/www/openai/venv/lib/python3.12/site-packages/litellm/proxy/hooks/dynamic_rate_limiter.py__init__z DynamicRateLimiterCache.__init__   s    
    modelc                    K   t               }|j                  d      }dj                  ||      }| j                  j	                  |       d {   }d }|t        |      }|S 7 w)N%H-%M{}:{})key)r   strftimeformatr   async_get_cachelen)r   r   dtcurrent_minutekey_name	_responseresponses          r   r#   z'DynamicRateLimiterCache.async_get_cache    se     W->>.%8**444BB	"& 9~H	 Cs   AA'A%A'valuec                 L  K   	 t               }|j                  d      }dj                  ||      }| j                  j	                  ||| j
                         d{    y7 # t        $ r4}t        j                  dj                  t        |                   |d}~ww xY ww)a  
        Add value to set.

        Parameters:
        - model: str, the name of the model group
        - value: str, the team id

        Returns:
        - None

        Raises:
        - Exception, if unable to connect to cache client (if redis caching enabled)
        r   r   )r    r*   r   Nz[litellm.proxy.hooks.dynamic_rate_limiter.py::async_set_cache_sadd(): Exception occured - {})
r   r!   r"   r   async_set_cache_saddr   	Exceptionr   	exceptionstr)r   r   r*   r%   r&   r'   es          r   r,   z,DynamicRateLimiterCache.async_set_cache_sadd*   s     	!#B[[1N~~ne<H**11Etxx 2     	 **mttF
 G	s;   B$AA$ A"A$ !B$"A$ $	B!-/BB!!B$)__name__
__module____qualname____doc__r   r   r/   r   intr#   r   r,    r   r   r   r      sD    i D 3 8C=  D r   r   c                        e Zd ZdefdZdefdZ	 ddedee   de	ee
   ee
   ee
   ee
   ee
   f   fdZd	ed
ededed   deeeeef      f
dZded	ef fdZ xZS )_PROXY_DynamicRateLimitHandlerinternal_usage_cachec                 &    t        |      | _        y )N)r   )r   r9   )r   r9   s     r   r   z'_PROXY_DynamicRateLimitHandler.__init__L   s    $;BV$W!r   
llm_routerc                     || _         y N)r;   )r   r;   s     r   update_variablesz/_PROXY_DynamicRateLimitHandler.update_variablesO   s	    $r   r   priorityr   c                 2  K   	 d}t         j                  |t         j                  vr4t        j                  dj	                  |t         j                               nQ|Ot         j                  ?t        j                  dd      t        j                  d       nt         j                  |   }| j                  j                  |       d{   }| j                  j                  |       d{   \  }}| j                  j                  |      }d}d}	|0|j                  |j                  }|j                  |j                  }	d}
||||z
  }
n||}
d}|	||	|z
  }n|	|	}d}|
"|t        |
|z  |z        }nt        |
|z        }||dk  rd}d}|"|t        ||z  |z        }nt        ||z        }||dk  rd}|||
||fS 7 7 # t        $ r7}t        j                   d	j	                  t#        |                   Y d}~y
d}~ww xY ww)a  
        For a given model, get its available tpm

        Params:
        - model: str, the name of the model in the router model_list
        - priority: Optional[str], the priority for the request.

        Returns
        - Tuple[available_tpm, available_tpm, model_tpm, model_rpm, active_projects]
            - available_tpm: int or null - always 0 or positive.
            - available_tpm: int or null - always 0 or positive.
            - remaining_model_tpm: int or null. If available tpm is int, then this will be too.
            - remaining_model_rpm: int or null. If available rpm is int, then this will be too.
            - active_projects: int or null
           NzRPriority Reservation not set. priority={}, but litellm.priority_reservation is {}.LITELLM_LICENSEzPREMIUM FEATURE: Reserving tpm/rpm by priority is a premium feature. Please add a 'LITELLM_LICENSE' to your .env to enable this.
Get a license: https://docs.litellm.ai/docs/proxy/enterprise.)r   )model_groupr   z[litellm.proxy.hooks.dynamic_rate_limiter.py::check_available_usage: Exception occurred - {})NNNNN)litellmpriority_reservationr   errorr"   osgetenvr9   r#   r;   get_model_group_usageget_model_group_infotpmrpmr5   r-   r.   r/   )r   r   r?   weightactive_projectscurrent_model_tpmcurrent_model_rpmmodel_group_infototal_model_tpmtotal_model_rpmremaining_model_tpmremaining_model_rpmavailable_tpmavailable_rpmr0   s                  r   check_available_usagez4_PROXY_DynamicRateLimitHandler.check_available_usageR   s    (R	0F,,47#?#??$**hoo '">">
 %'*F*F*R99.5=(.. Z %99(CF$($=$=$M$M %N % O oo;;;NN 10 444G  .2O-1O+#''3&6&:&:O#''3&6&:&:O15*/@/L&58I&I# ,&5#15*/@/L&58I&I# ,&5#+/M".".$'(;f(D(V$WM$'(;f(D$EM(]Q-> !+/M".".$'(;f(D(V$WM$'(;f(D$EM(]Q-> !## e Oj  	0 **mttF
 0	0sT   HCG G#G 0G1CG HG G 	H-H
HHHuser_api_key_dictr   data	call_type)
completiontext_completion
embeddingsimage_generation
moderationaudio_transcriptionpass_through_endpointrerankc           
        K   d|v r|j                   j                  dd      }| j                  |d   |       d{   \  }}}}	}
|0|dk(  r+t        dddj	                  |j
                  |||
      i	      |0|dk(  r+t        ddd
j	                  |j
                  ||	|
      i	      ||Bt        j                  | j                  j                  |d   |j                  xs dg             y7 w)z
        - For a model group
        - Check if tpm/rpm available
        - Raise RateLimitError if no tpm/rpm available
        r   r?   Nr   r?   r   i  rF   z:Key={} over available TPM={}. Model TPM={}, Active keys={})status_codedetailz:Key={} over available RPM={}. Model RPM={}, Active keys={}default_key)r   r*   )metadatagetrX   r   r"   api_keyasynciocreate_taskr9   r,   token)r   rY   r   rZ   r[   key_priorityrV   rW   	model_tpm	model_rpmrN   s              r   async_pre_call_hookz2_PROXY_DynamicRateLimitHandler.async_pre_call_hook   sC    . d?*;*D*D*H*HD+L 00w-, 1   PM=)Y (]a-?# #!]!d!d-55)%+	"
 
 *}/A# #!]!d!d-55)%+	"
 
 *m.G##--BB"7m066G-H C  Ms   :C4C2B6C4c                 F  K   	 t        |t              r| j                  j                  |j                  d         }|#J dj                  |j                  d                |j                  j                  dd       }| j                  |d   |       d {   \  }}}}	}
|d   ||||	|
d|j                  d<   |S t        | )  |||	       d {   S 7 ?7 # t        $ r9}t        j                  d
j                  t        |                   |cY d }~S d }~ww xY ww)Nmodel_id)idz'Model info for model with id={} is Noner?   
model_namere   )zx-litellm-model_groupz,x-ratelimit-remaining-litellm-project-tokensz.x-ratelimit-remaining-litellm-project-requestsz"x-ratelimit-remaining-model-tokensz$x-ratelimit-remaining-model-requestsz#x-ratelimit-current-active-projectsadditional_headers)rZ   rY   r)   zclitellm.proxy.hooks.dynamic_rate_limiter.py::async_post_call_success_hook(): Exception occured - {})
isinstancer	   r;   get_model_info_hidden_paramsr"   ri   rj   rX   superasync_post_call_success_hookr-   r   r.   r/   )r   rZ   rY   r)   
model_inforo   rV   rW   rp   rq   rN   r0   	__class__s               r   r|   z;_PROXY_DynamicRateLimitHandler.async_post_call_success_hook   sa    )	(M2!__;;..z: < 
 *<CC++J7* /@.H.H.L.L/ 44(6 5   T}iO 2<L1IHUJW>G@I?N ''(<=  ="3! >   ! 
  	 **u||F
 O	se   D!BC C$C =D!>C CC D!C C 	D%.DDD!DD!r=   )r1   r2   r3   r   r   r
   r>   r/   r   r   r5   rX   r   dictr   r   r-   rr   r|   __classcell__)r~   s   @r   r8   r8   I   s    XY X%6 % 59f0f0$,SMf0	x}hsmXc]HSMQ
f0PB)B B 	B
 	
B 
id"#
BH,,-;, ,r   r8   )rl   rG   typingr   r   r   r   r   fastapir   rD   r	   r
   litellm._loggingr   litellm.caching.cachingr   "litellm.integrations.custom_loggerr   litellm.proxy._typesr   litellm.types.routerr   litellm.utilsr   r   r8   r6   r   r   <module>r      sG   
  	 8 8 !  ) 1 - ; / / *1 1ha\ ar   