a
    a*j!                     @  sx   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
 d dlmZmZmZmZ erdd dlZG dd deZdS )	    )annotationsN)TYPE_CHECKINGTypecast)RedisBridge)ConfigurationError)AsyncRedisClientCallableOptionalUnionc                   @  s  e Zd ZU ddiZded< eddddZd	d
ddddddZdddddZdddddZ	ded< ded< ded< ded< ded< ded< ded< dJd
d d!d"d#Z
ddd$d%ZdKd'd(d
d(d(d)d*d+Zd'd(d,d-d.Zd'dd,d/d0Zd1dd2d3Zd'd(d(d4d5d6d7Zd'd'd(d8d9d:d;ZdLd'd(d(d(d
d<d=d>ZdMd'd'd(d(d(d
d?d@dAZd'dBd,dCdDZd
ddEdFZd1ddGdHZdIS )NRedispyBridgeZmax_connections  z"dict[str, Union[float, str, bool]]DEFAULT_CLUSTER_OPTIONSz3Union[Type[Exception], tuple[Type[Exception], ...]])returnc                 C  s
   | j jfS N)
dependencyZ
RedisErrorself r   \/var/www/html/assistant/venv/lib/python3.9/site-packages/limits/aio/storage/redis/redispy.pybase_exceptions   s    zRedispyBridge.base_exceptionszOptional[str]boolz,Optional[dict[str, Union[str, float, bool]]]zUnion[str, float, bool]None)service_nameuse_replicassentinel_kwargsoptionsr   c                   s   g }|  } jjdd } jj|d  dD ]$}|d\}	}
||	t|
f q4 jjrr jjddn|}|d u rt	d j
jj|fdi  j|pi ii  j| _ j| _ j| _ fd	d
 _d S )N@   ,:/ z'service_name' not providedr   c                   s   | rr j S  jS r   )storage_replicastoragereadonlyr   r   r   r   <lambda>8   s    z,RedispyBridge.use_sentinel.<locals>.<lambda>)copy
parsed_urinetlocfindsplitappendintpathreplacer   r   asyncioZSentinelparsed_authsentinelZ
master_forr$   Z	slave_forr#   connection_getter)r   r   r   r   r   Zsentinel_configurationZconnection_optionsseplochostportr   r'   r   use_sentinel   s,    zRedispyBridge.use_sentinel)r   r   c                   sZ   | dd  }r, jjjf d|i| _n jjjj jfi | _ fdd _d S )Nconnection_poolc                   s    j S r   r$   _r   r   r   r(   D       z)RedispyBridge.use_basic.<locals>.<lambda>)popr   r2   ZRedisr$   Zfrom_urlurir5   )r   r   r;   r   r   r   	use_basic<   s    
zRedispyBridge.use_basicc                   s    j jdd }g } j j|d  dD ]0}|d\}}| jjjj|t	|d q, jjj
f d|ii  j j| _ fdd _d S )	Nr   r   r   r    )r8   r9   Zstartup_nodesc                   s    j S r   r<   r=   r   r   r   r(   T   r?   z+RedispyBridge.use_cluster.<locals>.<lambda>)r*   r+   r,   r-   r.   r   r2   clusterZClusterNoder/   RedisClusterr   r3   r$   r5   )r   r   r6   Zcluster_hostsr7   r8   r9   r   r   r   use_clusterF   s    zRedispyBridge.use_clusterz'redis.commands.core.Script'lua_moving_windowlua_acquire_moving_windowlua_sliding_windowlua_acquire_sliding_windowlua_clear_keyslua_incr_expirez"Callable[[bool], AsyncRedisClient]r5   Fr   )r&   r   c                 C  s
   |  |S r   )r5   )r   r&   r   r   r   get_connection^   s    zRedispyBridge.get_connectionc                 C  sp   |   | j| _|   | j| _|   | j| _|   | j| _	|   | j
