a
    a*jB"                     @  s   d dl mZ d dlZd dlZd dlmZmZ d dlm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 G dd dejZG d	d
 d
eeeeZdS )    )annotationsN)Counterdefaultdict)floor)MovingWindowSupportSlidingWindowCounterSupportStorageTimestampedSlidingWindow)OptionalTypeUnionc                      s$   e Zd Zddd fddZ  ZS )LockableEntryfloatNone)expiryreturnc                   s$   t   | _| j| | _t   d S N)timeatimer   super__init__)selfr   	__class__ Q/var/www/html/assistant/venv/lib/python3.9/site-packages/limits/storage/memory.pyr      s    
zLockableEntry.__init__)__name__
__module____qualname__r   __classcell__r   r   r   r   r      s   r   c                      sV  e Zd ZdZdgZd;dddd fd	d
ZeddddZddddZddddZ	d<ddddddddZ
d=ddddddZdddddZdddd d!Zd>dddddd"d#d$Zdddd%d&Zdddd'd(d)Zdddd*d+d,d-Zd?dddddd"d.d/Zddddd0d1d2d3Zddd0d'd4d5Zddd6d7Zd8dd9d:Z  ZS )@MemoryStoragez
    rate limit storage using :class:`collections.Counter`
    as an in memory storage for fixed and elastic window strategies,
    and a simple list to implement moving window strategy.

    ZmemoryNFzOptional[str]boolstr)uriwrap_exceptions_c                   sV   t  | _ttj| _i | _i | _td| j	| _
| j
  t j|fd|i| d S )N{Gz?r$   )r   storager   	threadingRLocklocksexpirationseventsTimer_MemoryStorage__expire_eventstimerstartr   r   )r   r#   r$   r%   r   r   r   r   %   s    
zMemoryStorage.__init__z3Union[Type[Exception], tuple[Type[Exception], ...]])r   c                 C  s   t S r   )
ValueErrorr   r   r   r   base_exceptions0   s    zMemoryStorage.base_exceptionsr   c              
   C  s   t | j D ]h}t | j| D ]T}|< |jt krV|| j| v rV| j| | W d    q 1 sj0    Y  q qt | j D ]@}| j| t kr| j|d  | j|d  | j	|d  qd S r   )
listr,   keysr   r   remover+   r'   popr*   )r   keyeventr   r   r   Z__expire_events6   s    2zMemoryStorage.__expire_eventsc                 C  s(   | j  s$td| j| _ | j   d S )Nr&   )r/   is_aliver(   r-   r.   r0   r2   r   r   r   Z__schedule_expiryC   s    
zMemoryStorage.__schedule_expiry   r   int)r8   r   elastic_expiryamountr   c                 C  s   |  | |   | j| F | j|  |7  < |sB| j| |krTt | | j|< W d   n1 sh0    Y  | j |dS )aD  
        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
        :param elastic_expiry: whether to keep extending the rate limit
         window every hit.
        :param amount: the number to increment by
        Nr   )get_MemoryStorage__schedule_expiryr*   r'   r   r+   )r   r8   r   r=   r>   r   r   r   incrH   s    
0zMemoryStorage.incr)r8   r>   r   c                 C  sd   |  | |   | j| * t| j| | d| j|< W d   n1 sL0    Y  | j |dS )z
        decrements the counter for a given rate limit key

        :param key: the key to decrement
        :param amount: the number to decrement by
        r   N)r?   r@   r*   maxr'   )r   r8   r>   r   r   r   decr^   s
    
8zMemoryStorage.decr)r8   r   c                 C  sN   | j |dt kr@| j|d | j |d | j|d | j|dS )zB
        :param key: the key to get the counter value for
        r   N)r+   r?   r   r'   r7   r*   r   r8   r   r   r   r?   l   s
    zMemoryStorage.getc                 C  s<   | j |d | j|d | j|d | j|d dS )z>
        :param key: the key to clear rate limits for
        N)r'   r7   r+   r,   r*   rD   r   r   r   clearx   s    zMemoryStorage.clear)r8   limitr   r>   r   c                   s   ||krdS | j |g  |   t }z| j | ||  }W n tyV   d}Y n0 |rn|j|  krndS  fddt|D | j | dd< dS dS )z
        :param key: rate limit key to acquire an entry in
        :param limit: amount of entries allowed
        :param expiry: expiry of the entry
        :param amount: the number of entries to acquire
        FNc                   s   g | ]}t  qS r   )r   ).0r%   r   r   r   
