U
    ]g%                     @   s   U d Z ddlmZmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZmZmZ ddlmZ G dd	 d	ed
ZG dd deZG dd deZG dd deZeee ee ee f ZeeedZeeef ed< dS )z
Rate limiting strategies
    )ABCMetaabstractmethod)DictTypeUnioncast   )RateLimitItem)MovingWindowSupportStorageStorageTypes)WindowStatsc                   @   s~   e Zd ZedddZeddeeee	dddZ
eddeeee	dd	d
ZeeeedddZeeddddZdS )RateLimiterstoragec                 C   s   t |tst|| _d S N)
isinstancer   AssertionErrorr   selfr    r   5/tmp/pip-unpacked-wheel-kizsipjx/limits/strategies.py__init__   s    zRateLimiter.__init__r   costitemidentifiersr   returnc                G   s   t dS )
        Consume the rate limit

        :param item: The rate limit item
        :param identifiers: variable list of strings to uniquely identify this
         instance of the limit
        :param cost: The cost of this hit, default 1
        NNotImplementedErrorr   r   r   r   r   r   r   hit   s    
zRateLimiter.hitc                G   s   t dS )a  
        Check the rate limit without consuming from it.

        :param item: The rate limit item
        :param identifiers: variable list of strings to uniquely identify this
          instance of the limit
        :param cost: The expected cost to be consumed, default 1
        Nr    r"   r   r   r   test   s    
zRateLimiter.testr   r   r   c                 G   s   t dS )
  
        Query the reset time and remaining amount for the limit

        :param item: The rate limit item
        :param identifiers: variable list of strings to uniquely identify this
         instance of the limit
        :return: (reset time, remaining)
        Nr    r   r   r   r   r   r   get_window_stats*   s    
zRateLimiter.get_window_statsNc                 G   s   | j |j| S r   )r   clearkey_forr'   r   r   r   r)   6   s    zRateLimiter.clear)__name__
__module____qualname__r   r   r   r	   strintboolr#   r$   r   r(   r)   r   r   r   r   r      s   r   )	metaclassc                       sl   e Zd ZdZed fddZddeeee	ddd	Z
ddeeee	dd
dZeeedddZ  ZS )MovingWindowRateLimiterz4
    Reference: :ref:`strategies:moving window`
    r   c                    s2   t |ds"t |ds"td|j t | d S )Nacquire_entryget_moving_windowzBMovingWindowRateLimiting is not implemented for storage of type %s)hasattrr!   	__class__superr   r   r6   r   r   r   ?   s    z MovingWindowRateLimiter.__init__r   r   r   c                G   s&   t t| jj|j| |j| |dS )a  
        Consume the rate limit

        :param item: The rate limit item
        :param identifiers: variable list of strings to uniquely identify this
         instance of the limit
        :param cost: The cost of this hit, default 1
        :return: (reset time, remaining)
        )amount)r   r
   r   r3   r*   r9   
get_expiryr"   r   r   r   r#   I   s       zMovingWindowRateLimiter.hitc                G   s0   t t| j|j| |j| d |j| kS a  
        Check if the rate limit can be consumed

        :param item: The rate limit item
        :param identifiers: variable list of strings to uniquely identify this
         instance of the limit
        :param cost: The expected cost to be consumed, default 1
        r   )r   r
   r   r4   r*   r9   r:   r"   r   r   r   r$   X   s    zMovingWindowRateLimiter.testr%   c                 G   sB   t t| j|j| |j| \}}||  }t||j| S )a  
        returns the number of requests remaining within this limit.

        :param item: The rate limit item
        :param identifiers: variable list of strings to uniquely identify this
         instance of the limit
        :return: tuple (reset time, remaining)
        )r   r
   r   r4   r*   r9   r:   r   )r   r   r   Zwindow_startZwindow_itemsresetr   r   r   r(   k   s    	   z(MovingWindowRateLimiter.get_window_stats)r+   r,   r-   __doc__r   r   r	   r.   r/   r0   r#   r$   r   r(   __classcell__r   r   r8   r   r2   :   s
   
r2   c                   @   sV   e Zd ZdZddeeeedddZddeeeedddZ	eee
d	d
dZdS )FixedWindowRateLimiterz3
    Reference: :ref:`strategies:fixed window`
    r   r   r   c                G   s$   | j j|j| | d|d|jkS )r   FZelastic_expiryr9   r   incrr*   r:   r9   r"   r   r   r   r#      s    zFixedWindowRateLimiter.hitc                G   s    | j |j| |j| d k S r;   )r   getr*   r9   r"   r   r   r   r$      s    
zFixedWindowRateLimiter.testr%   c                 G   s:   t d|j| j|j|  }| j|j| }t||S )r&   r   )maxr9   r   rC   r*   r:   r   )r   r   r   	remainingr<   r   r   r   r(      s    	z'FixedWindowRateLimiter.get_window_statsN)r+   r,   r-   r=   r	   r.   r/   r0   r#   r$   r   r(   r   r   r   r   r?   |   s   r?   c                   @   s*   e Zd ZdZddeeeedddZdS )#FixedWindowElasticExpiryRateLimiterzG
    Reference: :ref:`strategies:fixed window with elastic expiry`
    r   r   r   c                G   s$   | j j|j| | d|d|jkS )r   Tr@   rA   r"   r   r   r   r#      s    z'FixedWindowElasticExpiryRateLimiter.hitN)	r+   r,   r-   r=   r	   r.   r/   r0   r#   r   r   r   r   rF      s   rF   )zfixed-windowzfixed-window-elastic-expiryzmoving-window
STRATEGIESN)r=   abcr   r   typingr   r   r   r   Zlimitsr	   r   r
   r   r   utilr   r   r2   r?   rF   ZKnownStrategyrG   r.   __annotations__r   r   r   r   <module>   s&   -B4