
    i&<              
         d Z ddlmZ ddlZddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZmZ ej        rddlmZmZ g dZd)dZd*dZd+dZ G d dej        eej        ej        ee
f                  f         ej        e	                   Z G d dee	                   Z G d dee	                   Z G d d          Z G d d           Z G d! d"ee          Z G d# d$ee          Z  G d% d&ee          Z! G d' d(ee          Z"dS ),a  
requests.hooks
~~~~~~~~~~~~~~

This module provides the capabilities for the Requests hooks system.

Available hooks:

``pre_request``:
    The prepared request just got built. You may alter it prior to be sent through HTTP.
``pre_send``:
    The prepared request got his ConnectionInfo injected.
    This event is triggered just after picking a live connection from the pool.
``on_upload``:
    Permit to monitor the upload progress of passed body.
    This event is triggered each time a block of data is transmitted to the remote peer.
    Use this hook carefully as it may impact the overall performance.
``response``:
    The response generated from a Request.
    )annotationsN)MutableMapping   )_HVAsyncHookCallableTypeAsyncHookTypeHookCallableTypeHookType)PreparedRequestResponsepre_requestpre_send	on_uploadearly_responseresponsereturnHookType[_HV]c                 $    d t           D             S )Nc                    i | ]}|g S  r   ).0events     I/root/projects/butler/venv/lib/python3.11/site-packages/niquests/hooks.py
<dictcomp>z!default_hooks.<locals>.<dictcomp>3   s    )))%E2)))    )HOOKSr   r   r   default_hooksr   2   s    ))5))))r   keystrhooksHookType[_HV] | None	hook_datar   kwargs
typing.Anyc                    ||S |                     |           }|rAt          |          r|g}|D ],}	  ||fi |}n# t          $ r  ||          }Y nw xY w||}-|S )z6Dispatches a hook dictionary on a given piece of data.)getcallable	TypeErrorr   r!   r#   r$   	callableshook
_hook_datas          r   dispatch_hookr.   6   s    }49IIcNNI 	'I 	$"I 	' 	'D-!T)66v66

 - - -!T)__


-%&	s   	=AAAsyncHookType[_HV] | Nonec                N  K   ||S |                     |           }|rt          |          r|g}|D ]r}t          j        |          r2	  ||fi | d{V }nG# t          $ r  ||           d{V }Y n*w xY w	  ||fi |}n# t          $ r  ||          }Y nw xY w||}s|S )zEDispatches a hook dictionary on a given piece of data asynchronously.N)r'   r(   asyncioiscoroutinefunctionr)   r*   s          r   async_dispatch_hookr3   K   s2     }QVQZQZ[^Q_Q_I 'I 	$"I 	' 	'D*400 	17'+tI'@'@'@'@!@!@!@!@!@!@JJ  7 7 7'+tI!6!6!6!6!6!6JJJ71!%i!:!:6!:!:JJ  1 1 1!%iJJJ1 %&	s$   	AA76A7;	BBBc                  N    e Zd ZddZddZdd
ZddZddZd Zd Z	d Z
d ZdS )_BaseLifeCycleHookr   Nonec                     g g g g g d| _         d S Nr   _storeselfs    r   __init__z_BaseLifeCycleHook.__init__j   s%     f
 f
r   r   str | bytesvalue8list[HookCallableType[_HV] | AsyncHookCallableType[_HV]]c                     t          d          NzLifeCycleHook is Read OnlyNotImplementedError)r<   r   r?   s      r   __setitem__z_BaseLifeCycleHook.__setitem__s       !">???r   r    c                    | j         |         S Nr9   r<   r   s     r   __getitem__z_BaseLifeCycleHook.__getitem__v   s    {3r   c                    | |         S rH   r   rI   s     r   r'   z_BaseLifeCycleHook.gety   s    Cyr   c                    t          |t                    st          i }t                      }| j                                        D ]%\  }}|||<   ||xx         |j        |         z  cc<   &||_        |S rH   )
isinstancer5   r)   r:   items)r<   other	tmp_storecombined_hookshfnss         r   __add__z_BaseLifeCycleHook.__add__|   s    %!344 	O	2D2F2Fk'')) 	, 	,FAsIaLaLLLELO+LLLL )r   c              #  $   K   | j         E d {V  d S rH   r9   r;   s    r   __iter__z_BaseLifeCycleHook.__iter__   s&      ;r   c              #  ,   K   | D ]}|| |         fV  d S rH   r   rI   s     r   rN   z_BaseLifeCycleHook.items   s6       	! 	!CtCy.    	! 	!r   c                     t          d          rB   rC   rI   s     r   __delitem__z_BaseLifeCycleHook.__delitem__   rF   r   c                *    t          | j                  S rH   )lenr:   r;   s    r   __len__z_BaseLifeCycleHook.__len__   s    4;r   Nr   r6   )r   r>   r?   r@   r   r6   )r   r    r   r@   )r   r5   )__name__
__module____qualname__r=   rE   rJ   r'   rT   rV   rN   rY   r\   r   r   r   r5   r5   g   s        
 
 
 