<listcomp>       z/MemoryStorage.acquire_entry.<locals>.<listcomp>r   T)r,   
setdefaultr@   r   
IndexErrorr   range)r   r8   rF   r   r>   	timestampentryr   rH   r   acquire_entry   s    
$zMemoryStorage.acquire_entryc                 C  s   | j |t S )z;
        :param key: the key to get the expiry for
        )r+   r?   r   rD   r   r   r   
get_expiry   s    zMemoryStorage.get_expiry)r8   r   r   c                   s6   t   | j|r2t fdd| j| D S dS )z
        returns the number of entries already acquired

        :param key: rate limit key to acquire an entry in
        :param expiry: expiry of the entry
        c                   s   g | ]}|j   kr|qS r   )r   )rG   kr   rN   r   r   rI      rJ   z2MemoryStorage.get_num_acquired.<locals>.<listcomp>r   )r   r,   r?   len)r   r8   r   r   rS   r   get_num_acquired   s
    
 zMemoryStorage.get_num_acquiredztuple[float, int])r8   rF   r   r   c                 C  sV   t   }| ||}| j|g ddd D ] }|j|| kr,|j|f  S q,||fS )z
        returns the starting point and the number of entries in the moving
        window

        :param key: rate limit key
        :param expiry: expiry of entry
        :return: (start of window, number of acquired entries)
        N)r   rU   r,   r?   r   )r   r8   rF   r   rN   Zacquireditemr   r   r   get_moving_window   s    	zMemoryStorage.get_moving_windowc                 C  s   ||krdS t   }| |||\}}| ||||\}}	}
}||	 | |
 }t|| |krbdS | j|d| |d}
||	 | |
 }t||kr| || dS dS d S )NF   )r>   T)r   sliding_window_keys_get_sliding_window_infor   rA   rC   )r   r8   rF   r   r>   nowprevious_keycurrent_keyprevious_countprevious_ttlcurrent_countr%   Zweighted_countr   r   r   acquire_sliding_window_entry   s&    z*MemoryStorage.acquire_sliding_window_entryztuple[int, float, int, float])r]   r^   r   r\   r   c           	      C  sb   |  |}|  |}|dkr&td}nd|| | d  | }d|| d  | | }||||fS )Nr   r;   )r?   r   )	r   r]   r^   r   r\   r_   ra   r`   Zcurrent_ttlr   r   r   r[      s    


z&MemoryStorage._get_sliding_window_infoc                 C  s*   t   }| |||\}}| ||||S r   )r   rZ   r[   )r   r8   r   r\   r]   r^   r   r   r   get_sliding_window   s    z MemoryStorage.get_sliding_windowc                 C  s   dS )z-
        check if storage is healthy
        Tr   r2   r   r   r   check   s    zMemoryStorage.checkzOptional[int]c                 C  sB   t t| jt| j}| j  | j  | j  | j  |S r   )rB   rT   r'   r,   rE   r+   r*   )r   	num_itemsr   r   r   reset  s    



zMemoryStorage.reset)NF)Fr;   )r;   )r;   )r;   )r   r   r   __doc__ZSTORAGE_SCHEMEr   propertyr3   r.   r@   rA   rC   r?   rE   rP   rQ   rU   rX   rb   r[   rc   rd   rf   r   r   r   r   r   r       s.     	 "r    )
__future__r   r(   r   collectionsr   r   mathr   Zlimits.typingZlimitsZlimits.storage.baser   r   r   r	   r
   r   r   _RLockr   r    r   r   r   r   <module>   s   
