
    9i'*                        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 ddlmZ d	d
lmZmZmZ erd dlZ edd       G d deee             Zy)    )annotationsN)TYPE_CHECKINGcast)versionchanged)Version)LiteralRedisClient   )get_package_data   )MovingWindowSupportSlidingWindowCounterSupportStoragez4.3zlAdded support for using the redis client from :pypi:`valkey` if :paramref:`uri` has the ``valkey://`` schema)versionreasonc                      e Zd ZU dZg dZ	  ed       ed      dZdZ ee d      Z	 ee d      Z
 ee d	      Z ee d
      Z ee d      Z ee d      Zded<   ded<   ded<   ded<   dZded<   dedf	 	 	 	 	 	 	 	 	 	 	 d) fdZe	 	 d*d       Zd+dZd,d-dZd.dZd.dZd.dZd/dZ	 	 	 	 	 	 d0dZd1d Z	 d2	 	 	 	 	 	 	 d3d!Zd4d"Zd5d#Z	 d2	 	 	 	 	 	 	 	 	 d6d$Z	 d2	 	 	 	 	 	 	 	 	 d6d%Z d7d&Z!d8d'Z"d9d(Z# xZ$S ):RedisStoragez
    Rate limit storage with redis as backend.

    Depends on :pypi:`redis` (or :pypi:`valkey` if :paramref:`uri` starts with
    ``valkey://``)
    )redisredissz
redis+unixvalkeyvalkeyszvalkey+unixz3.0z6.0)r   r   zresources/redis/lua_scriptsz/moving_window.luaz/acquire_moving_window.luaz/clear_keys.luaz/incr_expire.luaz/sliding_window.luaz/acquire_sliding_window.luazredis.commands.core.Scriptlua_moving_windowlua_acquire_moving_windowlua_sliding_windowlua_acquire_sliding_windowLIMITSzLiteral['redis', 'valkey']target_serverNFc                   t        |   |fd|i| || _        |j                  d      rdnd| _        | j
                  | j                     j                  | _        |j                  | j                   dd      }|s# | j                  j                  |fi || _
        nV| j                  dk(  r$ | j                  j                  dd|i|| _
        n# | j                  j                  dd|i|| _
        | j                  |       y)	a  
        :param uri: uri of the form ``redis://[:password]@host:port``,
         ``redis://[:password]@host:port/db``,
         ``rediss://[:password]@host:port``, ``redis+unix:///path/to/sock`` etc.
         This uri is passed directly to :func:`redis.from_url` except for the
         case of ``redis+unix://`` where it is replaced with ``unix://``.

         If the uri scheme is ``valkey`` the implementation used will be from
         :pypi:`valkey`.
        :param connection_pool: if provided, the redis client is initialized with
         the connection pool and any other params passed as :paramref:`options`
        :param key_prefix: the prefix for each key created in redis
        :param wrap_exceptions: Whether to wrap storage exceptions in
         :exc:`limits.errors.StorageError` before raising it.
        :param options: all remaining keyword arguments are passed
         directly to the constructor of :class:`redis.Redis`
        :raise ConfigurationError: when the :pypi:`redis` library is not available
        wrap_exceptionsr   r   z+unixunixconnection_poolN )super__init__
key_prefix
startswithr   dependenciesmodule
dependencyreplacefrom_urlstorageRedisValkeyinitialize_storage)selfurir!   r%   r   options	__class__s         G/var/www/html/venv/lib/python3.12/site-packages/limits/storage/redis.pyr$   zRedisStorage.__init__C   s   4 	IoII$),)AXw++D,>,>?FFkkT//06?34??33CC7CDL!!W,4t44  $3 7>   6t55  $3 7>  	$    c                x    | j                   dk(  r| j                  j                  S | j                  j                  S )Nr   )r   r)   
RedisErrorValkeyErrorr0   s    r4   base_exceptionszRedisStorage.base_exceptionsq   s:     !!W, OO&&	
 ,,	
r5   c                ,   | j                         j                  | j                        | _        | j                         j                  | j                        | _        | j                         j                  | j                        | _        | j                         j                  | j                        | _	        | j                         j                  | j                        | _        | j                         j                  | j                        | _        y N)get_connectionregister_scriptSCRIPT_MOVING_WINDOWr   SCRIPT_ACQUIRE_MOVING_WINDOWr   SCRIPT_CLEAR_KEYSlua_clear_keysSCRIPT_INCR_EXPIRElua_incr_expireSCRIPT_SLIDING_WINDOWr   SCRIPT_ACQUIRE_SLIDING_WINDOWr   )r0   _uris     r4   r/   zRedisStorage.initialize_storage{   s    !%!4!4!6!F!F%%"
 *.)<)<)>)N)N--*