@ @ @ @               ! ! !@ @ @         r   r5   c                  L     e Zd ZdZd fdZdd
ZddZddZddZddZ	 xZ
S )LifeCycleHookzP
    A sync-only middleware to be used in your request/response lifecycles.
    r   r6   c                    t                                                       | j                            | j        g| j        g| j        g| j        g| j        gd           d S r8   	superr=   r:   updater   r   r   r   r   r<   	__class__s    r   r=   zLifeCycleHook.__init__   o     $ 01!]O"n-#'#6"7!]O 	
 	
 	
 	
 	
r   prepared_requestr   r$   r%   PreparedRequest | Nonec                    dS zTThe prepared request just got built. You may alter it prior to be sent through HTTP.Nr   r<   rj   r$   s      r   r   zLifeCycleHook.pre_request       tr   c                    dS zThe prepared request got his ConnectionInfo injected. This event is triggered just
        after picking a live connection from the pool. You may not alter the prepared request.Nr   rn   s      r   r   zLifeCycleHook.pre_send   	     tr   c                    dS a  Permit to monitor the upload progress of passed body. This event is triggered each time
        a block of data is transmitted to the remote peer. Use this hook carefully as
        it may impact the overall performance. You may not alter the prepared request.Nr   rn   s      r   r   zLifeCycleHook.on_upload   s	     tr   r   r   c                    dS zAn early response caught before receiving the final Response for a given Request.
        Like but not limited to 103 Early Hints.Nr   r<   r   r$   s      r   r   zLifeCycleHook.early_response   rr   r   Response | Nonec                    dS zJThe response generated from a Request. You may alter the response at will.Nr   rw   s      r   r   zLifeCycleHook.response   ro   r   r]   rj   r   r$   r%   r   rk   rj   r   r$   r%   r   r6   r   r   r$   r%   r   r6   r   r   r$   r%   r   rx   r^   r_   r`   __doc__r=   r   r   r   r   r   __classcell__rh   s   @r   rb   rb               

 

 

 

 

 

      
      
       r   rb   c                  L     e Zd ZdZd fdZdd
ZddZddZddZddZ	 xZ
S )AsyncLifeCycleHookzR
    An async-only middleware to be used in your request/response lifecycles.
    r   r6   c                    t                                                       | j                            | j        g| j        g| j        g| j        g| j        gd           d S r8   rd   rg   s    r   r=   zAsyncLifeCycleHook.__init__   ri   r   rj   r   r$   r%   rk   c                
   K   dS rm   r   rn   s      r   r   zAsyncLifeCycleHook.pre_request         tr   c                
   K   dS rq   r   rn   s      r   r   zAsyncLifeCycleHook.pre_send          tr   c                
   K   dS rt   r   rn   s      r   r   zAsyncLifeCycleHook.on_upload   s       tr   r   r   c                
   K   dS rv   r   rw   s      r   r   z!AsyncLifeCycleHook.early_response   r   r   rx   c                
   K   dS rz   r   rw   s      r   r   zAsyncLifeCycleHook.response   r   r   r]   r{   r|   r}   r~   r   r   s   @r   r   r      r   r   r   c                  J    e Zd ZU dZded<   ded<   ded<   dd	Zdd
ZddZdS )_LeakyBucketMixinz$Shared leaky bucket algorithm logic.floatrateintervalfloat | Nonelast_requestr   r6   c                6    || _         d|z  | _        d | _        d S )N      ?)r   r   r   )r<   r   s     r   _init_leaky_bucketz$_LeakyBucketMixin._init_leaky_bucket   s"    	d
 r   c                h    t          j                    }| j        || j        z
  }| j        |z
  }nd}|S )zDCompute wait time and update state. Returns wait time (may be <= 0).Ng        )time	monotonicr   r   r<   nowelapsed	wait_times       r   _compute_waitz_LeakyBucketMixin._compute_wait   s>    n(D--G/IIIr   c                6    t          j                    | _        dS )zRecord that a request was made.N)r   r   r   r;   s    r   _record_requestz!_LeakyBucketMixin._record_request  s     N,,r   Nr   r   r   r6   )r   r   r]   )r^   r_   r`   r   __annotations__r   r   r   r   r   r   r   r      sv         ..KKKOOO! ! ! !
   - - - - - -r   r   c                  T    e Zd ZU dZded<   ded<   ded<   ded<   dd
