
    JiT(                        d dl mZ d dlZd dlZd dlZd dlm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mZmZ d d	lmZmZmZmZmZmZ d d
lmZ  G d deee      Zy)    )annotationsN)Iterable)ceilfloor)
ModuleType)parse_storage_uri)ConfigurationError)SlidingWindowCounterSupportStorageTimestampedSlidingWindow)AnyCallableMemcachedClientPPRcast)get_dependencyc                  J    e Zd ZdZdgZ	 dgZ	 d	 	 	 	 	 	 	 d fdZe	 	 dd       Z	 	 	 	 	 	 	 	 ddZ		 	 	 	 	 	 	 	 ddZ
edd       Zdd	Zdd
ZddZ	 	 d	 	 	 	 	 	 	 	 	 ddZd dZd!dZd"dZd#dZ	 d$	 	 	 	 	 	 	 	 	 d%dZ	 	 	 	 	 	 d&dZd'dZ	 	 	 	 	 	 	 	 	 	 d(dZ xZS ))MemcachedStoragez[
    Rate limit storage with memcached as backend.

    Depends on :pypi:`pymemcache`.
    	memcached
pymemcachec                   t        |      }|  |j                  r|j                  g| _        n|j                  | _        | j                  d   j
                  | _        t        |j                  dd            | _	        t        |j                  dd            | _
        t        t        t        t        t        t        t         f      t        t           z  gt"        f   |j                  d| j$                              | _        || _        t+        | j                        st-        d| j                         t/        j0                         | _        d| j2                  _        t6        | q  ||	       y)
an  
        :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        \/var/www/html/asim.com/backend/venv/lib/python3.12/site-packages/limits/storage/memcached.pyr/   zMemcachedStorage.__init__'   s1   $ 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  '__.%)"o>    c                .    | j                   j                  S N)r"   MemcacheErrorr0   s    r4   base_exceptionsz MemcachedStorage.base_exceptionsS   s     ,,,r5   c                    t        t        t        |      dkD  r |j                  |fi |      S  |j                  |i |      S )z
        returns a memcached client.

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

 )V((%:6:
 	
r5   c                    d|v r@t        j                  |      }d|j                  v s|j                  s|j	                  d        ||i |S )Nnoreply)inspectgetfullargspecargsvarkwr$   )r0   funcrE   r@   argspecs        r4   call_memcached_funcz$MemcachedStorage.call_memcached_funcl   sJ     ,,T2G-

9%T$V$$r5   c                   t        | j                  d      r| j                  j                  st        t	        | j
                        dkD  r| j                  n| j                        d   }|st        d| j                          | j                  || j
                  fi | j                  | j                  _        t        t        | j                  j                        S )zQ
        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   )r0   r"   s     r4   r-   zMemcachedStorage.storagew   s     **I64;M;M;U;U'(+DJJ!(;$$J (+<T=Q=Q<R)STT);););DJJ**.,,*D& $d&8&8&@&@AAr5   c                L    t        | j                  j                  |d            S )zB
        :param key: the key to get the counter value for
        0)r'   r-   getr0   keys     r4   rN   zMemcachedStorage.get   s      4<<##C-..r5   c                8    | j                   j                  |      S )z
        Return multiple counters at once

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

        :meta private:
        )r-   get_many)r0   keyss     r4   rR   zMemcachedStorage.get_many   s     ||$$T**r5   c                :    | j                   j                  |       y)z>
        :param key: the key to clear rate limits for
        N)r-   deleterO   s     r4   clearzMemcachedStorage.clear   s     	C r5   c                   | j                  | j                  j                  ||d      x}	 |S | j                  | j                  j                  ||t	        |      d      s | j                  j                  ||      xs |S |rW| j                  | j                  j
                  | j                  |      |t        j                         z   t	        |      d       |S )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rB   )expirerB   )rI   r-   incraddr   set_expiration_keytime)r0   rP   expiryamountset_expiration_keyvalues         r4   rZ   zMemcachedStorage.incr   s    " --!!3 .  E 	
 L++  #vtF|U ,  ||((f5??%,,((,,S1,#F| % -  Mr5   c                    t        | j                  j                  | j                  |            xs t	        j                               S )z;
        :param key: the key to get the expiry for
        )floatr-   rN   r]   r^   rO   s     r4   
