+
    j7                       ^ RI Ht ^ RIt^ RIt^ RIt^ RIHt ^ RIHtH	t	 ^ RI
HtH
t
 ^ RIHt ^ RIHtHt ^ RIHtHt ^ R	IHt ^ R
IHtHt ]! ]]04      t]! RR7       ! R R4      4       t]! RR7       ! R R4      4       t]! RR7       ! R R4      4       t ! R R]4      t ! R R] 4      t! ! R R4      t"R R lt#R"RR/R R lllt$R R lt%RR/R  R! llt&R# )#    )annotationsN)Mapping)	dataclassfield)UTCdatetime)Path)AccountSnapshotHealthStatus)	WINDOW_5H	WINDOW_7D)runtime_dir)capped_windowsdescribe_capsT)frozenc                  |    ] tR t^t$ R]R&   R]R&   R]R&   RtR]R&   R	tR]R
&   RtR]R&   ]! ]	R7      t
R]R&   RtR# )RoutingRuleszdict[str, 'ProjectRoute']projectsstrdefaultintquota_exhausted_threshold_pcttuple[str, ...]fallback_chainbroken_or_quota_exhaustedfallback_triggerTboolmissing_health_is_available)default_factoryzMapping[str, Mapping[str, int]]account_caps N)__name__
__module____qualname____firstlineno____annotations__r   r   r   r   dictr    __static_attributes__r!       J/home/user/overdeck-private-tests/subrouter-s5-systray/routing_resolver.pyr   r      sC    ''L#&&&(NO(7c7(,,49$4OL1Or)   r   c                  0    ] tR t^t$ R]R&   RtR]R&   RtR# )ProjectRouter   accountr   fallbackr!   N)r"   r#   r$   r%   r&   r.   r(   r!   r)   r*   r,   r,      s    L "Ho"r)   r,   c                  J    ] tR t^$t$ R]R&   R]R&   R]R&   R]R&   R]R	&   R
tR# )ResolvedRouter   slugr   chainsourcer   fallback_used
str | Nonefallback_fromr!   N)r"   r#   r$   r%   r&   r(   r!   r)   r*   r0   r0   $   s    
IKr)   r0   c                  6   a  ] tR t^-tRR/R V 3R llltRtV ;t# )NoHealthyAccountErrorr2   c               $    V ^8  d   QhRRRRRR/# )   messager   r2   r   returnNoner!   )formats   "r*   __annotate__"NoHealthyAccountError.__annotate__.   s!         r)   c               	2   < \         SV `  V4       W n        R # N)super__init__r2   )selfr;   r2   	__class__s   &&$r*   rD   NoHealthyAccountError.__init__.   s    !
r)   r2   r!   )r"   r#   r$   r%   rD   r(   __classcell__)rF   s   @r*   r8   r8   -   s       r)   r8   c                  "    ] tR t^3tR R ltRtR# )AllAccountsCappedErrorc                    V ^8  d   QhRRRR/# )r:   	resume_atr5   r<   r=   r!   )r>   s   "r*   r?   #AllAccountsCappedError.__annotate__4   s     # #* # #r)   c                	    Wn         R # rB   rM   )rE   rM   s   &&r*   rD   AllAccountsCappedError.__init__4   s    "r)   rP   N)r"   r#   r$   r%   rD   r(   r!   r)   r*   rK   rK   3   s    # #r)   rK   c                      ] tR t^8tRR R lltRR R lltR R ltR R	 ltR
 R ltR R lt	R R lt
R R ltR R ltR R ltR R ltR R ltRtR# )RoutingResolverNc          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r:   rulesr   healthzdict[str, AccountSnapshot]known_slugsset[str] | Nonelocked_slugsz set[str] | frozenset[str] | Noner<   r=   r!   )r>   s   "r*   r?   RoutingResolver.__annotate__9   s<     
: 
:
: +
: %	
:
 7
: 

