o
    KDi(                     @  s   d dl mZ d dl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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 deeeZdS )    )annotationsN)Iterable)ceilfloor)
ModuleType)ConfigurationError)SlidingWindowCounterSupportStorageTimestampedSlidingWindow)AnyCallableMemcachedClientPPRcast)get_dependencyc                      s   e Zd ZdZdgZ	 dgZ	dMdN fddZedOddZdPddZ	dQd d!Z
edRd"d#ZdSd&d'ZdTd+d,ZdUd-d.Z	/	0dVdWd5d6ZdXd7d8ZdYd9d:ZdZd;d<Zd[d>d?Z	/d\d]dAdBZd^dDdEZd_dFdGZd`dKdLZ  ZS )aMemcachedStoragez[
    Rate limit storage with memcached as backend.

    Depends on :pypi:`pymemcache`.
    	memcached
pymemcacheFuristrwrap_exceptionsbooloptions$str | Callable[[], MemcachedClientP]returnNonec                   s  t j|}g | _|j dD ]}|sq|d\}}| j|t|f q|j	r6|js6|j
s6|j	g| _| jd j| _t|dd| _t|dd| _tttttttf  gtf |d| j| _|| _t| jsvtd	| j t | _d
| j_ t! j"||d d
S )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)r   )#urllibparseurlparsehostsnetlocstripsplitappendintpathportdependenciesmodule
dependencyr   popr   r    r   r   r   listtupler   
get_clientr!   r   r   r   	threadinglocallocal_storagestoragesuper__init__)selfr   r   r   parsedlochostr,   	__class__ Q/var/www/Datamplify/venv/lib/python3.10/site-packages/limits/storage/memcached.pyr9   '   s4   




zMemcachedStorage.__init__-type[Exception] | tuple[type[Exception], ...]c                 C  s   | j jS N)r/   MemcacheErrorr:   r@   r@   rA   base_exceptionsZ   s   z MemcachedStorage.base_exceptionsr.   r   r%   list[tuple[str, int]]kwargsr   c                 K  s6   t tt|dk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)r:   r.   r%   rH   r@   r@   rA   r3   `   s   
zMemcachedStorage.get_clientfuncCallable[P, R]argsP.argsP.kwargsr   c                 O  s:   d|v rt |}d|jv s|js|d ||i |S )Nnoreply)inspectgetfullargspecrO   varkwr0   )r:   rM   rO   rH   argspecr@   r@   rA   call_memcached_funcs   s
   

z$MemcachedStorage.call_memcached_funcc                 C  st   t | jdr
| jjs3tt| jdk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
        r7   rI   r   zUnable to import )hasattrr6   r7   r   rJ   r%   r    r   r   r!   r   r   r   )r:   r/   r@   r@   rA   r7   ~   s   
zMemcachedStorage.storagekeyr*   c                 C  s   t | j|dS )zB
        :param key: the key to get the counter value for
        0)r*   r7   getr:   rY   r@   r@   rA   r[      s   zMemcachedStorage.getkeysIterable[str]dict[str, Any]c                 C  s   | j |S )z
        Return multiple counters at once

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

        :meta private:
        )r7   get_many)r:   r]   r@   r@   rA   r`      s   zMemcachedStorage.get_manyc                 C  s   | j | dS )z>
        :param key: the key to clear rate limits for
        N)r7   deleter\   r@   r@   rA   clear   s   zMemcachedStorage.clearrI   Texpiryfloatamountset_expiration_keyc                 C  s   | j | jj||dd }dur|S | j | jj||t|dds(| j||p'|S |r?| j | jj| ||t  t|d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rR   N)expirerR   )rW   r7   incraddr   set_expiration_keytime)r:   rY   rc   re   rf   valuer@   r@   rA   ri      s&   
zMemcachedStorage.incrc                 C  s   t | j| |pt S )z;
        :param key: the key to get the expiry for
        )rd   r7   r[   rl   rm   r\   r@   r@   rA   
get_expiry   s   zMemcachedStorage.get_expiryc                 C  s   |d 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/expiresr@   r\   r@   r@   rA   rl      s   z MemcachedStorage._expiration_keyc                 C  s$   z|  | jjd W dS    Y dS )zq
        Check if storage is healthy by calling the ``get`` command
        on the key ``limiter-check``
        zlimiter-checkTF)rW   r7   r[   rE   r@   r@   rA   check   s
   zMemcachedStorage.check
int | Nonec                 C  s   t rC   )NotImplementedErrorrE   r@   r@   rA   reset   s   zMemcachedStorage.resetlimitc                 C  s   ||krdS t   }| |||\}}| j||||d\}}	}
}||	 | |
 }t|| |kr2dS | j|d| |dd}
td|	t   |  }|| | |
 }t||krc| j| jj||dd dS dS )NF)now   )re   rf   r   Trg   )	rm   sliding_window_keys_get_sliding_window_infor   ri   minrW   r7   decr)r:   rY   rt   rc   re   ru   previous_keycurrent_keyprevious_countprevious_ttlcurrent_count_weighted_countactualised_previous_ttlr@   r@   rA   acquire_sliding_window_entry   s2   z-MemcachedStorage.acquire_sliding_window_entrytuple[int, float, int, float]c                 C  s*   t   }| |||\}}| ||||S rC   )rm   rw   rx   r:   rY   rc   ru   r{   r|   r@   r@   rA   get_sliding_window  s   z#MemcachedStorage.get_sliding_windowc                 C  s2   t   }| |||\}}| | | | d S rC   )rm   rw   rb   r   r@   r@   rA   clear_sliding_window  s   
z%MemcachedStorage.clear_sliding_windowr{   r|   ru   c           
      C  s~   |  ||g}t||dt||d}}|dkr!td}nd|| | d  | }d|| d  | | }	||||	fS )Nr   rI   )r`   r*   r[   rd   )
r:   r{   r|   rc   ru   resultr}   r   r~   current_ttlr@   r@   rA   rx   #  s   
z)MemcachedStorage._get_sliding_window_info)F)r   r   r   r   r   r   r   r   )r   rB   )r.   r   r%   rG   rH   r   r   r   )rM   rN   rO   rP   rH   rQ   r   r   )r   r   )rY   r   r   r*   )r]   r^   r   r_   )rY   r   r   r   )rI   T)
rY   r   rc   rd   re   r*   rf   r   r   r*   )rY   r   r   rd   )rY   r   r   r   )r   r   )r   rq   )rI   )
rY   r   rt   r*   rc   r*   re   r*   r   r   )rY   r   rc   r*   r   r   )rY   r   rc   r*   r   r   )
r{   r   r|   r   rc   r*   ru   rd   r   r   )__name__
__module____qualname____doc__STORAGE_SCHEMEDEPENDENCIESr9   propertyrF   r3   rW   r7   r[   r`   rb   ri   ro   rl   rp   rs   r   r   r   rx   __classcell__r@   r@   r>   rA   r      s8    3







'

	

)
r   )
__future__r   rS   r4   rm   urllib.parser"   collections.abcr   mathr   r   typesr   limits.errorsr   limits.storage.baser   r	   r
   limits.typingr   r   r   r   r   r   limits.utilr   r   r@   r@   r@   rA   <module>   s     