U
    ^g)                     @  s   d dl mZ d dlZd dlZd dlmZmZmZmZm	Z	 d dl
Z
d dlmZ ddlmZ ddlmZ ddlmZmZ G d	d
 d
ZdS )    )annotationsN)DictIterableListOptionalTuple)
OrderedSet   )ExemptionScope)get_qualified_name)Limit
LimitGroupc                	   @  s<  e Zd ZddddddddddZedd	d
dZedd	ddZdddddZdddddZd>dddddddZ	ddddddZ
dddddd Zdddd!d"d#Zdddd$d%d&Zddd'd(d)Zd?d+d,d,d,ddd-d.d/d0Zd+d,d,dd1d2d3Zddd4d5d6Zd+ddd7d8d9Zd+dd:d;d<d=Zd*S )@LimitManagerzList[LimitGroup]z!Dict[str, OrderedSet[LimitGroup]]zDict[str, ExemptionScope]None)application_limitsdefault_limitsdecorated_limitsblueprint_limitsroute_exemptionsblueprint_exemptionsreturnc                 C  s:   || _ || _|| _|| _|| _|| _i | _td| _	d S )Nzflask-limiter)
_application_limits_default_limits_decorated_limits_blueprint_limits_route_exemptions_blueprint_exemptions_endpoint_hintslogging	getLogger_logger)selfr   r   r   r   r   r    r"   9/tmp/pip-unpacked-wheel-8ut481ky/flask_limiter/manager.py__init__   s    	zLimitManager.__init__zList[Limit])r   c                 C  s   t tj| j S N)list	itertoolschainr   r!   r"   r"   r#   r   "   s    zLimitManager.application_limitsc                 C  s   t tj| j S r%   )r&   r'   r(   r   r)   r"   r"   r#   r   &   s    zLimitManager.default_limits)limitsr   c                 C  s
   || _ d S r%   )r   r!   r*   r"   r"   r#   set_application_limits*   s    z#LimitManager.set_application_limitsc                 C  s
   || _ d S r%   )r   r+   r"   r"   r#   set_default_limits-   s    zLimitManager.set_default_limitsFstrzOptional[LimitGroup]bool)routelimitoverrider   c                 C  s4   |r0|s | j |t | nt|g| j |< d S r%   )r   
setdefaultr   add)r!   r0   r1   r2   r"   r"   r#   add_decorated_limit0   s    z LimitManager.add_decorated_limit)	blueprintr1   r   c                 C  s   |r| j |t | d S r%   )r   r3   r   r4   )r!   r6   r1   r"   r"   r#   add_blueprint_limit9   s    z LimitManager.add_blueprint_limitr
   )r0   scoper   c                 C  s   || j |< d S r%   )r   )r!   r0   r8   r"   r"   r#   add_route_exemption=   s    z LimitManager.add_route_exemption)r6   r8   r   c                 C  s   || j |< d S r%   )r   )r!   r6   r8   r"   r"   r#   add_blueprint_exemption@   s    z$LimitManager.add_blueprint_exemption)endpointcallabler   c                 C  s   | j |t | d S r%   )r   r3   r   r4   )r!   r;   r<   r"   r"   r#   add_endpoint_hintC   s    zLimitManager.add_endpoint_hint)r;   r   c                 C  s   t | j|S r%   )r/   r   get)r!   r;   r"   r"   r#   	has_hintsF   s    zLimitManager.has_hintsNzflask.FlaskzOptional[str]zTuple[List[Limit], ...])appr;   r6   callable_namein_middlewaremarked_for_limitingr   c                 C  sB  |o|}g }g }	|rv|sP|s<|j |d }