:r)   c                	~    Wn         W n        Vf   R M
\        V4      V n        \        T;'       g    R4      V n        R # )Nr!   )rU   rV   	frozensetrW   rY   )rE   rU   rV   rW   rY   s   &&&&&r*   rD   RoutingResolver.__init__9   s7     
#.#64Ik<R%l&8&8b9r)   c               $    V ^8  d   QhRRRRRR/# )r:   project_namer5   dynamic_slugr<   r0   r!   )r>   s   "r*   r?   rZ   E   s'     R RJ Rj RTa Rr)   c           	     	   Ve&   V P                   P                  P                  V4      MR p\        V\        4      '       d   \        V4      pVe   RMRpVe   VP                  .VP                  OM,V P                   P                  .V P                   P                  Op. pV FA  pVR8X  d'   V'       g   \        R4      hVP                  V4       K0  VP                  V4       KC  	  \        V4      p\        V4       FD  w  rV P                  V4      '       g   K  \        YxYI^ 8  V	^ 8  d   V^ ,          4      u # R 4      u # 	  \        V P!                  \#        V4      4      VR7      h)Nr   r   dynamicz%dynamic route has no selected accountrH   )rU   r   get
isinstancer   r,   r-   r.   r   r   r8   appendtuple	enumerate_is_availabler0   _format_errorlist)
rE   r_   r`   project_router3   	raw_chainchain_partsr1   r2   indexs
   &&&       r*   resolveRoutingResolver.resolveE   sA   AMAY

++//=_cmS))(7M,8i%1 $++Em.D.DE8<

8J8J7gTZZMfMf7g 	!#Dy #/0WXX""<0""4(  k"$U+KE!!$''$T&!)QVYZQZU1Xee`dee , $D$6$6tE{$C5QQr)   c                    V ^8  d   QhRRRR/# )r:   r1   r   r<   zMapping[str, int]r!   )r>   s   "r*   r?   rZ   Z   s     5 5 5): 5r)   c                	N    V P                   P                  P                  V/ 4      # rB   )rU   r    rc   )rE   r1   s   &&r*   r    RoutingResolver.account_capsZ   s    zz&&**444r)   c                    V ^8  d   QhRRRR/# r:   r1   r   r<   r   r!   )r>   s   "r*   r?   rZ   ]   s     	4 	4S 	4T 	4r)   c                	    V P                  V4      pV'       g   R # V P                  P                  V4      pVf   R# VP                  \        P
                  8X  d   R # \        \        W24      4      # )FT)r    rV   rc   statusr   BROKENr   r   )rE   r1   capssnapshots   &&  r*   _is_cap_excluded RoutingResolver._is_cap_excluded]   sX      &;;??4(??l111N8233r)   c                    V ^8  d   QhRRRR/# r:   slugsr   r<   r   r!   )r>   s   "r*   r?   rZ   h   s     B Bo B$ Br)   c                	   a  V'       g   R # \         ;QJ d    V 3R lV 4       F  '       d   K   R # 	  R# ! V 3R lV 4       4      # )Fc              3  F   <"   T F  pSP                  V4      x  K  	  R # 5irB   )r{   .0r1   rE   s   & r*   	<genexpr>3RoutingResolver.all_cap_excluded.<locals>.<genexpr>k   s     A544((..5s   !T)allrE   r   s   f&r*   all_cap_excluded RoutingResolver.all_cap_excludedh   s2    sA5AssAsAsA5AAAr)   c                    V ^8  d   QhRRRR/# r~   r!   )r>   s   "r*   r?   rZ   m   s     P P PD Pr)   c                	   a  \        V4      ;'       d;    \        ;QJ d    V 3R  lV 4       F  '       d   K   R# 	  R# ! V 3R  lV 4       4      # )c              3  @   <"   T F  qSP                   9   x  K  	  R # 5irB   rY   r   s   & r*   r   -RoutingResolver.all_locked.<locals>.<genexpr>n   s     "O4+<+<#<s   FT)r   r   r   s   f&r*   