ZddZddZdS )_TokenBucketMixinz$Shared token bucket algorithm logic.r   r   capacitytokenslast_updater   r   r6   c                r    || _         ||n|| _        | j        | _        t          j                    | _        d S rH   )r   r   r   r   r   r   )r<   r   r   s      r   _init_token_bucketz$_TokenBucketMixin._init_token_bucket  s8    	$,$8dm>++r   c                    t          j                    }|| j        z
  }t          | j        | j        || j        z  z             | _        || _        | j        dk    r| xj        dz  c_        dS d| j        z
  | j        z  }|S )zUReplenish tokens and try to acquire one. Returns wait time if needed, None otherwise.r   Nr   r   r   minr   r   r   r   s       r   _acquire_tokenz _TokenBucketMixin._acquire_token  s    n(($-w7J)JKK;#KK3KK4 t{*di7Ir   c                    t          j                    }|| j        z
  }t          | j        | j        || j        z  z             | _        || _        | xj        dz  c_        dS )z*Called after waiting to consume the token.r   Nr   )r<   r   r   s      r   
_post_waitz_TokenBucketMixin._post_wait%  sY    n(($-w7J)JKKsr   Nr   r   r   r   r   r6   )r   r   r]   )r^   r_   r`   r   r   r   r   r   r   r   r   r   r     s         ..KKKOOOMMM, , , ,        r   r   c                  .     e Zd ZdZdd fdZddZ xZS )LeakyBucketLimiterap  Rate limiter using the leaky bucket algorithm.

    Requests "leak" out at a constant rate. When a request arrives, it waits
    until enough time has passed since the last request to maintain the rate.

    Usage::

        limiter = LeakyBucketLimiter(rate=10.0)  # 10 requests per second
        with niquests.Session(hooks=limiter) as session:
            ...
          $@r   r   r   r6   c                    t                                                       |                     |           t          j                    | _        dS zjInitialize the leaky bucket limiter.

        Args:
            rate: Maximum requests per second
        N)re   r=   r   	threadingLock_lockr<   r   rh   s     r   r=   zLeakyBucketLimiter.__init__=  sB     	%%%^%%


r   rj   r   r$   r%   rk   c                    | j         5  |                                 }|dk    rt          j        |           |                                  ddd           n# 1 swxY w Y   dS )*Wait if needed to maintain the rate limit.r   N)r   r   r   sleepr   r<   rj   r$   r   s       r   r   zLeakyBucketLimiter.pre_requestG  s    Z 	# 	#**,,I1}}
9%%%  """		# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#
 ts   AAAAr   r   r{   r^   r_   r`   r   r=   r   r   r   s   @r   r   r   0  s`        
 
& & & & & & &       r   r   c                  .     e Zd ZdZdd fdZddZ xZS )AsyncLeakyBucketLimitera  Rate limiter using the leaky bucket algorithm.

    Requests "leak" out at a constant rate. When a request arrives, it waits
    until enough time has passed since the last request to maintain the rate.

    Usage::

        limiter = AsyncLeakyBucketLimiter(rate=10.0)  # 10 requests per second
        async with niquests.AsyncSession(hooks=limiter) as session:
            ...
    r   r   r   r   r6   c                    t                                                       |                     |           t          j                    | _        dS r   )re   r=   r   r1   r   r   r   s     r   r=   z AsyncLeakyBucketLimiter.__init__^  s@     	%%%\^^


r   rj   r   r$   r%   rk   c                   K   | j         4 d{V  |                                 }|dk    rt          j        |           d{V  |                                  ddd          d{V  n# 1 d{V swxY w Y   dS )r   Nr   )r   r   r1   r   r   r   s       r   r   z#AsyncLeakyBucketLimiter.pre_requesth  s     : 	# 	# 	# 	# 	# 	# 	# 	#**,,I1}}mI.........  """		# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#
 ts   A	A++
A58A5r   r   r{   r   r   s   @r   r   r   Q  s`        
 
