a
    a*j#                     @  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	m
Z
 d dlZd dlmZmZmZ d dlmZ d dlmZmZmZ G d	d
 d
ejZe
ddG dd deeeeZdS )    )annotationsN)Counterdefaultdict)floor)versionadded)MovingWindowSupportSlidingWindowCounterSupportStorage)TimestampedSlidingWindow)OptionalTypeUnionc                      s$   e Zd Zddd fddZ  ZS )LockableEntryintNone)expiryreturnc                   s$   t   | _| j| | _t   d S N)timeatimer   super__init__)selfr   	__class__ U/var/www/html/assistant/venv/lib/python3.9/site-packages/limits/aio/storage/memory.pyr      s    
zLockableEntry.__init__)__name__
__module____qualname__r   __classcell__r   r   r   r   r      s   r   z2.1)versionc                      sX  e Zd ZdZdgZd;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d0d'd1d2Zddddd0d3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async+memoryNFzOptional[str]boolstrr   )uriwrap_exceptions_r   c                   sB   t  | _ttj| _i | _i | _d | _t	 j
|fd|i| d S )Nr&   )r   storager   asyncioLocklocksexpirationseventstimerr   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_exceptions5   s    zMemoryStorage.base_exceptionsc                   s   | j  D ]|}t| j | D ]h}|4 I d H B |jt krZ|| j | v rZ| j | | W d   I d H  q1 I d H sz0    Y  qq
t| j D ]@}| j| t kr| j|d  | j|d  | j	|d  qd S r   )
r-   keyslistr   r   remover,   r(   popr+   )r   keyeventr   r   r   Z__expire_events;   s    >zMemoryStorage.__expire_eventsc                   s$   | j r| j  r t|  | _ d S r   )r.   doner)   Zcreate_task_MemoryStorage__expire_eventsr0   r   r   r   Z__schedule_expiryH   s    zMemoryStorage.__schedule_expiry   floatr   )r6   r   elastic_expiryamountr   c              	     s   |  |I dH  |  I dH  | j| 4 I dH L | j|  |7  < |sV| j| |krht | | j|< W d  I dH  q1 I dH s0    Y  | j ||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
        N)get_MemoryStorage__schedule_expiryr+   r(   r   r,   )r   r6   r   r<   r=   r   r   r   incrL   s    <zMemoryStorage.incr)r6   r=   r   c              	     s   |  |I dH  |  I dH  | j| 4 I dH 0 t| j| | d| j|< W d  I dH  qv1 I dH sl0    Y  | j ||S )z
        decrements the counter for a given rate limit key. 0 is the minimum allowed value.

        :param amount: the number to increment by
        Nr   )r>   r?   r+   maxr(   )r   r6   r=   r   r   r   decrb   s
    DzMemoryStorage.decr)r6   r   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(   r5   r+   r   r6   r   r   r   r>   o   s
    zMemoryStorage.getc                   s<   | j |d | j|d | j|d | j|d dS )z>
        :param key: the key to clear rate limits for
        N)r(   r5   r,   r-   r+   rC   r   r   r   clearz   s    zMemoryStorage.clear)r6   limitr   r=   r   c                   s   ||krdS | j |g  |  I dH  t }z| j | ||  }W n ty\   d}Y n0 |rt|j|  krtd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   r6   rE   r   r=   	timestampentryr   rG   r   acquire_entry   s    	
$zMemoryStorage.acquire_entryc                   s   | j |t S )z;
        :param key: the key to get the expiry for
        )r,   r>   r   rC   r   r   r   
get_expiry   s    zMemoryStorage.get_expiry)r6   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   )rF   kr   rM   r   r   rH      rI   z2MemoryStorage.get_num_acquired.<locals>.<listcomp>r   )r   r-   r>   len)r   r6   r   r   rR   r   get_num_acquired   s
    
 zMemoryStorage.get_num_acquiredztuple[float, int])r6   rE   r   r   c                   s\   t   }| ||I dH }| j|g ddd D ] }|j|| kr2|j|f  S q2||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   rT   r-   r>   r   )r   r6   rE   r   rM   Zacquireditemr   r   r   get_moving_window   s    zMemoryStorage.get_moving_windowc                   s   ||krdS t   }| |||\}}| ||||I d H \}}	}
}||	 | |
 }t|| |krhdS | j|d| |dI d H }
||	 | |
 }t||kr| ||I d H  dS dS d S )NF   )r=   T)r   sliding_window_keys_get_sliding_window_infor   r@   rB   )r   r6   rE   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]c                   s0   t   }| |||\}}| ||||I d H S r   )r   rY   rZ   )r   r6   r   r[   r\   r]   r   r   r   get_sliding_window   s
    z MemoryStorage.get_sliding_window)r\   r]   r   r[   r   c           	        sn   |  |I d H }|  |I d H }|dkr2td}nd|| | d  | }d|| d  | | }||||fS )Nr   r:   )r>   r;   )	r   r\   r]   r   r[   r^   r`   r_   Zcurrent_ttlr   r   r   rZ      s    
z&MemoryStorage._get_sliding_window_infoc                   s   dS )z-
        check if storage is healthy
        Tr   r0   r   r   r   check  s    zMemoryStorage.checkzOptional[int]c                   sB   t t| jt| j}| j  | j  | j  | j  |S r   )rA   rS   r(   r-   rD   r,   r+   )r   	num_itemsr   r   r   reset  s    



zMemoryStorage.reset)NF)Fr:   )r:   )r:   )r:   )r   r   r   __doc__ZSTORAGE_SCHEMEr   propertyr1   r9   r?   r@   rB   r>   rD   rO   rP   rT   rW   ra   rb   rZ   rc   re   r    r   r   r   r   r"      s0    
 
  "	r"   )
__future__r   r)   r   collectionsr   r   mathr   Zdeprecated.sphinxr   Zlimits.typingZlimitsZlimits.aio.storage.baser   r   r	   Zlimits.storage.baser
   r   r   r   r*   r   r"   r   r   r   r   <module>   s   