all_lockedRoutingResolver.all_lockedm   s8    E{OOss"O"OssOsOs"O"OOOr)   c                    V ^8  d   QhRRRR/# )r:   r   r   r<   r!   )r>   s   "r*   r?   rZ   p   s     N No N/ Nr)   c                	h   a  \         ;QJ d    . V 3R  lV 4       F  NK  	  5# ! V 3R  lV 4       4      # )c              3  L   <"   T F  qSP                   9  g   K  Vx  K  	  R # 5irB   r   r   s   & r*   r   +RoutingResolver.unlocked.<locals>.<genexpr>q   s     Med4;L;L/LTTes   $
$)rf   r   s   f&r*   unlockedRoutingResolver.unlockedp   s%    uMeMuMuMeMMMr)   c                    V ^8  d   QhRRRR/# )r:   r   r   r<   r5   r!   )r>   s   "r*   r?   rZ   s   s     1 1O 1
 1r)   c                	   . pV F  pV P                  V4      pV P                  P                  V4      pV'       d   Vf   K=  \        WT4       F=  pV\        8X  d   VP
                  MVP                  pVf   K,  VP                  V4       K?  	  K  	  V'       g   R # \        P                  ! \        \        V4      4      \        R7      pVP                  R4      # )N)tzz%Y-%m-%dT%H:%M:%SZ)r    rV   rc   r   r   primary_reset_atsecondary_reset_atre   r   fromtimestampr   minr   strftime)	rE   r   epochsr1   ry   rz   windowreset_atdts	   &&       r*   earliest_cap_resume_at&RoutingResolver.earliest_cap_resume_ats   s     D$$T*D{{t,H8+(8 * --!44 
 'MM(+ 9  ##CF$4={{/00r)   c                    V ^8  d   QhRRRR/# ru   r!   )r>   s   "r*   r?   rZ      s     3 3# 3$ 3r)   c                	   WP                   9   d   R # V P                  e   WP                  9  d   R # V P                  P                  V4      pVfF   V P	                  V4      '       d   R # V P                  RJ;'       d    V P
                  P                  # VP                  \        P                  8X  d   R # \        W P	                  V4      4      '       d   R # V P
                  P                  R8w  d   R# V P                  V4      '       * # )FNr   T)rY   rW   rV   rc   r    rU   r   rw   r   rx   r   r   _quota_exhausted)rE   r1   rz   s   && r*   rh   RoutingResolver._is_available   s    $$$'D8H8H,H;;??4(  &&##4/ZZDJJ4Z4ZZ??l111($5$5d$;<<::&&*EE((222r)   c                    V ^8  d   QhRRRR/# )r:   rz   r
   r<   r   r!   )r>   s   "r*   r?   rZ      s     
 
 
T 
r)   c                	    V P                   P                  pVP                  pVP                  pVR J;'       d    W28  ;'       g    VR J;'       d    WB8  # rB   )rU   r   primary_used_pctsecondary_used_pct)rE   rz   	thresholdprimary	secondarys   &&   r*   r    RoutingResolver._quota_exhausted   s\    JJ<<	++//	t#<<(< 
 
T!<<i&<	
r)   c                    V ^8  d   QhRRRR/# )r:   triedz	list[str]r<   r   r!   )r>   s   "r*   r?   rZ      s     C C9 C Cr)   c                	    V Uu. uF  q" R V P                  V4       2NK  	  ppRRP                  V4      ,           # u upi )=zno healthy account available: z, )_describe_statusjoin)rE   r   r1   partss   &&  r*   ri   RoutingResolver._format_error   sE    EJKUT6400678UK/$))E2BBB Ls   =c                    V ^8  d   QhRRRR/# )r:   r1   r   r<   r!   )r>   s   "r*   r?   rZ      s     % %S %S %r)   c                	h   WP                   9   d   R # V P                  e   WP                  9  d   R# V P                  P                  V4      pVf   R# VP                  \
        P                  8X  d   R# \        W P                  V4      4      pV'       d   V# V P                  P                  R8X  dk   V P                  V4      '       dT   VP                  f   RM\        VP                  4      pVP                  f   RM\        VP                  4      pRV RV R2# VP                  P                  # )	lockedzunknown-accountzmissing-healthbrokenr   ?zquota-exhausted(primary=z,secondary=))rY   rW   rV   rc   rw   r   rx   r   r    rU   r   r   r   r   r   value)rE   r1   rz   
