
    Nwg                         d Z ddlZddlmZ ddlmZ ddlmZ  G d d      Z	 G d d	e	      Z
 G d
 de
      Z G d de
      Z G d de
      Zy)z'
Provides various throttling policies.
    N)cache)ImproperlyConfigured)api_settingsc                   "    e Zd ZdZd Zd Zd Zy)BaseThrottlez&
    Rate throttling of requests.
    c                     t        d      )zT
        Return `True` if the request should be allowed, `False` otherwise.
        z#.allow_request() must be overriddenNotImplementedErrorselfrequestviews      P/var/www/horilla/myenv/lib/python3.12/site-packages/rest_framework/throttling.pyallow_requestzBaseThrottle.allow_request   s     ""GHH    c                 ^   |j                   j                  d      }|j                   j                  d      }t        j                  }|C|dk(  s||S |j	                  d      }|t        |t        |                }|j                         S |rdj                  |j	                               S |S )z
        Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR
        if present and number of proxies is > 0. If not use all of
        HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.
        HTTP_X_FORWARDED_FORREMOTE_ADDRr   , )	METAgetr   NUM_PROXIESsplitminlenstripjoin)r   r   xffremote_addrnum_proxiesaddrsclient_addrs          r   	get_identzBaseThrottle.get_ident   s     ll56ll&&}5".."a3;""IIcNE[#e*!= =>K$$&&'*rwwsyy{#;;r   c                      y)zm
        Optionally, return a recommended number of seconds to wait before
        the next request.
        N r   s    r   waitzBaseThrottle.wait*   s    
 r   N)__name__
__module____qualname____doc__r   r$   r(   r&   r   r   r   r      s    I<&r   r   c                   |    e Zd ZdZeZej                  ZdZdZ	e
j                  Zd Zd Zd Zd Zd Zd	 Zd
 Zd Zy)SimpleRateThrottlea  
    A simple cache implementation, that only requires `.get_cache_key()`
    to be overridden.

    The rate (requests / seconds) is set by a `rate` attribute on the Throttle
    class.  The attribute is a string of the form 'number_of_requests/period'.

    Period should be one of: ('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day')

    Previous request information used for throttling is stored in the cache.
    zthrottle_%(scope)s_%(ident)sNc                     t        | dd       s| j                         | _        | j                  | j                        \  | _        | _        y )Nrate)getattrget_rater0   
parse_ratenum_requestsdurationr'   s    r   __init__zSimpleRateThrottle.__init__D   s7    tVT*DI+/??499+E(4=r   c                     t        d      )z
        Should return a unique cache-key which can be used for throttling.
        Must be overridden.

        May return `None` if the request should not be throttled.
        z#.get_cache_key() must be overriddenr	   r   s      r   get_cache_keyz SimpleRateThrottle.get_cache_keyI   s     ""GHHr   c                     t        | dd      s$d| j                  j                  z  }t        |      	 | j                  | j
                     S # t        $ r d| j
                  z  }t        |      w xY w)zR
        Determine the string representation of the allowed request rate.
        scopeNz9You must set either `.scope` or `.rate` for '%s' throttlez+No default throttle rate set for '%s' scope)r1   	__class__r)   r   THROTTLE_RATESr:   KeyError)r   msgs     r   r2   zSimpleRateThrottle.get_rateR   st     tWd+N>>**+C&s++	,&&tzz22 	,?$**LC&s++	,s   A $A0c                 h    |y|j                  d      \  }}t        |      }ddddd|d      }||fS )	z
        Given the request rate string, return a two tuple of:
        <allowed number of requests>, <period of time in seconds>
        )NN/   <   i  iQ )smhdr   )r   int)r   r0   numperiodr4   r5   s         r   r3   zSimpleRateThrottle.parse_ratea   sH    
 <jjoV3x$U;F1IFh''r   c                 r   | j                   y| j                  ||      | _        | j                  y| j                  j	                  | j                  g       | _        | j                         | _        | j
                  ry| j
                  d   | j                  | j                  z
  k  rP| j
                  j                          | j
                  r*| j
                  d   | j                  | j                  z
  k  rPt        | j
                        | j                  k\  r| j                         S | j                         S )z
        Implement the check to see if the request should be throttled.

        On success calls `throttle_success`.
        On failure calls `throttle_failure`.
        T)r0   r8   keyr   r   historytimernowr5   popr   r4   throttle_failurethrottle_successr   s      r   r   z SimpleRateThrottle.allow_requestm   s     99%%gt488zz~~dhh3::< llt||B/488dmm3KKLL llt||B/488dmm3KKt|| 1 11((**$$&&r   c                     | j                   j                  d| j                         | j                  j	                  | j
                  | j                   | j                         y)zd
        Inserts the current request's timestamp along with the key
        into the cache.
        r   T)rM   insertrO   r   setrL   r5   r'   s    r   rR   z#SimpleRateThrottle.throttle_success   s?    
 	Atxx(

txxt}}=r   c                      y)zP
        Called when a request to the API has failed due to throttling.
        Fr&   r'   s    r   rQ   z#SimpleRateThrottle.throttle_failure   s     r   c                     | j                   r*| j                  | j                  | j                   d   z
  z
  }n| j                  }| j                  t	        | j                         z
  dz   }|dk  ry|t        |      z  S )zG
        Returns the recommended next request time in seconds.
        rK   rA   r   N)rM   r5   rO   r4   r   float)r   remaining_durationavailable_requestss      r   r(   zSimpleRateThrottle.wait   sq     <<!%$((T\\"=M2M!N!%!..T\\1BBQF"!E*<$===r   )r)   r*   r+   r,   default_cacher   timerN   cache_formatr:   r   DEFAULT_THROTTLE_RATESr<   r6   r8   r2   r3   r   rR   rQ   r(   r&   r   r   r.   r.   2   sV    
 EIIE1LE!88NF
I,
('2>r   r.   c                       e Zd ZdZdZd Zy)AnonRateThrottlez
    Limits the rate of API calls that may be made by a anonymous users.

    The IP address of the request will be used as the unique cache key.
    anonc                     |j                   r|j                   j                  ry | j                  | j                  | j	                  |      dz  S Nr:   ident)useris_authenticatedr]   r:   r$   r   s      r   r8   zAnonRateThrottle.get_cache_key   sC    <<GLL99  ZZ^^G,$
 
 	
r   Nr)   r*   r+   r,   r:   r8   r&   r   r   r`   r`      s    
 E