| _|   | j| _d S r   )rL   Zregister_scriptZSCRIPT_MOVING_WINDOWrF   ZSCRIPT_ACQUIRE_MOVING_WINDOWrG   ZSCRIPT_CLEAR_KEYSrJ   ZSCRIPT_INCR_EXPIRErK   ZSCRIPT_SLIDING_WINDOWrH   ZSCRIPT_ACQUIRE_SLIDING_WINDOWrI   r   r   r   r   register_scriptsa   s$    zRedispyBridge.register_scriptsr   strr/   )keyexpiryelastic_expiryamountr   c                   s`   |  |}|r>|  ||I dH }|  ||I dH  |S tt| |g||gI dH S 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
        N)prefixed_keyrL   ZincrbyZexpirer   r/   rK   )r   rO   rP   rQ   rR   valuer   r   r   incrv   s    
zRedispyBridge.incr)rO   r   c                   s*   |  |}t| jdd|I dH p&dS )zC

        :param key: the key to get the counter value for
        Tr%   Nr   )rS   r/   rL   getr   rO   r   r   r   rV      s    
zRedispyBridge.getc                   s"   |  |}|  |I dH  dS )z?
        :param key: the key to clear rate limits for

        N)rS   rL   deleterW   r   r   r   clear   s    
zRedispyBridge.clearzOptional[int]c                   s   t t| | dgI d H S )N*)r   r/   rJ   rS   r   r   r   r   	lua_reset   s    zRedispyBridge.lua_resetztuple[float, int])rO   limitrP   r   c                   sN   |  |}t }| |g|| |gI dH }|rFt|d |d 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: (previous count, previous TTL, current count, current TTL)
        Nr   r   )rS   timerF   float)r   rO   r\   rP   	timestampwindowr   r   r   get_moving_window   s    
zRedispyBridge.get_moving_windowztuple[int, float, int, float])previous_keycurrent_keyrP   r   c                   s|   |  | || |g|gI d H  }rxt|d p4dtdt|d pFdd t|d pZdtdt|d pldd fS dS )Nr   r   r         )r           r   rf   )rH   rS   r/   maxr^   )r   rb   rc   rP   r`   r   r   r   get_sliding_window   s    z RedispyBridge.get_sliding_window)rO   r\   rP   rR   r   c                   s6   |  |}t }| |g||||gI dH }t|S )z
        :param key: rate limit key to acquire an entry in
        :param limit: amount of entries allowed
        :param expiry: expiry of the entry

        N)rS   r]   rG   r   )r   rO   r\   rP   rR   r_   acquiredr   r   r   acquire_entry   s    

zRedispyBridge.acquire_entry)rb   rc   r\   rP   rR   r   c                   s8   |  |}|  |}| ||g|||gI d H }t|S r   )rS   rI   r   )r   rb   rc   r\   rP   rR   ri   r   r   r   acquire_sliding_window_entry   s    


z*RedispyBridge.acquire_sliding_window_entryr^   c                   s,   |  |}t|  |I dH dt  S )z;
        :param key: the key to get the expiry for
        Nr   )rS   rg   rL   ttlr]   rW   r   r   r   
get_expiry   s    
zRedispyBridge.get_expiryc                   s,   z|    I dH  W dS    Y dS 0 dS )z-
        check if storage is healthy
        NTF)rL   Zpingr   r   r   r   check   s
    zRedispyBridge.checkc                   sR   |  d}| jj|| jjjjjdI d H }d}|D ]}|| j|I d H 7 }q2|S )NrZ   )Ztarget_nodesr   )	rS   r$   keysr   r2   rC   rD   Z	ALL_NODESrX   )r   prefixro   countrO   r   r   r   reset   s    
zRedispyBridge.resetN)F)Fr   )r   )r   )__name__
__module____qualname__r   __annotations__propertyr   r:   rB   rE   rL   rM   rU   rV   rY   r[   ra   rh   rj   rk   rm   rn   rr   r   r   r   r   r      s>   
$
  	  r   )
__future__r   r]   typingr   r   r   Zlimits.aio.storage.redis.bridger   Zlimits.errorsr   Zlimits.typingr   r	   r
   r   Zredis.commandsZredisr   r   r   r   r   <module>   s   