cap_statusr   r   s   &&    r*   r    RoutingResolver._describe_status   s   $$$'D8H8H,H$;;??4(#??l111"8->->t-DE
JJ''+FF%%h//%66>cCHaHaDbG22:HD_D_@`  .gYk)ANN$$$r)   )rV   rW   rY   rU   )NNrB   )r"   r#   r$   r%   rD   ro   r    r{   r   r   r   r   rh   r   ri   r   r(   r!   r)   r*   rS   rS   8   sH    
:R*5	4B
PN1(3$
C% %r)   rS   c               $    V ^8  d   QhRRRRRR/# )r:   r    objectrW   rX   r<   zdict[str, dict[str, int]]r!   )r>   s   "r*   r?   r?      s(       ! 	r)   c               (   V f   / # \        V \        4      '       g   \        R4      h/ pV P                  4        F  w  r4\        V\        4      '       d	   V'       g   \        R4      hVe   W19  d   \        RV: R24      h\        V\        4      '       g   \        R4      h/ pVP                  4        FQ  w  rgV\
        9  d   \        R4      h\        V\        4      '       d   ^Tu;8:  d   ^d8:  g   M \        R4      hWuV&   KS  	  WRV&   K  	  V# )N1routing_rules.json account_caps must be an objectz>routing_rules.json account_caps keys must be non-empty stringsz%routing_rules.json account_caps slug z is not in the registry7routing_rules.json account_caps entries must be objectsz@routing_rules.json account_caps window keys must be '5h' or '7d'zArouting_rules.json account_caps values must be ints from 1 to 100)rd   r'   
ValueErroritemsr   _VALID_CAP_WINDOWSr   )r    rW   
normalizedr1   windowsnormalized_windowsr   cap_pcts   &$      r*   _normalize_account_capsr      s   
 	lD))LMM,.J%++-$$$D]^^"t'>DTHLcdee'4((VWW-/&}}OF// !cddgs++13F33F !dee)0v&  / .4 . r)   rW   c               $    V ^8  d   QhRRRRRR/# )r:   pathzPath | NonerW   rX   r<   r   r!   )r>   s   "r*   r?   r?      s-     K K
