
    N j1Q                         S SK r S SK Jr  S SKrS SKrS SKJr  S SKJrJ	r	  S SK
Jr  S SKrS SKJr  SSKJrJr  SS	KJr  S SKrSS
KJrJrJr  S rSrS r " S S\5      r " S S\S9rg)    N)	lru_cache)requests)urlspliturljoin)BeautifulSoup)
frozendict   )utilscache)YfConfig)YFExceptionYFDataExceptionYFRateLimitErrorc                     [        U [        [        R                  [        45      (       a  g[        U 5      R                  n1 SknX;   $ )zDCheck if error is transient (network/timeout) and should be retried.T>   TimeoutReadTimeoutTimeoutErrorConnectTimeoutConnectionErrorRemoteDisconnectedChunkedEncodingError)
isinstancer   socketerrorOSErrortype__name__)	exceptionerror_type_nametransient_error_typess      ^/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/yfinance/data.py_is_transient_errorr"      s?    )lFLL'BCC9o..O 33    @   c                    ^  [         R                  " T 5      U 4S j5       nT R                  Ul        T R                  Ul        U$ )z
Decorator transforms mutable dictionary and list arguments into immutable types
Needed so lru_cache can cache method calls what has dict or list arguments.
c            	      D  > [        U  Vs/ s H%  n[        U[        5      (       a  [        U5      OUPM'     sn5      n UR	                  5        VVs0 s H(  u  p4U[        U[        5      (       a  [        U5      OU_M*     nnn[        U  Vs/ s H%  n[        U[
        5      (       a  [        U5      OUPM'     sn5      n UR	                  5        VVs0 s H(  u  p4U[        U[
        5      (       a  [        U5      OU_M*     nnnT" U 0 UD6$ s  snf s  snnf s  snf s  snnf N)tupler   dictr   itemslist)argskwargsargkvfuncs        r!   wrapped%lru_cache_freezeargs.<locals>.wrapped(   s    SWXSWCC)>)>joCGSWXYMS\\^\^TQ!jD&9&9Z]q@^\dSdsJsD$9$9eCjsBdSTHNW!At!4!4U1X!;WT$V$$	 Y\SWs   ,D/D,D/D)	functoolswraps
cache_infocache_clear)r1   r2   s   ` r!   lru_cache_freezeargsr8   "   sA     __T% % G**GNr#   c                   R   ^  \ rS rSrSr0 r\R                  " 5       rU 4S jr	Sr
U =r$ )SingletonMeta7   z.
Metaclass that creates a Singleton instance.
c                 x  > U R                      X R                  ;  a  [        TU ]  " U0 UD6nX0R                  U '   OVSU;   d  U(       aI  [	        U5      S:  a:  SU;   a  UR                  S5      OUS   nU R                  U    R                  U5        U R                  U    sS S S 5        $ ! , (       d  f       g = f)Nsessionr   )_lock
_instancessuper__call__lenget_set_session)clsr,   r-   instancer=   	__class__s        r!   rA   SingletonMeta.__call__>   s    YY..( 7+T<V<&.s# &4CIM7@F7Jfjj3PTUVPWGNN3'44W=>>#& YYs   BB++
B9 )r   
__module____qualname____firstlineno____doc__r?   	threadingLockr>   rA   __static_attributes____classcell__)rG   s   @r!   r:   r:   7   s%     JNNE
' 
'r#   r:   c                   Z   \ rS rSrSrSS jrS rSS jr\R                  S 5       r
\R                  S 5       r\R                  SS	 j5       r\R                  SS
 j5       r\R                  S 5       r\R                  S 5       r\R                  SS j5       r\R                  SS j5       r\R                  SS j5       r\R                  S S j5       r\R                  S S j5       r\\" \S9SS j5       5       rSS jrS\S\4S jrS\R<                  S\S\R<                  4S jr Sr!g)!YfDataK   z
Have one place to retrieve data from Yahoo API in order to ease caching and speed up operations.
Singleton means one session one cookie shared by all threads.
Nc                     S U l         S U l        SU l        [        R                  " 5       U l        S U l        U R                  U=(       d    [        R                  " SS95        g )Nbasicchrome)impersonate)
_crumb_cookie_cookie_strategyrN   rO   _cookie_lock_sessionrD   r   Sessionselfr=   s     r!   __init__YfData.__init__Q   sP     !( &NN,'KX%5%5(%KLr#   c                    Uc  g  UR                     SU l        [        S5      e! [         a
    SU l         Of = f[	        U[
        R                  R                  5      (       d  [        S[        U5       S35      eU R                     Xl
        [        R                  R                  b)  [        R                  R                  U R                  l        S S S 5        g ! , (       d  f       g = f)NTzrequest_cache sessions don't work with curl_cffi, which is necessary now for Yahoo API. Solution: stop setting session, let YF handle.Fz)Yahoo API requires curl_cffi session not z0. Solution: stop setting session, let YF handle.)r   _session_is_cachingr   AttributeErrorr   r   r=   r^   r   r\   r]   r   networkproxyproxiesr_   s     r!   rD   YfData._set_session_   s    ?	lMM (,D$!  #k  l  l  	-',D$	- '8#3#3#;#;<<!$MdSZm_  ]M  #N  O  O#M%%1(0(8(8(>(>% s   $ 88AC
C*c                 h   XR                   :X  a  g U(       d  U R                  R                  5          U R                   S:X  a^  [        R                  " 5       R                  SU R                    S35        U R                  R                  R                  5         SU l         O9[        R                  " 5       R                  SU R                    S35        SU l         S U l	        S U l
        U(       d  U R                  R                  5         g g ! [         a    U R                  R                  5         e f = f)Ncsrfztoggling cookie strategy z	 -> basicrV   z -> csrf)r[   r\   acquirer
   get_yf_loggerdebugr]   cookiesclearrZ   rY   	Exceptionrelease)r`   strategy	have_locks      r!   _set_cookie_strategyYfData._set_cookie_strategyx   s   ,,,%%'	$$.##%++.GH]H]G^^g,hi%%++-(/%##%++.GH]H]G^^f,gh(.%DLDK
 %%' 	  	%%'	s   B5D &D1c                 8   U R                   c  gU R                   R                  R                  R                  n[	        U5      S:X  a  gUR                  5        Vs/ s H  nSU;   d  M  UPM     nn[	        U5      S:  a  U Vs/ s H  nSU;  d  M  UPM     nn[	        U5      S:  a(  [        R                  " 5       R                  SU 35        g[	        U5      S:X  a  gUS   nXAU   0n[        R                  " 5       R                  SU5        gs  snf s  snf )	NFr   yahoor	   consentz1Multiple Yahoo cookies, not sure which to cache: curlCffiT)r]   ro   jar_cookiesrB   keysr
   rm   rn   r   get_cookie_cachestore)r`   ro   r/   
yh_domains	yh_domain	yh_cookies         r!   _save_cookie_curlCffiYfData._save_cookie_curlCffi   s    == --''++44w<1!(@A7a<a
@z?Q%/FZ9A3E!ZJFz?Q!''*[\f[g(hiz?aqM		 23	 &&z9= A Gs   
D)D
DDc                    U R                   c  g[        R                  " 5       R                  S5      nUb  [	        U5      S:X  a  gUS   n[        UR                  5       5      S   nX#   S   S   nUR                  nUS:  a  US-  n[        R                  R                  U[        R                  R                  S	9nU[        R                  R                  [        R                  R                  5      :  nU(       a%  [        R                  " 5       R                  S
5        gU R                   R                   R"                  R$                  R'                  U5        X@l        g)NFrz   r   cookie/A3g    eAg     @@)tzzcached cookie expiredT)r]   r   r~   lookuprB   r+   r}   expiresdatetimefromtimestamptimezoneutcnowr
   rm   rn   ro   r{   r|   updaterZ   )r`   cookie_dictro   domainr   	expiry_ts	expiry_dtexpireds           r!   _load_cookie_curlCffiYfData._load_cookie_curlCffi   s   == ,,.55jA#k"2a"7h'glln%a(%d+NN	s?#I%%33I(BSBSBWBW3X	h//33H4E4E4I4IJJ!''(?@!!**11':r#   c                    U R                   b%  [        R                  " 5       R                  S5        gU R	                  5       (       a%  [        R                  " 5       R                  S5        g U R
                  R                  SUSS9  U R                  5         g! [        R                  R                   a:  n[        R                  " 5       R                  S[        U5      -   5         S nAgS nAff = f)Nreusing cookieTreusing persistent cookiezhttps://fc.yahoo.comurltimeoutallow_redirectsz$Handling DNS error on cookie fetch: F)rZ   r
   rm   rn   r   r]   rC   r   
exceptionsDNSErrorstrr   )r`   r   es      r!   _get_cookie_basicYfData._get_cookie_basic   s    <<#!''(89''))!''(CD		MM* $  & 	""$ ""++ 	 !''(NQTUVQW(WX		s   .B C280C--C2c                 >   U R                   b0  [        R                  " 5       R                  S5        U R                   $ U R	                  5       (       d  g SUSS.nU R
                  (       a,  U R                  US'   U R                  R                  " S0 UD6nOU R                  R                  " S0 UD6nUR                  U l         UR                  S:X  d  SU R                   ;   a;  [        R                  " 5       R                  SU R                    35        [        5       eU R                   b  S	U R                   ;   a%  [        R                  " 5       R                  S
5        g [        R                  " 5       R                  SU R                    S35        U R                   $ )Nreusing crumbz1https://query1.finance.yahoo.com/v1/test/getcrumbTr   expire_after  Too Many RequestsDidn't receive crumb <html>Didn't receive crumb	crumb = ''rI   )rY   r
   rm   rn   r   rd   _expire_afterr]   rC   textstatus_coder   )r`   r   get_argscrumb_responses       r!   _get_crumb_basicYfData._get_crumb_basic   sL   ;;"!''8;;%%'' G#

 ##'+'9'9H^$!]]..::N!]]..::N$))%%,0Ct{{0R!''*?}(MN"$$;;(dkk"9!''(>?##i}A$>?{{r#   c                 R    U R                  U5      (       d  g U R                  U5      $ r'   )r   r   )r`   r   s     r!   _get_cookie_and_crumb_basic"YfData._get_cookie_and_crumb_basic   s'    %%g..$$W--r#   c                    U R                   b%  [        R                  " 5       R                  S5        gU R	                  5       (       a,  [        R                  " 5       R                  S5        SU l         gSU0n0 UESS0En U R
                  (       a,  U R                  US'   U R                  R                  " S0 UD6nOU R                  R                  " S0 UD6n [        UR                  S
5      nUR                  SSS0S9nUc%  [        R                  " 5       R                  S5        g	US   n[        R                  " 5       R                  SU 35        UR                  SSS0S9nUS   n	[        R                  " 5       R                  SU	 35        Sn
SnSS/SU	UU
US.n0 UESU	 3US.En0 UESU	 3US.En U R
                  (       aW  U R                  US'   U R                  US'   U R                  R                  " S0 UD6  U R                  R                  " S0 UD6  O9U R                  R                  " S0 UD6  U R                  R                  " S0 UD6   SU l         U R!                  5         g! [        R                  R                   a'    [        R                  " 5       R                  S5         g	f = f! [        R                  R                   a'    [        R                  " 5       R                  S5         Nf = f)Nr   Tr   r   r   zhttps://guce.yahoo.com/consentr   zR_get_cookie_csrf() encountering requests.exceptions.ChunkedEncodingError, abortingFhtml.parserinputname	csrfToken)attrsz&Failed to find "csrfToken" in responsevaluezcsrfToken = 	sessionIdzsessionId='zhttps://finance.yahoo.com/rx   agreedefault)r   consentUUIDr   r   originalDoneUrl	namespacez6https://consent.yahoo.com/v2/collectConsent?sessionId=)r   dataz-https://guce.yahoo.com/copyConsent?sessionId=rI   )rZ   r
   rm   rn   r   rd   r   r]   rC   r   r   r   r   contentfindpostr   )r`   r   	base_argsr   responsesoupcsrfTokenInputr   sessionIdInputr   r   r   r   	post_argss                 r!   _get_cookie_csrfYfData._get_cookie_csrf   s   <<#!''(89''))!''(CDDL w 	 JiI(HI		''+/+=+=(==,,8x8==,,8x8 X--}=76;2GH!!''(PQ"7+	##l9+$>?76;2GH"7+	##k)$=>6	w'$""."
y KI;W	i B9+N	~'',0,>,>	.)+/+=+=(""/Y/!!-H-""/Y/!!-H- ""$] ""77 	!''(|}	R ""77 	~!''(|}	~s3   <I6 >I6 =A'J> %8J> 6AJ;:J;>ALLc                 ^   U R                   b0  [        R                  " 5       R                  S5        U R                   $ U R	                  U5      (       d  g SUS.nU R
                  (       a,  U R                  US'   U R                  R                  " S0 UD6nOU R                  R                  " S0 UD6nUR                  U l         UR                  S:X  d  SU R                   ;   a;  [        R                  " 5       R                  SU R                    35        [        5       eU R                   b   SU R                   ;   d  U R                   S	:X  a%  [        R                  " 5       R                  S
5        g [        R                  " 5       R                  SU R                    S35        U R                   $ )Nr   z1https://query2.finance.yahoo.com/v1/test/getcrumb)r   r   r   r   r   r   r    r   r   r   rI   )rY   r
   rm   rn   r   rd   r   r]   rC   r   r   r   )r`   r   r   rs       r!   _get_crumb_csrfYfData._get_crumb_csrf=  sT    ;;"!''8;;$$W-- G  ##'+'9'9H^$!!-H-A!!-H-Aff==C#6$++#E!''*?}(MN"$$;;(dkk"9T[[B=N!''(>?##i}A$>?{{r#   c                    Su  p#[         R                  " 5       R                  SU R                   S35        U R                     U R                  S:X  a5  U R                  5       nUc!  U R                  SSS9  U R                  U5      nO4U R                  U5      nUc   U R                  SSS9  U R                  5       nU R                  nS S S 5        X#4$ ! , (       d  f       X#4$ = f)N)NNzcookie_mode = 'r   rk   rV   T)rt   )r
   rm   rn   r[   r\   r   ru   r   )r`   r   crumbrs   s       r!   _get_cookie_and_crumbYfData._get_cookie_and_crumb^  s    $##od6K6K5LA$NO$$.,,.=--g-F <<WEE 88A=--f-E 002E,,H    s   BC
C$c                     U R                  XR                  R                  X#S9nU R                  UR                  5      (       d   U$ U R                  XC5      nU$ )N)request_methodparamsr   )_make_requestr]   rC   _is_this_consent_urlr   _accept_consent_formr`   r   r   r   r   s        r!   rC   
YfData.getu  sZ    %%cMM<M<MV\%n ((66
  00CHr#   c           	      L    U R                  XR                  R                  X#XES9$ )N)r   bodyr   r   r   )r   r]   r   )r`   r   r   r   r   r   s         r!   r   YfData.post  s,    !!#8J8JQUnu!  B  	Br#   c                    [        U5      S:  a,  [        R                  " 5       R                  SUS S  S35        O'[        R                  " 5       R                  SU 35        [        R                  " 5       R                  SU 35        [        R
                  R                  U R                  l        Uc  0 nSU;   a  [        S5      eU R                  5       u  pxUb  SU0n	O0 n	U0 UEU	EUS.n
U(       a  X:S'   U(       a  XjS	'   S
S0U
S'   [        [        R
                  R                  S-   5       H  n U" S0 U
D6n  O   [        R                  " 5       R                  SWR"                   35        UR"                  S:  a  US:X  a  U R%                  S5        OU R%                  S5        U R                  U5      u  pxXzS   S'   U" S0 U
D6n[        R                  " 5       R                  SUR"                   35        UR"                  S:X  a
  ['        5       eU$ ! [         aT  n[        U5      (       a>  U[        R
                  R                  :  a   [        R                   " SU-  5         S nAGMA  e S nAff = f)N   zurl=z...zparams=r   z@Don't manually add 'crumb' to params dict, let data.py handle it)r   r   r   jsonr   zContent-Typezapplication/jsonheadersr	      zresponse code=i  rV   rk   r   r   rI   )rB   r
   rm   rn   r   rf   rg   r]   rh   r   r   rangeretriesrq   r"   _timesleepr   ru   r   )r`   r   r   r   r   r   r   r   rs   crumbsrequest_argsattemptr   r   s                 r!   r   YfData._make_request  sT    s8c>!''$s4Cyk(=>!''$se5##gfX$67 !) 0 0 6 6>Ff`aa446u%FF **6*
 #' #' '57I&JL#X--559:G)9L9 ; 	##nX5I5I4J$KL3&7"))&1))'2"88AOE.3"7+%55H!''.9M9M8N(OP ##s*&((+  &q))g8H8H8P8P.PKKW--	s   6H
I9%AI43I44I9)maxsizec                 &    U R                  XU5      $ r'   )rC   )r`   r   r   r   s       r!   	cache_getYfData.cache_get  s     xxW--r#   c                     [         R                  " 5       R                  SU 35        U R                  XUS9nUR	                  5         UR                  5       $ )Nzget_raw_json(): )r   r   )r
   rm   rn   rC   raise_for_statusr   r   s        r!   get_raw_jsonYfData.get_raw_json  sK    ##&6se$<=88C8@!!#}}r#   response_urlreturnc                      [        U5      R                  =(       a$    [        U5      R                  R                  S5      $ ! [         a     gf = f)z
Check if given response_url is consent page

Args:
    response_url (str) : response.url

Returns:
    True : This is cookie-consent page
    False : This is not cookie-consent page
zconsent.yahoo.comF)r   hostnameendswithrq   )r`   r   s     r!   r   YfData._is_this_consent_url  sL    	L)22 5x8hxx 345  		s   ?A 
AAconsent_respr   c                 f   [        UR                  S5      nUR                  S5      nU(       d  U$ UR                  S5      =(       d    UR                  n[        UR                  U5      n 0 nUR                  S5       H  nUR                  S5      nU(       d  M  UR                  S5      =(       d    SR                  5       n	UR                  S5      =(       d    S	n
U	S
;   aN  SUR                  5       ;   d*  SUR                  5       ;   d  UR                  S5      (       a  U
S	:w  a  U
OSXh'   M  M  XU'   M     UR                  5        Vs1 s H  oR                  5       iM     nn[        S U 5       5      (       d  SUS'   SUR                  0nU R                  R                  XVXSS9nU$ s  snf )aY  
Click 'Accept all' to cookie-consent form and return response object.

Args:
    consent_resp (requests.Response) : Response instance of cookie-consent page
    timeout (int) : Raise TimeoutError if post doesn't respond

Returns:
    response (requests.Response) : Reponse instance received from the server after accepting cookie-consent post.
r   formactionr   r   r   r   r   r   )checkboxradior   acceptchecked1c              3   D   #    U  H  nS U;   =(       d    SU;   v   M     g7f)r   r  NrI   ).0r/   s     r!   	<genexpr>.YfData._accept_consent_form.<locals>.<genexpr>  s      DGqGqL1HM1Gs    RefererT)r   r   r   r   )r   r   r   rC   r   r   find_alllowerhas_attrr}   anyr]   r   )r`   r  r   r   r  r  r   inpr   typvalr/   loweredr   r   s                  r!   r   YfData._accept_consent_form  s    \..> yy  (#7|'7'7))62	 ==)C776?D776?,f335C'''"(bC++ tzz|+4::</||I..(+r	sDJ / !T
! *& '+iik2k779k2DGDDDDM l../==%%wQU & 
  3s   F.)rZ   r\   r[   rY   r]   rd   r'   )F)   )Nr  )NNr  N)"r   rJ   rK   rL   rM   ra   rD   ru   r
   log_indent_decoratorr   r   r   r   r   r   r   r   rC   r   r   r8   r   cache_maxsizer   r   r   boolr   r   Responseintr   rP   rI   r#   r!   rS   rS   K   s   
M?2(.   (   ,   .   < .  .
 B  BH   @   ,    B  B =  =~ }%. & .  $<$--<8;<			<r#   rS   )	metaclass)r4   r   r   timer   	curl_cffir   urllib.parser   r   bs4r   r   r   r   r
   r   configr   rN   r   r   r   r   r"   r  r8   r   r:   rS   rI   r#   r!   <module>r%     sZ         *   !    F F	4 *'D '(U} Ur#   