r   r`   c                       e Zd ZdZdZd Zy)UserRateThrottlez
    Limits the rate of API calls that may be made by a given user.

    The user id will be used as a unique cache key if the user is
    authenticated.  For anonymous requests, the IP address of the request will
    be used.
    rf   c                     |j                   r-|j                   j                  r|j                   j                  }n| j                  |      }| j                  | j
                  |dz  S rc   rf   rg   pkr$   r]   r:   r   r   r   re   s       r   r8   zUserRateThrottle.get_cache_key   sR    <<GLL99LLOOENN7+E  ZZ$
 
 	
r   Nrh   r&   r   r   rj   rj      s     E	
r   rj   c                   2     e Zd ZdZdZd Z fdZd Z xZS )ScopedRateThrottlea,  
    Limits the rate of API calls by different amounts for various parts of
    the API.  Any view that has the `throttle_scope` property set will be
    throttled.  The unique cache key will be generated by concatenating the
    user id of the request, and the scope of the view being accessed.
    throttle_scopec                      y )Nr&   r'   s    r   r6   zScopedRateThrottle.__init__   s     	r   c                     t        || j                  d       | _        | j                  sy| j                         | _        | j                  | j                        \  | _        | _        t        | %  ||      S )NT)
r1   
scope_attrr:   r2   r0   r3   r4   r5   superr   )r   r   r   r;   s      r   r   z ScopedRateThrottle.allow_request   sb    T4??D9
 zz MMO	+/??499+E(4= w$Wd33r   c                     |j                   r-|j                   j                  r|j                   j                  }n| j                  |      }| j                  | j
                  |dz  S )z
        If `view.throttle_scope` is not set, don't apply this throttle.

        Otherwise generate the unique cache key by concatenating the user id
        with the `.throttle_scope` property of the view.
        rd   rl   rn   s       r   r8   z ScopedRateThrottle.get_cache_key   sT     <<GLL99LLOOENN7+E  ZZ$
 
 	
r   )	r)   r*   r+   r,   rt   r6   r   r8   __classcell__)r;   s   @r   rp   rp      s     "J
4 
r   rp   )r,   r\   django.core.cacher   r[   django.core.exceptionsr   rest_framework.settingsr   r   r.   r`   rj   rp   r&   r   r   <module>r{      sY     4 7 0# #Lp> p>f
) 
$
) 
,-
+ -
r   