
    Ej1Q                         d dl Z d dl mZ d dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZ d dlZd dlmZ ddlmZmZ dd	lmZ d dlZdd
lmZmZmZ d ZdZd Z G d de          Z G d de          ZdS )    N)	lru_cache)requests)urlspliturljoin)BeautifulSoup)
frozendict   )utilscache)YfConfig)YFExceptionYFDataExceptionYFRateLimitErrorc                     t          | t          t          j        t          f          rdS t          |           j        }h d}||v S )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      I/var/www/html/bolsaweb/venv/lib/python3.11/site-packages/yfinance/data.py_is_transient_errorr"      sP    )lFL'BCC t9oo.O   333    @   c                 v     t          j                    fd            } j        |_         j        |_        |S )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                      t          d | D                       } d |                                D             }t          d | D                       } d |                                D             } | i |S )Nc                 Z    g | ](}t          |t                    rt          |          n|)S  r   dictr   .0args     r!   
<listcomp>z9lru_cache_freezeargs.<locals>.wrapped.<locals>.<listcomp>*   s1    XXXCC)>)>GjoooCXXXr#   c                 b    i | ],\  }}|t          |t                    rt          |          n|-S r(   r)   r,   kvs      r!   
<dictcomp>z9lru_cache_freezeargs.<locals>.wrapped.<locals>.<dictcomp>+   s7    \\\TQ!jD&9&9@Z]]]q\\\r#   c                 Z    g | ](}t          |t                    rt          |          n|)S r(   r   listtupler+   s     r!   r.   z9lru_cache_freezeargs.<locals>.wrapped.<locals>.<listcomp>,   s1    SSSsJsD$9$9BeCjjjsSSSr#   c                 b    i | ],\  }}|t          |t                    rt          |          n|-S r(   r5   r0   s      r!   r3   z9lru_cache_freezeargs.<locals>.wrapped.<locals>.<dictcomp>-   s7    WWW1!At!4!4;U1XXX!WWWr#   )r7   items)argskwargsfuncs     r!   wrappedz%lru_cache_freezeargs.<locals>.wrapped(   s    XXSWXXXYY\\V\\^^\\\SSdSSSTTWWWWWtT$V$$$r#   )	functoolswraps
cache_infocache_clear)r<   r=   s   ` r!   lru_cache_freezeargsrB   "   sO     _T% % % % % G*GNr#   c                   D     e Zd ZdZi Z ej                    Z fdZ xZ	S )SingletonMetaz6
    Metaclass that creates a Singleton instance.
    c                 n   | j         5  | | j        vr$ t                      j        |i |}|| j        | <   nZd|v s|rTt	          |          dk    rAd|v r|                    d          n|d         }| j        |                              |           | j        |          cd d d            S # 1 swxY w Y   d S )Nsessionr   )_lock
_instancessuper__call__lenget_set_session)clsr:   r;   instancerF   	__class__s        r!   rJ   zSingletonMeta.__call__>   s   Y 		' 		'#.((+577+T<V<<&.s## &&4&CIIMM7@F7J7Jfjj333PTUVPWGN3'44W===>#&		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		' 		's   BB**B.1B.)
r   
__module____qualname____doc__rH   	threadingLockrG   rJ   __classcell__)rP   s   @r!   rD   rD   7   sX          JINE
' 
' 
' 
' 
' 
' 
' 
' 
'r#   rD   c                      e Zd ZdZddZd ZddZej        d             Z	ej        d             Z
ej        dd
            Zej        dd            Zej        d             Zej        d             Zej        dd            Zej        dd            Zej        dd            Zej        d d            Zej        d d            Ze ee          dd                        ZddZdedefdZdej        dedej        fdZdS )!YfDataz
    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                     d | _         d | _        d| _        t          j                    | _        d | _        |                     |pt          j	        d                     d S )Nbasicchrome)impersonate)
_crumb_cookie_cookie_strategyrT   rU   _cookie_lock_sessionrM   r   SessionselfrF   s     r!   __init__zYfData.__init__Q   s`     !( &N,,'KX%5(%K%K%KLLLLLr#   c                    |d S 	 |j          d| _        t          d          # t          $ r
 d| _        Y nw xY wt	          |t
          j        j                  s t          dt          |           d          | j	        5  || _
        t          j        j        t          j        j        | j
        _        d d d            d S # 1 swxY w Y   d S )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   rF   rb   r   r`   ra   r   networkproxyproxiesrc   s     r!   rM   zYfData._set_session_   sJ   ?F	lMM (,D$!  #k  l  l  l  	- 	- 	-',D$$$	- '8#3#;<< 	O!  #NdSZmm  #N  #N  #N  O  O  O 	? 	?#DM%1(0(8(>%	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	? 	?s   # 77 4CCCFc                 ,   || j         k    rd S |s| j                                         	 | j         dk    rUt          j                                        d| j          d           | j        j                                         d| _         n6t          j                                        d| j          d           d| _         d | _	        d | _
        n(# t          $ r | j                                          w xY w|s| j                                         d S d S )Ncsrfztoggling cookie strategy z	 -> basicrZ   z -> csrf)r_   r`   acquirer
   get_yf_loggerdebugra   cookiesclearr^   r]   	Exceptionrelease)rd   strategy	have_locks      r!   _set_cookie_strategyzYfData._set_cookie_strategyx   s9   t,,,F 	(%%'''	$..#%%++,hH],h,h,hiii%++---(/%%#%%++,gH],g,g,ghhh(.%DLDKK 	 	 	%%'''	  	(%%'''''	( 	(s   B$C %C4c                     | j         dS | j         j        j        j        }t	          |          dk    rdS d |                                D             }t	          |          dk    rd |D             }t	          |          dk    r+t          j                                        d|            dS t	          |          dk    rdS |d         }|||         i}t          j
                                        d|           dS )	NFr   c                     g | ]}d |v |	S )yahoor(   r,   r1   s     r!   r.   z0YfData._save_cookie_curlCffi.<locals>.<listcomp>   s    @@@A7a<<a<<<r#   r	   c                     g | ]}d |v|	S )consentr(   r{   s     r!   r.   z0YfData._save_cookie_curlCffi.<locals>.<listcomp>   s"    FFF9A3E3E!3E3E3Er#   z1Multiple Yahoo cookies, not sure which to cache: curlCffiT)ra   rq   jar_cookiesrK   keysr
   ro   rp   r   get_cookie_cachestore)rd   rq   
yh_domains	yh_domain	yh_cookies        r!   _save_cookie_curlCffizYfData._save_cookie_curlCffi   s   = 5-'+4w<<15@@@@@
z??QFFZFFFJz??Q!!''(h\f(h(hiii5z??a5qM		 23	  &&z9===tr#   c                    | j         dS t          j                                        d          }|t	          |          dk    rdS |d         }t          |                                          d         }||         d         d         }|j        }|dk    r|dz  }t          j        	                    |t          j
        j        	          }|t          j                            t          j
        j                  k     }|r(t          j                                        d
           dS | j         j        j        j                            |           || _        dS )NFr~   r   cookie/A3g    eAg     @@)tzzcached cookie expiredT)ra   r   r   lookuprK   r6   r   expiresdatetimefromtimestamptimezoneutcnowr
   ro   rp   rq   r   r   updater^   )rd   cookie_dictrq   domainr   	expiry_ts	expiry_dtexpireds           r!   _load_cookie_curlCffizYfData._load_cookie_curlCffi   s1   = 5,..55jAA#k"2"2a"7"75h'gllnn%%a(%d+N	s??#I%33I(BSBW3XX	h/33H4E4IJJJ 	!!''(?@@@5!*11':::tr#      c                    | j         (t          j                                        d           dS |                                 r(t          j                                        d           dS 	 | j                            d|d           nX# t          j        j	        $ rA}t          j                                        dt          |          z              Y d }~dS d }~ww xY w|                                  dS )Nreusing cookieTreusing persistent cookiezhttps://fc.yahoo.comurltimeoutallow_redirectsz$Handling DNS error on cookie fetch: F)r^   r
   ro   rp   r   ra   rL   r   
exceptionsDNSErrorstrr   )rd   r   es      r!   _get_cookie_basiczYfData._get_cookie_basic   s   <#!!''(89994'')) 	!!''(CDDD4		M* $  & & & & "+ 	 	 	 !!''(NQTUVQWQW(WXXX55555		
 	""$$$ts   -B C 6CC c                    | j         -t          j                                        d           | j         S |                                 sd S d|dd}| j        r| j        |d<    | j        j        di |}n | j        j        di |}|j	        | _         |j
        dk    s	d| j         v r<t          j                                        d| j                     t                      | j         	d	| j         v r(t          j                                        d
           d S t          j                                        d| j          d           | j         S )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 = ''r(   )r]   r
   ro   rp   r   rg   _expire_afterra   rL   textstatus_coder   )rd   r   get_argscrumb_responses       r!   _get_crumb_basiczYfData._get_crumb_basic   ss   ;"!!''888;%%'' 	4 G#
 

 # 	;'+'9H^$.T].::::NN.T].::::N$)%,,0Ct{0R0R!!''(M(M(MNNN"$$$;(dk"9"9!!''(>???4##$>$>$>$>???{r#   c                 Z    |                      |          sd S |                     |          S N)r   r   )rd   r   s     r!   _get_cookie_and_crumb_basicz"YfData._get_cookie_and_crumb_basic   s1    %%g.. 	4$$W---r#   c                 j   | j         (t          j                                        d           dS |                                 r/t          j                                        d           d| _         dS d|i}i |ddi}	 | j        r| j        |d<    | j        j        di |}n | j        j        di |}nA# t          j
        j        $ r* t          j                                        d           Y d	S w xY wt          |j        d
          }|                    dddi          }|(t          j                                        d           d	S |d         }t          j                                        d|            |                    dddi          }|d         }	t          j                                        d|	            d}
d}ddgd|	||
|d}i |d|	 |d}i |d|	 |d}	 | j        r9| j        |d<   | j        |d<    | j        j        di |  | j        j        di | n$ | j        j        di |  | j        j        di | n@# t          j
        j        $ r) t          j                                        d           Y nw xY wd| _         |                                  dS )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/rz   agreedefault)r   consentUUIDr   r   originalDoneUrl	namespacez6https://consent.yahoo.com/v2/collectConsent?sessionId=)r   dataz-https://guce.yahoo.com/copyConsent?sessionId=r(   )r^   r
   ro   rp   r   rg   r   ra   rL   r   r   r   r   contentfindpostr   )rd   r   	base_argsr   responsesoupcsrfTokenInputr   sessionIdInputr   r   r   r   	post_argss                 r!   _get_cookie_csrfzYfData._get_cookie_csrf   s   <#!!''(89994'')) 	!!''(CDDDDL4 w 	 JiI(HII		' 9+/+=(,4=,88x88,4=,88x88"7 	 	 	!!''(|}}}55	
 X-}==76;2GHH!!!''(PQQQ5"7+	##$>9$>$>???76;2GHH"7+	##$=)$=$=>>>6	w'$""."
 
y WIWW  	i N9NN  	~' .,0,>	.)+/+=(""//Y///!!--H----""//Y///!!--H---"7 	~ 	~ 	~!!''(|}}}}}	~ ""$$$ts%    6B7 7:C54C53A$I :JJc                    | j         -t          j                                        d           | j         S |                     |          sd S d|d}| j        r| j        |d<    | j        j        di |}n | j        j        di |}|j	        | _         |j
        dk    s	d| j         v r<t          j                                        d| j                     t                      | j         d| j         v s| j         d	k    r(t          j                                        d
           d S t          j                                        d| j          d           | j         S )Nr   z1https://query2.finance.yahoo.com/v1/test/getcrumb)r   r   r   r   r   r   r    r   r   r   r(   )r]   r
   ro   rp   r   rg   r   ra   rL   r   r   r   )rd   r   r   rs       r!   _get_crumb_csrfzYfData._get_crumb_csrf=  s~    ;"!!''888;$$W-- 	4 G    # 	.'+'9H^$!!--H--AA!!--H--Af=C#6$+#E#E!!''(M(M(MNNN"$$$;(dk"9"9T[B=N=N!!''(>???4##$>$>$>$>???{r#   c                    d\  }}t          j                                        d| j         d           | j        5  | j        dk    rC|                                 }|,|                     dd           |                     |          }nB|                     |          }|+|                     dd           |                                 }| j        }d d d            n# 1 swxY w Y   ||fS )N)NNzcookie_mode = 'r   rm   rZ   T)rv   )r
   ro   rp   r_   r`   r   rw   r   )rd   r   crumbru   s       r!   _get_cookie_and_crumbzYfData._get_cookie_and_crumb^  s>   $x##$Nd6K$N$N$NOOO 	- 	-$..,,..=--g-FFF <<WEEE 88AA=--f-EEE 0022E,H	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- hs   BC  C$'C$c                     |                      || j        j        ||          }|                     |j                  sn|                     ||          }|S )N)request_methodparamsr   )_make_requestra   rL   _is_this_consent_urlr   _accept_consent_formrd   r   r   r   r   s        r!   rL   z
YfData.getu  s_    %%cDM<MV\fm%nn ((66 	D 007CCHr#   c                 L    |                      || j        j        ||||          S )N)r   bodyr   r   r   )r   ra   r   )rd   r   r   r   r   r   s         r!   r   zYfData.post  s9    !!#8JQU^dnu  }A!  B  B  	Br#   c                    t          |          dk    r3t          j                                        d|d d          d           n)t          j                                        d|            t          j                                        d|            t          j        j        | j        _        |i }d|v rt          d          | 
                                \  }}|d|i}	ni }	|i ||	|d}
|r||
d<   |r||
d	<   d
di|
d<   t          t          j        j        dz             D ]`}	  |di |
} nT# t          $ rG}t          |          r-|t          j        j        k     rt          j        d|z             n Y d }~Yd }~ww xY wt          j                                        d|j                    |j        dk    r|dk    r|                     d           n|                     d           | 
                    |          \  }}||
d         d<    |di |
}t          j                                        d|j                    |j        dk    rt'                      |S )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  rZ   rm   r   r   r(   )rK   r
   ro   rp   r   ri   rj   ra   rk   r   r   rangeretriesrs   r"   _timesleepr   rw   r   )rd   r   r   r   r   r   r   r   ru   crumbsrequest_argsattemptr   r   s                 r!   r   zYfData._make_request  s    s88c>>!!''(=s4C4y(=(=(=>>>>!!''s555##$6f$6$6777 !) 0 6>Ff`aaa4466xu%FFF **6*
 
  	(#'L  	K#'L '57I&JL#X-59:: 	 	G)>99L99   &q)) g8H8P.P.PKW---- .----
 	##$KX5I$K$KLLL3&&7""))&1111))'222"88AAOE8.3L"7+%~5555H!!''(O9M(O(OPPP #s**&(((s   .D88
F	=FF	)maxsizec                 0    |                      |||          S r   )rL   )rd   r   r   r   s       r!   	cache_getzYfData.cache_get  s     xxVW---r#   c                     t          j                                        d|            |                     |||          }|                                 |                                S )Nzget_raw_json(): )r   r   )r
   ro   rp   rL   raise_for_statusr   r   s        r!   get_raw_jsonzYfData.get_raw_json  s_    ##$<s$<$<===88C8@@!!###}}r#   response_urlreturnc                     	 t          |          j        o&t          |          j                            d          S # t          $ r Y dS w xY w)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endswithrs   )rd   r   s     r!   r   zYfData._is_this_consent_url  sb    	L))2 5x8 8xx 3445  	 	 	55	s   := 
A
Aconsent_respr   c                 "   t          |j        d          }|                    d          }|s|S |                    d          p|j        }t          |j        |          }	 i }|                    d          D ]}|                    d          }|s|                    d          pd                                }	|                    d          pd	}
|	d
v rOd|                                v s+d|                                v s|                    d          r|
d	k    r|
nd||<   |
||<   d |	                                D             }t          d |D                       sd|d<   d|j        i}| j                            ||||d          }|S )a  
        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                 6    h | ]}|                                 S r(   )lowerr{   s     r!   	<setcomp>z.YfData._accept_consent_form.<locals>.<setcomp>  s     22217799222r#   c              3   &   K   | ]}d |v pd|v V  dS )r   r   Nr(   r{   s     r!   	<genexpr>z.YfData._accept_consent_form.<locals>.<genexpr>  s/      DDqGqL1HMDDDDDDr#   RefererT)r   r   r   r   )r   r   r   rL   r   r   find_allr  has_attrr   anyra   r   )rd   r   r   r   r   r   r   inpr   typvalloweredr   r   s                 r!   r   zYfData._accept_consent_form  s    \.>> yy   	  (##7|'7)622	 ==)) 	! 	!C776??D 776??,f3355C'''""(bC+++ tzz||++4::<<//||I.. 0 ),r		sDJ T

 32diikk222DDGDDDDD 	 DM l./=%%wQU & 
 
 r#   r   )F)r   )Nr   )NNr   N) r   rQ   rR   rS   re   rM   rw   r
   log_indent_decoratorr   r   r   r   r   r   r   r   rL   r   r   rB   r   cache_maxsizer   r   r   boolr   r   Responseintr   r(   r#   r!   rX   rX   K   s|        
M M M M? ? ?2( ( ( (.    (    ,     .     < . .  .
 B B  BH     @     ,      B B B  B = = =  =~ Y}%%%. . . &% .        $<$-<8;<		< < < < < <r#   rX   )	metaclass)r>   r   r   timer   	curl_cffir   urllib.parser   r   bs4r   r   r   r   r
   r   configr   rT   r   r   r   r   r"   r  rB   r   rD   rX   r(   r#   r!   <module>r     sv                        * * * * * * * *        ! ! ! ! ! !                   F F F F F F F F F F	4 	4 	4   *' ' ' ' 'D ' ' '(U U U U U} U U U U U Ur#   