$ $ $ $ $ $ $       r   r   c                  .     e Zd ZdZdd fd
ZddZ xZS )TokenBucketLimitera{  Rate limiter using the token bucket algorithm.

    Tokens are added to a bucket at a constant rate up to a maximum capacity.
    Each request consumes one token. Allows bursts up to the bucket capacity.

    Usage::

        limiter = TokenBucketLimiter(rate=10.0, capacity=50.0)  # 10/s, burst of 50
        with niquests.Session(hooks=limiter) as session:
            ...
    r   Nr   r   r   r   r   r6   c                    t                                                       |                     ||           t          j                    | _        dS zInitialize the token bucket limiter.

        Args:
            rate: Token replenishment rate (tokens per second)
            capacity: Maximum bucket capacity (defaults to rate, allowing 1 second burst)
        N)re   r=   r   r   r   r   r<   r   r   rh   s      r   r=   zTokenBucketLimiter.__init__  sD     	h///^%%


r   rj   r   r$   r%   rk   c                    | j         5  |                                 }|(t          j        |           |                                  ddd           n# 1 swxY w Y   dS z1Wait until a token is available, then consume it.N)r   r   r   r   r   r   s       r   r   zTokenBucketLimiter.pre_request  s    Z 	" 	"++--I$
9%%%!!!		" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	"
 ts   ?AAAr   Nr   r{   r   r   s   @r   r   r   r  s`        
 
	& 	& 	& 	& 	& 	& 	&       r   r   c                  .     e Zd ZdZdd fd
ZddZ xZS )AsyncTokenBucketLimitera  Rate limiter using the token bucket algorithm.

    Tokens are added to a bucket at a constant rate up to a maximum capacity.
    Each request consumes one token. Allows bursts up to the bucket capacity.

    Usage::

        limiter = AsyncTokenBucketLimiter(rate=10.0, capacity=50.0)  # 10/s, burst of 50
        async with niquests.AsyncSession(hooks=limiter) as session:
            ...
    r   Nr   r   r   r   r   r6   c                    t                                                       |                     ||           t          j                    | _        dS r   )re   r=   r   r1   r   r   r   s      r   r=   z AsyncTokenBucketLimiter.__init__  sB     	h///\^^


r   rj   r   r$   r%   rk   c                   K   | j         4 d{V  |                                 }|.t          j        |           d{V  |                                  ddd          d{V  n# 1 d{V swxY w Y   dS r   )r   r   r1   r   r   r   s       r   r   z#AsyncTokenBucketLimiter.pre_request  s     : 	" 	" 	" 	" 	" 	" 	" 	"++--I$mI.........!!!		" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	"
 ts   AA''
A14A1r   r   r{   r   r   s   @r   r   r     s`        
 
	$ 	$ 	$ 	$ 	$ 	$ 	$       r   r   )r   r   )
r   r    r!   r"   r#   r   r$   r%   r   r   )
r   r    r!   r/   r#   r   r$   r%   r   r   )#r   
__future__r   r1   r   r   typingcollections.abcr   r   r   r   r	   r
   TYPE_CHECKINGmodelsr   r   r   r   r.   r3   r    ListUnionGenericr5   rb   r   r   r   r   r   r   r   r   r   r   <module>r      s   * # " " " " "        * * * * * *              
 211111111	 	 	* * * *   *   8/  /  /  /  / 
#v{6<8HJ_8_+`aabdjdrsvdw/  /  / d' ' ' ' '&s+ ' ' 'T' ' ' ' '+C0 ' ' 'T- - - - - - - -6% % % % % % % %P    *M   B    /1C   B    *M   D    /1C     r   