& #113CC""
  $224DD## 
 #'"5"5"7"G"G&&#
 +/*=*=*?*O*O..+
'r5   c                6    t        t        | j                        S r<   )r   r	   r,   )r0   readonlys     r4   r=   zRedisStorage.get_connection   s    K..r5   c                    d| dS )a  
        Return the current window's storage key (Sliding window strategy)

        Contrary to other strategies that have one key per rate limit item,
        this strategy has two keys per rate limit item than must be on the same machine.
        To keep the current key and the previous key on the same Redis cluster node,
        curly braces are added.

        Eg: "{constructed_key}"
        {}r"   r0   keys     r4   _current_window_keyz RedisStorage._current_window_key   s     C5|r5   c                *    | j                  |       dS )a%  
        Return the previous window's storage key (Sliding window strategy).

        Curvy braces are added on the common pattern with the current window's key,
        so the current and the previous key are stored on the same Redis cluster node.

        Eg: "{constructed_key}/-1"
        z/-1)rO   rM   s     r4   _previous_window_keyz!RedisStorage._previous_window_key   s     **3/044r5   c                $    | j                    d| S )N:)r%   rM   s     r4   prefixed_keyzRedisStorage.prefixed_key   s    //"!C5))r5   c                    | j                  |      }t        j                         }| j                  |g||z
  |g      x}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: (start of window, number of acquired entries)
        r   r   )rT   timer   float)r0   rN   limitexpiry	timestampwindows         r4   get_moving_windowzRedisStorage.get_moving_window   se     $IIK	++SEI4F3NOO6O#VAY..!|r5   c           
     r   | j                  | j                  |            }| j                  | j                  |            }| j                  ||g|g      x}r`t	        |d   xs d      t        dt        |d   xs d            dz  t	        |d   xs d      t        dt        |d   xs d            dz  fS y)Nr   r   i  r
      )r           r   r_   )rT   rQ   rO   r   intmaxrW   )r0   rN   rY   previous_keycurrent_keyr[   s         r4   get_sliding_windowzRedisStorage.get_sliding_window   s     (()B)B3)GH''(@(@(EF,,lK-H6(SS6SF1IN#AuVAY^!,-4F1IN#AuVAY^!,-4	  r5   c                    | j                  |      }| j                  |      }| j                  |       | j                  |       y r<   )rQ   rO   clear)r0   rN   rY   rb   rc   s        r4   clear_sliding_windowz!RedisStorage.clear_sliding_window   s:    005..s3

< 

;r5   c                `    | j                  |      }t        | j                  |g||g            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
        )rT   r`   rD   )r0   rN   rY   amounts       r4   incrzRedisStorage.incr   s3     $4''/?@AAr5   c                ~    | j                  |      }t        | j                  d      j                  |      xs d      S )zC

        :param key: the key to get the counter value for
        Tr   )rT   r`   r=   getrM   s     r4   rl   zRedisStorage.get   s:     $4&&t,005:;;r5   c                d    | j                  |      }| j                         j                  |       y)z>
        :param key: the key to clear rate limits for
        N)rT   r=   deleterM   s     r4   rf   zRedisStorage.clear   s+     $$$S)r5   c                    | j                  |      }t        j                         }| j                  |g||||g      }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

        :param amount: the number of entries to acquire
        )rT   rV   r   bool)r0   rN   rX   rY   ri   rZ   acquireds          r4   acquire_entryzRedisStorage.acquire_entry   sK     $IIK	11EIuff5
 H~r5   c                    | j                  | j                  |            }| j                  | j                  |            }| j                  ||g|||g      }t	        |      S )a0  
        Acquire an entry. Shift the current window to the previous window if it expired.

        :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
        )rT   rQ   rO   r   rp   )r0   rN   rX   rY   ri   rb   rc   rq   s           r4   acquire_sliding_window_entryz)RedisStorage.acquire_sliding_window_entry  sg     (()B)B3)GH''(@(@(EF22;'%)@
 H~r5   c                    | j                  |      }t        | j                  d      j                  |      d      t	        j                         z   S )z<
        :param key: the key to get the expiry for

        Tr   )rT   ra   r=   ttlrV   rM   s     r4   
get_expiryzRedisStorage.get_expiry  sB     $4&&t,005q9DIIKGGr5   c                N    	 | j                         j                         S #  Y yxY w)z-
        check if storage is healthy
        F)r=   pingr9   s    r4   checkzRedisStorage.check'  s)    	&&(--//	s     $c                Z    | j                  d      }t        | j                  |g            S )al  
        This function calls a Lua Script to delete keys prefixed with
        :paramref:`RedisStorage.key_prefix` in blocks of 5000.

        .. warning::
           This operation was designed to be fast, but was not tested
           on a large production based system. Be careful with its usage as it
           could be slow on very large data sets.

        *)rT   r`   rB   )r0   prefixs     r4   resetzRedisStorage.reset0  s,     ""3'4&&x011r5   )r1   strr!   z&redis.connection.ConnectionPool | Noner%   r   r   rp   r2   zfloat | str | boolreturnNone)r   z-type[Exception] | tuple[type[Exception], ...])rG   r   r   r   )F)rI   rp   r   r	   )rN   r   r   r   )rN   r   rX   r`   rY   r`   r   ztuple[float, int])rN   r   rY   r`   r   ztuple[int, float, int, float])rN   r   rY   r`   r   r   )r   )rN   r   rY   r`   ri   r`   r   r`   )rN   r   r   r`   )rN   r   r   r   )
rN   r   rX   r`   rY   r`   ri   r`   r   rp   )rN   r   r   rW   )r   rp   )r   z
int | None)%__name__
__module____qualname____doc__STORAGE_SCHEMEr   DEPENDENCIESRES_DIRr   r?   r@   rA   rC   rE   rF   __annotations__PREFIXr$   propertyr:   r/   r=   rO   rQ   rT   r\   rd   rg   rj   rl   rf   rr   rt   rw   rz   r~   __classcell__)r3   s   @r4   r   r      s6   N '$U^wu~FL+G+wi7I,JK#3)-.$  )G9O)DE)WI5E*FG,y8K-LM$4)./%! 219922 ::F--
 CG  %,%,% @,% 	,%
 ,% &,% 
,%\ 
	6
 

(/	5*  #	&  	BB B 	B
 
B"<*   	
  
6   	
  
,H2r5   r   )
__future__r   rV   typingr   r   deprecated.sphinxr   packaging.versionr   limits.typingr   r	   utilr   baser   r   r   r   r   r"   r5   r4   <module>r      sW    "  & , % . # K K 	;d27/1L d2d2r5   