o
    ;hv                      @  sl   d dl m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 er,d dlZG dd deZdS )	    )annotationsN)TYPE_CHECKINGcast)RedisBridge)ConfigurationError)AsyncRedisClientCallablec                   @  s  e Zd ZU ddiZded< 	 edLddZdMddZdNddZdNddZ	ded< ded< ded< ded< ded< ded< ded < dOdPd$d%Z
dQd&d'Z	(dRdSd.d/ZdTd0d1ZdUd2d3ZdVd5d6ZdWd9d:ZdXd>d?Z	(dRdYd@dAZ	(dRdZdBdCZd[dEdFZd\dGdHZdVdIdJZdKS )]RedispyBridgeZmax_connections  zdict[str, float | str | bool]DEFAULT_CLUSTER_OPTIONSreturn-type[Exception] | tuple[type[Exception], ...]c                 C  s
   | j jfS N)
dependencyZ
RedisErrorself r   S/var/www/html/venv/lib/python3.10/site-packages/limits/aio/storage/redis/redispy.pybase_exceptions   s   
zRedispyBridge.base_exceptionsservice_name
str | Noneuse_replicasboolsentinel_kwargs$dict[str, str | float | bool] | Noneoptionsstr | float | boolNonec                   s   g }|  } jjdd } jj|d  dD ]}|d\}	}
||	t|
f q jjr9 jjddn|}|d u rCt	d j
jj|fdi  j|pQi 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_sentinelc                   sZ   | dd  }r jjjdd|i| _n jjjj jfi | _ fdd _d S )Nconnection_poolc                       j S r   r%   _r   r   r   r)   D       z)RedispyBridge.use_basic.<locals>.<lambda>r   )popr   r3   ZRedisr%   Zfrom_urlurir6   )r   r   r<   r   r   r   	use_basic<   s   
zRedispyBridge.use_basicc                   s    j jdd }g } j j|d  dD ]}|d\}}| jjjj|t	|d q jjj
d	d|ii  j j| _ fdd _d S )
Nr   r   r    r!   )r9   r:   Zstartup_nodesc                   r=   r   r>   r?   r   r   r   r)   T   rA   z+RedispyBridge.use_cluster.<locals>.<lambda>r   )r+   r,   r-   r.   r/   r   r3   clusterZClusterNoder0   RedisClusterr   r4   r%   r6   )r   r   r7   Zcluster_hostsr8   r9   r:   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]r6   Fr'   r   c                 C  s
   |  |S r   )r6   )r   r'   r   r   r   get_connection^   s   
zRedispyBridge.get_connectionc                 C  sp   |   | j| _|   | j| _|   | j| _|   | j| _	|   | j
| _|   | j| _d S r   )rN   Zregister_scriptZSCRIPT_MOVING_WINDOWrH   ZSCRIPT_ACQUIRE_MOVING_WINDOWrI   ZSCRIPT_CLEAR_KEYSrL   ZSCRIPT_INCR_EXPIRErM   ZSCRIPT_SLIDING_WINDOWrJ   ZSCRIPT_ACQUIRE_SLIDING_WINDOWrK   r   r   r   r   register_scriptsa   s$   
zRedispyBridge.register_scriptsr   keystrexpiryr0   amountc                   s*   |  |}tt| |g||gI dH 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_keyr   r0   rM   )r   rP   rR   rS   r   r   r   incrv   s   
zRedispyBridge.incrc                   s,   |  |}t| jdd|I dH pdS )zC

        :param key: the key to get the counter value for
        Tr&   Nr   )rT   r0   rN   getr   rP   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)rT   rN   deleterW   r   r   r   clear   s   
zRedispyBridge.clear
int | Nonec                   s    t t| | dgI d H S )N*)r   r0   rL   rT   r   r   r   r   	lua_reset   s   zRedispyBridge.lua_resetlimittuple[float, int]c                   sP   |  |}t }| |g|| |gI dH }|r$t|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   )rT   timerH   float)r   rP   r]   rR   	timestampwindowr   r   r   get_moving_window   s   
zRedispyBridge.get_moving_windowprevious_keycurrent_keytuple[int, float, int, float]c                   s~   |  | || |g|gI d H  }r=t|d pdtdt|d p$dd t|d p.dtdt|d p7dd fS dS )Nr   r   r
         )r           r   ri   )rJ   rT   r0   maxr`   )r   rd   re   rR   rb   r   r   r   get_sliding_window   s   z RedispyBridge.get_sliding_windowc                   s8   |  |}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)rT   r_   rI   r   )r   rP   r]   rR   rS   ra   acquiredr   r   r   acquire_entry   s   

zRedispyBridge.acquire_entryc                   s:   |  |}|  |}| ||g|||gI d H }t|S r   )rT   rK   r   )r   rd   re   r]   rR   rS   rl   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   )rT   rj   rN   ttlr_   rW   r   r   r   
get_expiry   s   
"zRedispyBridge.get_expiryc                   s(   z|    I dH  W dS    Y dS )z-
        check if storage is healthy
        NTF)rN   Zpingr   r   r   r   check   s   zRedispyBridge.checkc                   sT   |  d}| jj|| jjjjjdI d H }d}|D ]}|| j|I d H 7 }q|S )Nr[   )Ztarget_nodesr   )	rT   r%   keysr   r3   rE   rF   Z	ALL_NODESrX   )r   prefixrr   countrP   r   r   r   reset   s   
zRedispyBridge.resetN)r   r   )
r   r   r   r   r   r   r   r   r   r   )r   r   r   r   )F)r'   r   r   r   )r   r   )r   )rP   rQ   rR   r0   rS   r0   r   r0   )rP   rQ   r   r0   )rP   rQ   r   r   )r   rZ   )rP   rQ   r]   r0   rR   r0   r   r^   )rd   rQ   re   rQ   rR   r0   r   rf   )
rP   rQ   r]   r0   rR   r0   rS   r0   r   r   )rd   rQ   re   rQ   r]   r0   rR   r0   rS   r0   r   r   )rP   rQ   r   r`   )r   r   )__name__
__module____qualname__r   __annotations__propertyr   r;   rD   rG   rN   rO   rU   rV   rY   r\   rc   rk   rm   rn   rp   rq   ru   r   r   r   r   r	      s@   
 

$




	




r	   )
__future__r   r_   typingr   r   Zlimits.aio.storage.redis.bridger   Zlimits.errorsr   Zlimits.typingr   r   Zredis.commandsZredisr	   r   r   r   r   <module>   s    