K !K 	Kr)   c                  V f   \        4       R,          p \        P                  ! V P                  RR7      4      pVP	                  R4      p\        V\        4      '       g   \        R4      hVP	                  R4      pVP	                  R. 4      pVP	                  RR	4      pVP	                  R
VP	                  R4      R8g  4      pVP	                  R^d4      p\        V\        4      '       d	   V'       g   \        R4      h\        V\        4      '       g   \        R4      h\        V\        4      '       d;   \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   \        R4      h\        V\        4      '       d	   V'       g   \        R4      h\        V\        4      '       g   \        R4      h/ p	VP                  4        EF  w  r\        V\        4      '       d   RV/p\        V
\        4      '       d   V
'       d   \        V\        4      '       g   \        R4      hVP	                  R4      VP	                  R. 4      r\        V\        4      '       dY   V'       dQ   \        V\        4      '       d;   \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   \        R4      h\        V\        V4      4      W&   EK  	  \!        VP	                  R/ 4      VR7      pVP	                  R4      R8w  d   RRRV	P                  4        U
Uu/ uF?  w  rT
RVP"                  /VP$                  '       d   R\        VP$                  4      /M/ CbKA  	  upp
RVRVRVR
VRVRV/pV P'                  \        P(                  ! V^R7      R,           RR7       \+        V	V\        V4      VVVVR7      # u upp
i ) Nzrouting_rules.jsonutf-8encodingr   z-routing_rules.json projects must be an objectr   r   r   r   r   versionz
routing/v2r   z5routing_rules.json default must be a non-empty stringz?routing_rules.json quota_exhausted_threshold_pct must be an intc              3  j   "   T F)  p\        V\        4      '       * ;'       g    V'       * x  K+  	  R # 5irB   rd   r   )r   r1   s   & r*   r   load_rules.<locals>.<genexpr>   s*      3:H$JtS!!--X-.    33TFzErouting_rules.json fallback_chain must be a list of non-empty stringsz>routing_rules.json fallback_trigger must be a non-empty stringz=routing_rules.json missing_health_is_available must be a boolr-   z9routing_rules.json projects entries must be route objectsr.   c              3  j   "   T F)  p\        V\        4      '       * ;'       g    V'       * x  K+  	  R # 5irB   r   )r   xs   & r*   r   r     s?       `S  JR  EFdnoprudv`v``~z`  JRr   z+routing_rules.json project route is invalidr    rW   )indent
)r   r   r   r   r   r   r    )r   jsonloads	read_textrc   rd   r'   r   r   r   rj   anyr   r   r,   rf   r   r-   r.   
write_textdumpsr   )r   rW   payloadr   r   r   r   r   r   normalized_projectskeyr   r-   r.   r    routemigrateds   &$               r*   
load_rulesr      su   
 |}33jj9:G{{:&Hh%%HIIkk)$G[[!126N{{#57RS")++%w{{9'='M# ;SAIgs##7PQQi%%Z[[nd++ss 3:H3sss 3:H3 0 0 `aa&,,4DYZZ1488XYY35nn&
eS!!&E#s##3j6M6MXYY!IIi0%))J2K'3''wjSW>X>X\_\_  `S  JR  `S\_\_\_  `S  JR  `S  ]S  ]SJKK#/x#I  ' +NB'L
 {{9-|
 #6";";"=
 #>JC	 u}}=B^^^
D$89QS  #> wn 0)+F+YL
  	

8A6=P$^,)$?&/! !s   9AOc               $    V ^8  d   QhRRRRRR/# )r:   r   r	   r   zdict[str, object]r<   r=   r!   )r>   s   "r*   r?   r?   (  s"      d -> 4 r)   c           	        V P                   P                  R R R7       \        P                  ! RRV P                   RR7      ;_uu_ 4       p\        P
                  ! W^R R7       VP                  R4       VP                  4        \        P                  ! VP                  4       4       \        VP                  4      pRRR4       XP                  V 4       R#   + '       g   i     L#; i)	T)parentsexist_okwr   F)r   dirdelete)r   	sort_keysr   N)parentmkdirtempfileNamedTemporaryFiler   dumpwriteflushosfsyncfilenor	   namereplace)r   r   	temp_file	temp_paths   &&  r*   _atomic_write_rulesr  (  s    KKdT2		$	$KK	
 

 
		'Q$?
!!#$(	
 d
 
s   
A4CC)	c               0    V ^8  d   QhRRRRRRRRRR	R
R/# )r:   r   r	   r1   r   r   r   z
int | NonerW   rX   r<   r=   r!   )r>   s   "r*   r?   r?   8  sD     1' 1'
1'
1' 1' 	1' !1' 
1'r)   c               &    \         P                  ! V P                  R R7      4      p\        T\        4      '       g   \	        RT  24      hTP                  R/ 4      pTf   / p\        T\        4      '       g   \	        R4      hTP                  T/ 4      pTf   / p\        T\        4      '       g   \	        R4      h\        T4      p	Tf   T	P                  TR4       MY9T&   \        T4      p
Te,   T
P                  4        UUu/ uF  w  rY9   g   K  YbK  	  p
ppT	'       d   YT&   MT
P                  TR4       \        YR7       \        T4      pYR&   \        Y4       R#   \        \        3 d   p\	        RT  24      ThRp?ii ; iu uppi )r   r   zrouting rules unreadable: Nr    r   r   r   )r   r   r   OSErrorr   rd   r'   rc   popr   r   r  )r   r1   r   r   rW   rawexcr    	slug_capsupdated_slug_capsupdated_account_caps
entry_slugr   r   s   &&&&$         r*   update_account_capr  8  s   Gjj9: c4  5dV<==77>2.LlD))LMM  r*I	i&&RSSYfd+$+&!- (<'A'A'C 
'C#
(  J'C 	  

 %6T"  t,0J3iG2N&O Z  G5dV<=3FG2 
s#   &E% 
FF%F
6FF
rB   )'
__future__r   r   r   r   collections.abcr   dataclassesr   r   r   r   pathlibr	   health_clientr
   r   limit_warningr   r   runtime_pathsr   	spend_capr   r   r\   r   r   r,   r0   RuntimeErrorr8   	ExceptionrK   rS   r   r   r  r  r!   r)   r*   <module>r     s    "  	  # ( "  7 . % 3	956  $P P P $# # #
 $  L #Y #
C% C%L8K $(K K\ 1' $(1' 1'r)   