
    5jT(                        S SK Jr  S SKrS SKrS SKrS SKJr  S SKJrJ	r	  S SK
Jr  S SKJr  S SKJr  S SKJrJrJr  S S	KJrJrJrJrJrJr  S S
KJr   " S S\\\5      rg)    )annotationsN)Iterable)ceilfloor)
ModuleType)parse_storage_uri)ConfigurationError)SlidingWindowCounterSupportStorageTimestampedSlidingWindow)AnyCallableMemcachedClientPPRcast)get_dependencyc                  |  ^  \ rS rSrSrS/r S/r S       SU 4S jjjr\  SS j5       r	        SS jr
        SS jr\SS	 j5       rSS
 jrSS jrSS jr  S          S!S jjrS"S jrS#S jrS$S jrS%S jr S&         S'S jjr      S(S jrS)S jr          S*S jrSrU =r$ )+MemcachedStorage   zO
Rate limit storage with memcached as backend.

Depends on :pypi:`pymemcache`.
	memcached
pymemcachec                  > [        U5      nU   UR                  (       a  UR                  /U l        OUR                  U l        U R                  S   R
                  U l        [        UR                  SS5      5      U l	        [        UR                  SS5      5      U l
        [        [        [        [        [        [        [         4      [        [           -  /["        4   UR                  SU R$                  5      5      U l        X0l        [+        U R                  5      (       d  [-        SU R                   35      e[.        R0                  " 5       U l        SU R2                  l        [6        TU ]q  XS	9  g)
a  
:param uri: memcached location of the form
 ``memcached://host:port,host:port``,
 ``memcached:///var/tmp/path/to/sock``
:param wrap_exceptions: Whether to wrap storage exceptions in
 :exc:`limits.errors.StorageError` before raising it.
:param options: all remaining keyword arguments are passed
 directly to the constructor of :class:`pymemcache.client.base.PooledClient`
 or :class:`pymemcache.client.hash.HashClient` (if there are more than
 one hosts specified)
:raise ConfigurationError: when :pypi:`pymemcache` is not available
r   libraryzpymemcache.clientcluster_libraryzpymemcache.client.hashclient_getterz5memcached prerequisite not available. please install N)wrap_exceptions)r   pathhosts	locationsdependenciesmodule
dependencystrpopr   r   r   r   r   listtupleintr   
get_clientr   optionsr   r	   	threadinglocallocal_storagestoragesuper__init__)selfurir   r*   storage_uri_options	__class__s        W/root/lseg-credit/backend/venv/lib/python3.13/site-packages/limits/storage/memcached.pyr0   MemcachedStorage.__init__'   s0   $ 04##-223DJ,66DJ++L9@@7;;y2EFG"KK)+CD 
 "j$uS#X"7$s)"CDFVVWKK9
 dll++$G~V  '__.%)">    c                .    U R                   R                  $ N)r#   MemcacheErrorr1   s    r5   base_exceptions MemcachedStorage.base_exceptionsS   s     ,,,r7   c                    [        [        [        U5      S:  a  UR                  " U40 UD65      $ UR                  " U0 UD65      $ )zh
returns a memcached client.

:param module: the memcached module
:param hosts: list of memcached hosts
   )r   r   len
HashClientPooledClient)r1   r"   r   kwargss       r5   r)   MemcachedStorage.get_clientY   sU      u:> !!%262
 	

 ((%:6:
 	
r7   c                    SU;   aH  [         R                  " U5      nSUR                  ;   d"  UR                  (       d  UR	                  S5        U" U0 UD6$ )Nnoreply)inspectgetfullargspecargsvarkwr%   )r1   funcrI   rC   argspecs        r5   call_memcached_func$MemcachedStorage.call_memcached_funcl   sJ     ,,T2G-

9%T$V$$r7   c                   [        U R                  S5      (       a  U R                  R                  (       d  [        [	        U R
                  5      S:  a  U R                  OU R                  5      S   nU(       d  [        SU R                   35      eU R                  " XR
                  40 U R                  D6U R                  l        [        [        U R                  R                  5      $ )zA
lazily creates a memcached client instance using a thread local
r.   r?   r   zUnable to import )hasattrr-   r.   r   r@   r   r   r   r	   r   r*   r   r   )r1   r#   s     r5   r.   MemcachedStorage.storagew   s     **I664;M;M;U;U'(+DJJ!(;$$J (+<T=Q=Q<R)STT)-););JJ**.,,*D& $d&8&8&@&@AAr7   c                L    [        U R                  R                  US5      5      $ )z2
:param key: the key to get the counter value for
0)r(   r.   getr1   keys     r5   rT   MemcachedStorage.get   s      4<<##C-..r7   c                8    U R                   R                  U5      $ )zg
Return multiple counters at once

:param keys: the keys to get the counter values for

:meta private:
)r.   get_many)r1   keyss     r5   rY   MemcachedStorage.get_many   s     ||$$T**r7   c                :    U R                   R                  U5        g)z.
:param key: the key to clear rate limits for
N)r.   deleterU   s     r5   clearMemcachedStorage.clear   s     	C r7   c                   U R                  U R                  R                  XSS9=n b  U$ U R                  U R                  R                  X[	        U5      SS9(       d$  U R                  R                  X5      =(       d    U$ U(       aU  U R                  U R                  R
                  U R                  U5      U[        R                  " 5       -   [	        U5      SS9  U$ )a  
increments the counter for a given rate limit key

:param key: the key to increment
:param expiry: amount in seconds for the key to expire in
 window every hit.
:param amount: the number to increment by
:param set_expiration_key: set the expiration key with the expiration time if needed. If set to False, the key will still expire, but memcached cannot provide the expiration time.
FrF   )expirerF   )rM   r.   incraddr   set_expiration_keytime)r1   rV   expiryamountset_expiration_keyvalues         r5   rc   MemcachedStorage.incr   s    " --!!3 .  E 	
 L++  #tF|U ,  ||((5??%,,((,,S1,#F| % -  Mr7   c                    [        U R                  R                  U R                  U5      5      =(       d    [        R                  " 5       5      $ )z+
:param key: the key to get the expiry for
)floatr.   rT   rf   rg   rU   s     r5   
get_expiryMemcachedStorage.get_expiry   s4    
 T\\%%d&:&:3&?@ODIIKPPr7   c                    US-   $ )z
Return the expiration key for the given counter key.

Memcached doesn't natively return the expiration time or TTL for a given key,
so we implement the expiration time on a separate key.
z/expires rU   s     r5   rf    MemcachedStorage._expiration_key   s     Zr7   c                `     U R                  U R                  R                  S5        g!    g= f)zY
Check if storage is healthy by calling the ``get`` command
on the key ``limiter-check``
zlimiter-checkTF)rM   r.   rT   r;   s    r5   checkMemcachedStorage.check   s.    
	$$T\\%5%5G	s   &) -c                    [         er9   )NotImplementedErrorr;   s    r5   resetMemcachedStorage.reset   s    !!r7   c                   XB:  a  g[         R                   " 5       nU R                  XU5      u  pgU R                  XgX5S9u  ppX-  U-  U
-   n[        U5      U-   U:  a  gU R	                  USU-  USS9n
[        SU	[         R                   " 5       U-
  -
  5      nX-  U-  U
-   n[        U5      U:  a'  U R                  U R                  R                  UUSS9  gg)NF)now   )ri   rj   r   Tra   )	rg   sliding_window_keys_get_sliding_window_infor   rc   minrM   r.   decr)r1   rV   limitrh   ri   r|   previous_keycurrent_keyprevious_countprevious_ttlcurrent_count_weighted_countactualised_previous_ttls                 r5   acquire_sliding_window_entry-MemcachedStorage.acquire_sliding_window_entry   s    >iik$($<$<S#$N!9=9V9Vv :W :
6m (6?-O 6)E1
 !IIQZ5 & M '*!\TYY[3=N-O&P#86AMQ  ^$u, ((LL%% 	 )  r7   c                x    [         R                   " 5       nU R                  XU5      u  pEU R                  XEX#5      $ r9   )rg   r~   r   r1   rV   rh   r|   r   r   s         r5   get_sliding_window#MemcachedStorage.get_sliding_window  s7     iik$($<$<S#$N!,,\TTr7   c                    [         R                   " 5       nU R                  XU5      u  pEU R                  U5        U R                  U5        g r9   )rg   r~   r^   r   s         r5   clear_sliding_window%MemcachedStorage.clear_sliding_window  s:    iik$($<$<S#$N!

< 

;r7   c                    U R                  X/5      n[        UR                  US5      5      [        UR                  US5      5      pvUS:X  a  [        S5      nOSXC-
  U-  S-  -
  U-  nSXC-  S-  -
  U-  U-   n	XhXy4$ )Nr   r?   )rY   r(   rT   rn   )
r1   r   r   rh   r|   resultr   r   r   current_ttls
             r5   r   )MemcachedStorage._get_sliding_window_info  s     :;

<+,

;*+ &
 Q 8L3<6"9Q!>?6ILS\Q./69FB]GGr7   )r   r   r#   r   r   r-   r*   )F)r2   r$   r   boolr*   z$str | Callable[[], MemcachedClientP]returnNone)r   z-type[Exception] | tuple[type[Exception], ...])r"   r   r   zlist[tuple[str, int]]rC   r$   r   r   )rK   zCallable[P, R]rI   zP.argsrC   zP.kwargsr   r   )r   r   )rV   r$   r   r(   )rZ   zIterable[str]r   zdict[str, Any])rV   r$   r   r   )r?   T)
rV   r$   rh   rn   ri   r(   rj   r   r   r(   )rV   r$   r   rn   )rV   r$   r   r$   )r   r   )r   z
int | None)r?   )
rV   r$   r   r(   rh   r(   ri   r(   r   r   )rV   r$   rh   r(   r   tuple[int, float, int, float])rV   r$   rh   r(   r   r   )
r   r$   r   r$   rh   r(   r|   rn   r   r   )__name__
__module____qualname____firstlineno____doc__STORAGE_SCHEMEDEPENDENCIESr0   propertyr<   r)   rM   r.   rT   rY   r^   rc   ro   rf   ru   ry   r   r   r   r   __static_attributes____classcell__)r4   s   @r5   r   r      s    "]N* >L
 !&*?*? *? 8	*?
 
*? *?X -	6- -

 
)>
JM
	
&	%"	%+1	%=E	%	
	% B B$/+! #'%% % 	%
 !% 
%NQ 
" '' ' 	'
 ' 
'RUU #U	&U HH.1H;>HEJH	&H Hr7   r   )
__future__r   rG   r+   rg   collections.abcr   mathr   r   typesr   limits._storage_schemer   limits.errorsr	   limits.storage.baser
   r   r   limits.typingr   r   r   r   r   r   limits.utilr   r   rr   r7   r5   <module>r      sO    "    $   4 , 
  'NHw ;=U NHr7   