|
r6t|
nd}n|}|| | | j|t D ]}|	| | q`|r|s|rtdd |D r|| || | 	|||}|r|t
j@ s| jng }tdd |D }tdd |D }|	rtdd |	D nd}|s|r*|s*|t
j@ r0|r:|| j7 }||fS )N c                 s  s   | ]}|j  V  qd S r%   override_defaults.0r1   r"   r"   r#   	<genexpr>d   s     z.LimitManager.resolve_limits.<locals>.<genexpr>c                 s  s   | ]}|j V  qd S r%   )Zmethod_exemptrG   r"   r"   r#   rI   o   s     c                 s  s   | ]}|j  V  qd S r%   rE   rG   r"   r"   r#   rI   t   s    c                 s  s   | ]}|j  V  qd S r%   rE   rG   r"   r"   r#   rI   |   s     F)view_functionsr>   r   extendr   r   r   allr   exemption_scoper
   APPLICATIONr   DEFAULTr   )r!   r@   r;   r6   rA   rB   rC   Zbefore_request_contextr   Zhinted_limits	view_funcnamehintrM   Z
all_limitsZexplicit_limits_exemptZcombined_defaultsZhinted_limits_request_defaultsr"   r"   r#   resolve_limitsI   s\    		
zLimitManager.resolve_limits)r@   r;   r6   r   c                 C  s   |j |pdd }|rt|nd}| j|tj}|rB|j|nd }|sN|S |sVt| ||\}}	|tj	tj
B  @ s||	r|	 D ]}
||
O }q||B S d S )NrD   )rJ   r>   r   r   r
   NONE
blueprintsAssertionError_blueprint_exemption_scoperO   rN   values)r!   r@   r;   r6   rP   rQ   Zroute_exemption_scopeblueprint_instanceZblueprint_exemption_scopeZancestor_exemption_scopes	exemptionr"   r"   r#   rM      s(    

zLimitManager.exemption_scope)rA   r   c                 C  s   g }| j |tjs|| jkr| j| D ]X}z|D ]}|| q2W q( tk
r~ } z| jd| d|  W 5 d }~X Y q(X q(|S )Nz&failed to load ratelimit for function : )	r   r>   r
   rT   r   append
ValueErrorr    error)r!   rA   r*   groupr1   er"   r"   r#   r      s    
zLimitManager.decorated_limits)r@   r6   r   c                   s.  g }|r|j |nd }|r*|j}t|r4|dng } ||\}}|tjtjB  @ s* j	|t
 }	|	rtdd |	D s j|tjtj@ stj fdd| j	|D  n|	}
|
r*|
D ]Z}z|dd |D  W q tk
r& } z jd| d|  W 5 d }~X Y qX q|S )	N.c                 s  s   | ]}|j V  qd S r%   rE   rG   r"   r"   r#   rI      s    z0LimitManager.blueprint_limits.<locals>.<genexpr>c                 3  s   | ]} j |g V  qd S r%   )r   r>   )rH   memberr)   r"   r#   rI      s   c                 S  sB   g | ]:}t |j|j|j|j|j|j|j|j|j	|j
|j|jqS r"   )r   r1   Zkey_funcr8   Z
per_methodmethodserror_messageZexempt_whenrF   Zdeduct_whenZ	on_breachZcostZsharedrG   r"   r"   r#   
<listcomp>   s   z1LimitManager.blueprint_limits.<locals>.<listcomp>z'failed to load ratelimit for blueprint r[   )rU   r>   rQ   setsplitrW   r
   rO   rN   r   r   rL   r   rT   	ANCESTORSr'   r(   intersection
differencerK   r]   r    r^   )r!   r@   r6   r*   rY   blueprint_nameZblueprint_ancestoryZself_exemptionZancestor_exemptionsZblueprint_self_limitsr   Zlimit_groupr`   r"   r)   r#   r      sf      
 
zLimitManager.blueprint_limitsz0Tuple[ExemptionScope, Dict[str, ExemptionScope]])r@   rk   r   c                   sb   |j | j} j|tjtj @ }t|d}dd  j	 D 
|}| fdd|D fS )Nra   c                 S  s   h | ]\}}|t j@ r|qS r"   )r
   ZDESCENDENTS)rH   kfr"   r"   r#   	<setcomp>   s   
z:LimitManager._blueprint_exemption_scope.<locals>.<setcomp>c                   s   i | ]}| j |tjqS r"   )r   r>   r
   rT   )rH   rl   r)   r"   r#   
<dictcomp>  s    z;LimitManager._blueprint_exemption_scope.<locals>.<dictcomp>)rU   rQ   r   r>   r
   rT   rh   rf   rg   itemsri   )r!   r@   rk   rQ   rZ   Z	ancestoryZancestor_exemptionr"   r)   r#   rW      s    z'LimitManager._blueprint_exemption_scope)F)NNNFF)__name__
__module____qualname__r$   propertyr   r   r,   r-   r5   r7   r9   r:   r=   r?   rS   rM   r   r   rW   r"   r"   r"   r#   r      s0    	     @Cr   )
__future__r   r'   r   typingr   r   r   r   r   ZflaskZordered_setr   	constantsr
   utilr   wrappersr   r   r   r"   r"   r"   r#   <module>   s   