get_expiryzMemcachedStorage.get_expiry   s4    
 T\\%%d&:&:3&?@ODIIKPPr5   c                    |dz   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 rO   s     r4   r]   z MemcachedStorage._expiration_key   s     Zr5   c                `    	 | j                  | j                  j                  d       y#  Y yxY w)zq
        Check if storage is healthy by calling the ``get`` command
        on the key ``limiter-check``
        zlimiter-checkTF)rI   r-   rN   r9   s    r4   checkzMemcachedStorage.check   s.    
	$$T\\%5%5G	s   &) -c                    t         r7   )NotImplementedErrorr9   s    r4   resetzMemcachedStorage.reset   s    !!r5   c                   ||kD  ryt        j                          }| j                  |||      \  }}| j                  ||||      \  }}	}
}||	z  |z  |
z   }t        |      |z   |kD  ry| j	                  |d|z  |d      }
t        d|	t        j                          |z
  z
        }||z  |z  |
z   }t        |      |kD  r*| j                  | j                  j                  ||d       yy)NF)now   )r`   ra   r   TrX   )	r^   sliding_window_keys_get_sliding_window_infor   rZ   minrI   r-   decr)r0   rP   limitr_   r`   rn   previous_keycurrent_keyprevious_countprevious_ttlcurrent_count_weighted_countactualised_previous_ttls                 r4   acquire_sliding_window_entryz-MemcachedStorage.acquire_sliding_window_entry   s     E>iik$($<$<S&#$N!k9=9V9V+v3 :W :
6mQ (,6?-O 6)E1
 !IIQZ5 & M '*!\TYY[3=N-O&P#!886AMQ  ^$u, ((LL%% 	 )  r5   c                ~    t        j                          }| j                  |||      \  }}| j                  ||||      S r7   )r^   rp   rq   r0   rP   r_   rn   ru   rv   s         r4   get_sliding_windowz#MemcachedStorage.get_sliding_window  s@     iik$($<$<S&#$N!k,,\;PSTTr5   c                    t        j                          }| j                  |||      \  }}| j                  |       | j                  |       y r7   )r^   rp   rV   r   s         r4   clear_sliding_windowz%MemcachedStorage.clear_sliding_window  s>    iik$($<$<S&#$N!k

< 

;r5   c                   | j                  ||g      }t        |j                  |d            t        |j                  |d            }}|dk(  rt        d      }nd||z
  |z  dz  z
  |z  }d||z  dz  z
  |z  |z   }	||||	fS )Nr   r<   )rR   r'   rN   rd   )
r0   ru   rv   r_   rn   resultrw   ry   rx   current_ttls
             r4   rq   z)MemcachedStorage._get_sliding_window_info  s     k:;

<+,

;*+ &
 Q 8L3<6"9Q!>?6ILS6\Q./69FB|]KGGr5   )F)r1   r#   r   boolr)   z$str | Callable[[], MemcachedClientP]returnNone)r   z-type[Exception] | tuple[type[Exception], ...])r!   r   r   zlist[tuple[str, int]]r@   r#   r   r   )rG   zCallable[P, R]rE   zP.argsr@   zP.kwargsr   r   )r   r   )rP   r#   r   r'   )rS   zIterable[str]r   zdict[str, Any])rP   r#   r   r   )r<   T)
rP   r#   r_   rd   r`   r'   ra   r   r   r'   )rP   r#   r   rd   )rP   r#   r   r#   )r   r   )r   z
int | None)r<   )
rP   r#   rt   r'   r_   r'   r`   r'   r   r   )rP   r#   r_   r'   r   tuple[int, float, int, float])rP   r#   r_   r'   r   r   )
ru   r#   rv   r#   r_   r'   rn   rd   r   r   )__name__
__module____qualname____doc__STORAGE_SCHEMEDEPENDENCIESr/   propertyr:   r(   rI   r-   rN   rR   rV   rZ   re   r]   ri   rl   r}   r   r   rq   __classcell__)r3   s   @r4   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r5   r   )
__future__r   rC   r*   r^   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   rg   r5   r4   <module>r      sO    "    $   4 , 
  'NHw ;=U NHr5   