U
    ]gp                     @   s   d Z ddlmZmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ dd	lmZmZ G d
d deZG dd deZG dd deZG dd deZeeedZdS )z'
Asynchronous rate limiting strategies
    )ABCabstractmethod)cast   )RateLimitItem)StorageTypes)WindowStats   )MovingWindowSupportStoragec                   @   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   9/tmp/pip-unpacked-wheel-kizsipjx/limits/aio/strategies.py__init__   s    zRateLimiter.__init__r	   costitemidentifiersr   returnc                   s   t dS )
        Consume the rate limit

        :param item: the rate limit item
        :param identifiers: variable list of strings to uniquely identify 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                   s   t dS )  
        Check if the rate limit can be consumed

        :param item: the rate limit item
        :param identifiers: variable list of strings to uniquely identify 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                    s   t dS )z
        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 the
         limit
        :return: (reset time, remaining))
        Nr   r   r   r   r   r   r   get_window_stats+   s    zRateLimiter.get_window_statsNc                    s   | j |j| I d H S r   )r   clearkey_forr$   r   r   r   r&   9   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   c                       sn   e Zd ZdZed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`
    N)r   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   r2   r   r   r   B   s    z MovingWindowRateLimiter.__init__r	   r   r   c                   s,   t t| jj|j| |j| |dI dH S )r   )amountN)r   r
   r   r/   r'   r5   
get_expiryr   r   r   r   r    L   s    
   zMovingWindowRateLimiter.hitc                   s>   t t| j|j| |j| I dH }|d }||j| kS r!   Nr	   )r   r
   r   r0   r'   r5   r6   )r   r   r   r   resr5   r   r   r   r"   Z   s    	
zMovingWindowRateLimiter.testr#   c                    sH   t t| j|j| |j| I dH \}}||  }t||j| S )z
        returns the number of requests remaining within this limit.

        :param item: the rate limit item
        :param identifiers: variable list of strings to uniquely identify the
         limit
        :return: (reset time, remaining)
        N)r   r
   r   r0   r'   r5   r6   r   )r   r   r   Zwindow_startZwindow_itemsresetr   r   r   r%   l   s       z(MovingWindowRateLimiter.get_window_stats)r(   r)   r*   __doc__r   r   r   r+   r,   r-   r    r"   r   r%   __classcell__r   r   r4   r   r.   =   s   
 r.   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                   s*   | j j|j| | d|dI dH |jkS )r   FZelastic_expiryr5   Nr   incrr'   r6   r5   r   r   r   r   r       s    
zFixedWindowRateLimiter.hitc                   s&   | j |j| I dH |j| d k S r7   )r   getr'   r5   r   r   r   r   r"      s    $zFixedWindowRateLimiter.testr#   c                    sF   t d|j| j|j| I dH  }| j|j| I dH }t||S )z
        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 the
         limit
        :return: reset time, remaining
        r   N)maxr5   r   r@   r'   r6   r   )r   r   r   	remainingr9   r   r   r   r%      s    z'FixedWindowRateLimiter.get_window_statsN)r(   r)   r*   r:   r   r+   r,   r-   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                   s.   | j j|j| | d|dI dH }||jkS )a   
        Consume the rate limit

        :param item: a :class:`limits.limits.RateLimitItem` instance
        :param identifiers: variable list of strings to uniquely identify the
         limit
        :param cost: The cost of this hit, default 1
        Tr=   Nr>   )r   r   r   r   r5   r   r   r   r       s    	z'FixedWindowElasticExpiryRateLimiter.hitN)	r(   r)   r*   r:   r   r+   r,   r-   r    r   r   r   r   rC      s   rC   )zfixed-windowzfixed-window-elastic-expiryzmoving-windowN)r:   abcr   r   typingr   Zlimitsr   r   r   utilr   r
   r   r   r.   r<   rC   Z
STRATEGIESr   r   r   r   <module>   s   /B;