o
    KDi"                     @  s   d dl mZ d dl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 G dd dZG dd	 d	eeeeZdS )
    )annotationsN)Counterdefaultdict)floor)MovingWindowSupportSlidingWindowCounterSupportStorageTimestampedSlidingWindowc                   @  s   e Zd ZdddZdS )	EntryexpiryfloatreturnNonec                 C  s   t   | _| j| | _d S N)timeatimer   )selfr    r   N/var/www/Datamplify/venv/lib/python3.10/site-packages/limits/storage/memory.py__init__   s   
zEntry.__init__N)r   r   r   r   )__name__
__module____qualname__r   r   r   r   r   r
      s    r
   c                      s   e Zd ZdZdgZdCdD fddZdEddZdFddZdGddZdGddZ	e
dHddZdIdJd"d#ZdIdKd$d%ZdLd&d'ZdMd(d)ZdIdNd+d,ZdOd-d.ZdPd0d1Z	dIdNd2d3ZdQd8d9ZdRd:d;ZdSd<d=ZdTd>d?ZdUdAdBZ  ZS )VMemoryStoragez
    rate limit storage using :class:`collections.Counter`
    as an in memory storage for fixed and sliding window strategies,
    and a simple list to implement moving window strategy.

    memoryNFuri
str | Nonewrap_exceptionsbool_strc                   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startsuperr   )r   r   r   r   	__class__r   r   r   $   s   
zMemoryStorage.__init__r   dict[str, limits.typing.Any]c                 C  s   | j  }|d= |d= |S )Nr*   r%   )__dict__copyr   stater   r   r   __getstate__-   s   
zMemoryStorage.__getstate__r3   r   c                 C  s6   | j | ttj| _td| j| _| j	  d S Nr!   )
r0   updater   r#   r$   r%   r(   r)   r*   r+   r2   r   r   r   __setstate__3   s   zMemoryStorage.__setstate__c              	   C  s   t | j D ]G}| j| 8 | j|g  }r1tj|t  dd d}| j| d | | j|< | j|d s?| j|d  W d    n1 sIw   Y  qt | j	 D ] }| j	| t krv| j
|d  | j	|d  | j|d  qVd S )Nc                 S     | j  S r   )r   )eventr   r   r   <lambda>>       z/MemoryStorage.__expire_events.<locals>.<lambda>key)listr'   keysr%   getbisectbisect_leftr   popr&   r"   )r   r=   r'   oldestr   r   r   __expire_events9   s&   zMemoryStorage.__expire_eventsc                 C  s,   | j  std| j| _ | j   d S d S r5   )r*   is_aliver#   r(   r)   r+   r   r   r   r   __schedule_expiryI   s   
zMemoryStorage.__schedule_expiry-type[Exception] | tuple[type[Exception], ...]c                 C  s   t S r   )
ValueErrorrG   r   r   r   base_exceptionsN   s   zMemoryStorage.base_exceptions   r=   r   r   amountintc                 C  s|   |  | |   | j| ! | j|  |7  < | j| |kr(t | | j|< W d   n1 s2w   Y  | j |dS )z
        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 amount: the number to increment by
        Nr   )r@   _MemoryStorage__schedule_expiryr%   r"   r   r&   )r   r=   r   rM   r   r   r   incrT   s   
zMemoryStorage.incrc                 C  sd   |  | |   | j|  t| j| | d| j|< W d   n1 s&w   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@   rO   r%   maxr"   )r   r=   rM   r   r   r   decrd   s   
zMemoryStorage.decrc                 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"   rC   r%   r   r=   r   r   r   r@   r   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"   rC   r&   r'   r%   rS   r   r   r   clear~   s   zMemoryStorage.clearlimitc              	   C  s   ||krdS |    | j| L | j|g  t }z| j| ||  }W n ty1   d}Y nw |rD|j|| krD	 W d   dS t|g| | j| dd< 	 W d   dS 1 s^w   Y  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
        FNr   T)rO   r%   r'   
setdefaultr   
IndexErrorr   r
   )r   r=   rU   r   rM   	timestampentryr   r   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   rS   r   r   r   
get_expiry   s   zMemoryStorage.get_expirytuple[float, int]c                 C  sN   t   }| j|g  }r#tj|||  dd d}||d  j|fS |d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)
        c                 S  r8   r   )r   )rY   r   r   r   r:      r;   z1MemoryStorage.get_moving_window.<locals>.<lambda>r<   rL   r   )r   r'   r@   rA   rB   r   )r   r=   rU   r   rX   r'   rD   r   r   r   get_moving_window   s   	zMemoryStorage.get_moving_windowc                 C  s   ||krdS t   }| |||\}}| ||||\}}	}
}||	 | |
 }t|| |kr1dS | j|d| |d}
||	 | |
 }t||krQ| || dS dS )NF   )rM   T)r   sliding_window_keys_get_sliding_window_infor   rP   rR   )r   r=   rU   r   rM   nowprevious_keycurrent_keyprevious_countprevious_ttlcurrent_countr   weighted_countr   r   r   acquire_sliding_window_entry   s&   z*MemoryStorage.acquire_sliding_window_entryrb   rc   ra   tuple[int, float, int, float]c           	      C  sb   |  |}|  |}|dkrtd}nd|| | d  | }d|| d  | | }||||fS )Nr   rL   )r@   r   )	r   rb   rc   r   ra   rd   rf   re   current_ttlr   r   r   r`      s   


z&MemoryStorage._get_sliding_window_infoc                 C  s*   t   }| |||\}}| ||||S r   )r   r_   r`   r   r=   r   ra   rb   rc   r   r   r   get_sliding_window   s   z MemoryStorage.get_sliding_windowc                 C  s2   t   }| |||\}}| | | | d S r   )r   r_   rT   rk   r   r   r   clear_sliding_window   s   
z"MemoryStorage.clear_sliding_windowc                 C  s   dS )z-
        check if storage is healthy
        Tr   rG   r   r   r   check   s   zMemoryStorage.check
int | Nonec                 C  sB   t t| jt| j}| j  | j  | j  | j  |S r   )rQ   lenr"   r'   rT   r&   r%   )r   	num_itemsr   r   r   reset   s   



zMemoryStorage.reset)NF)r   r   r   r   r   r    )r   r/   )r3   r/   r   r   )r   r   )r   rI   )rL   )r=   r    r   r   rM   rN   r   rN   )r=   r    rM   rN   r   rN   )r=   r    r   rN   )r=   r    r   r   )
r=   r    rU   rN   r   rN   rM   rN   r   r   )r=   r    r   r   )r=   r    rU   rN   r   rN   r   r\   )
rb   r    rc   r    r   rN   ra   r   r   ri   )r=   r    r   rN   r   ri   )r=   r    r   rN   r   r   )r   r   )r   ro   )r   r   r   __doc__STORAGE_SCHEMEr   r4   r7   r)   rO   propertyrK   rP   rR   r@   rT   rZ   r[   r]   rh   r`   rl   rm   rn   rr   __classcell__r   r   r-   r   r      s0    
	




	


!


r   )
__future__r   rA   r#   r   collectionsr   r   mathr   limits.typinglimitslimits.storage.baser   r   r   r	   r
   r   r   r   r   r   <module>   s    
