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mZmZmZmZmZmZmZmZ d dlmZ ddd	d
dZG dd dee
dZG dd deZG dd deZG dd dZdS )    )annotationsN)ABCabstractmethod)errors)StorageRegistry)AnyCallableOptionalPRTypeUnioncast)LazyDependencyzCallable[P, R])fnreturnc                   s$   t  dddd fdd}|S )NzP.argszP.kwargsr   )argskwargsr   c               
     s^   t t| d }z | i |W S  |jyX } z |jrBt|| W Y d }~n
d }~0 0 d S )Nr   )r   Storagebase_exceptionswrap_exceptionsr   ZStorageError)r   r   instanceexcr    O/var/www/html/assistant/venv/lib/python3.9/site-packages/limits/storage/base.pyinner   s    z_wrap_errors.<locals>.inner)	functoolswraps)r   r   r   r   r   _wrap_errors   s    	r   c                      s   e Zd ZU dZded< ddd fddZd(dddd fddZeeddddZ	ed)ddddddddZ
edddddZeddddd Zeddd!d"Zed#dd$d%Zedddd&d'Z  ZS )*r   zC
    Base class to extend when implementing a storage backend.
    zOptional[list[str]]ZSTORAGE_SCHEMEr   Noner   r   c                   s6   dD ]}t | |tt| | qt jf i | d S )N>   clearcheckincrreset
get_expirygetsetattrr   getattrsuper__init_subclass__clsr   method	__class__r   r   r,   .   s    zStorage.__init_subclass__NFzOptional[str]boolzUnion[float, str, bool])urir   optionsc                   s   t  | _t   || _dS )z
        :param wrap_exceptions: Whether to wrap storage exceptions in
         :exc:`limits.errors.StorageError` before raising it.
        N)	threadingRLocklockr+   __init__r   )selfr3   r   r4   r0   r   r   r8   :   s    

zStorage.__init__z3Union[Type[Exception], tuple[Type[Exception], ...]])r   c                 C  s   t d S )NNotImplementedErrorr9   r   r   r   r   I   s    zStorage.base_exceptions   strint)keyexpiryelastic_expiryamountr   c                 C  s   t 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:   )r9   r@   rA   rB   rC   r   r   r   r$   N   s    zStorage.incr)r@   r   c                 C  s   t dS )zB
        :param key: the key to get the counter value for
        Nr:   r9   r@   r   r   r   r'   ]   s    zStorage.getfloatc                 C  s   t dS )z;
        :param key: the key to get the expiry for
        Nr:   rD   r   r   r   r&   d   s    zStorage.get_expiryc                 C  s   t dS )z-
        check if storage is healthy
        Nr:   r<   r   r   r   r#   k   s    zStorage.checkzOptional[int]c                 C  s   t dS )z/
        reset storage to clear limits
        Nr:   r<   r   r   r   r%   r   s    zStorage.resetc                 C  s   t dS )za
        resets the rate limit key

        :param key: the key to clear rate limits for
        Nr:   rD   r   r   r   r"   y   s    zStorage.clear)NF)Fr=   )__name__
__module____qualname____doc____annotations__r,   r8   propertyr   r   r$   r'   r&   r#   r%   r"   __classcell__r   r   r0   r   r   &   s,   
   r   )	metaclassc                      s\   e Zd ZdZddd fddZeddd	d	d	d
dddZedd	d	ddddZ  ZS )MovingWindowSupportzh
    Abstract base class for storages that support
    the :ref:`strategies:moving window` strategy
    r   r    r!   c                   s6   dD ]}t | |tt| | qt jf i | d S )N>   get_moving_windowacquire_entryr(   r-   r0   r   r   r,      s    z%MovingWindowSupport.__init_subclass__r=   r>   r?   r2   r@   limitrA   rC   r   c                 C  s   t 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
        Nr:   r9   r@   rR   rA   rC   r   r   r   rP      s    z!MovingWindowSupport.acquire_entryztuple[float, int])r@   rR   rA   r   c                 C  s   t d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)
        Nr:   )r9   r@   rR   rA   r   r   r   rO      s    
z%MovingWindowSupport.get_moving_window)r=   )	rF   rG   rH   rI   r,   r   rP   rO   rL   r   r   r0   r   rN      s   	rN   c                      sZ   e Zd ZdZddd fddZeddd	d	d	d
dddZedd	ddddZ  ZS )SlidingWindowCounterSupportzr
    Abstract base class for storages that support
    the :ref:`strategies:sliding window counter` strategy.
    r   r    r!   c                   s6   dD ]}t | |tt| | qt jf i | d S )N>   acquire_sliding_window_entryget_sliding_windowr(   r-   r0   r   r   r,      s    z-SlidingWindowCounterSupport.__init_subclass__r=   r>   r?   r2   rQ   c                 C  s   t dS )aU  
        Acquire an entry if the weighted count of the current and previous
        windows is less than or equal to the limit

        :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
        Nr:   rS   r   r   r   rU      s    z8SlidingWindowCounterSupport.acquire_sliding_window_entryztuple[int, float, int, float])r@   rA   r   c                 C  s   t dS )a  
        Return the previous and current window information.

        :param key: the rate limit key
        :param expiry: the rate limit expiry, needed to compute the key in some implementations
        :return: a tuple of (int, float, int, float) with the following information:
          - previous window counter
          - previous window TTL
          - current window counter
          - current window TTL
        Nr:   )r9   r@   rA   r   r   r   rV      s    z.SlidingWindowCounterSupport.get_sliding_window)r=   )	rF   rG   rH   rI   r,   r   rU   rV   rL   r   r   r0   r   rT      s   	 rT   c                   @  s(   e Zd ZdZedddddddZd	S )
TimestampedSlidingWindowz\Helper class for storage that support the sliding window counter, with timestamp based keys.r>   r?   rE   ztuple[str, str])r@   rA   atr   c                 C  s0   | dt || |  | dt ||  fS )a-  
        returns the previous and the current window's keys.

        :param key: the key to get the window's keys from
        :param expiry: the expiry of the limit item, in seconds
        :param at: the timestamp to get the keys from. Default to now, ie ``time.time()``

        Returns a tuple with the previous and the current key: (previous, current).

        Example:
          - key = "mykey"
          - expiry = 60
          - at = 1738576292.6631825

        The return value will be the tuple ``("mykey/28976271", "mykey/28976270")``.
        /)r?   )r.   r@   rA   rX   r   r   r   sliding_window_keys   s    z,TimestampedSlidingWindow.sliding_window_keysN)rF   rG   rH   rI   classmethodrZ   r   r   r   r   rW      s   rW   )
__future__r   r   r5   abcr   r   Zlimitsr   Zlimits.storage.registryr   Zlimits.typingr   r   r	   r
   r   r   r   r   Zlimits.utilr   r   r   rN   rT   rW   r   r   r   r   <module>   s   (
])0