
    hYN                         d dl Z d dl m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Zdd	lmZm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)YFRateLimitErrorYFDataException@   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  
isinstancedictr   .0args     K/var/www/html/marketdash/venv/lib/python3.11/site-packages/yfinance/data.py
<listcomp>z9lru_cache_freezeargs.<locals>.wrapped.<locals>.<listcomp>   s1    XXXCC)>)>GjoooCXXX    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   r"   r   s      r   r    z9lru_cache_freezeargs.<locals>.wrapped.<locals>.<dictcomp>   s7    WWW1!At!4!4;U1XXX!WWWr   )r$   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_freezeargsr/      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                 "   | j         5  | | j        vr$ t                      j        |i |}|| j        | <   nd|v s|rTt	          |          dk    rAd|v r|                    d          n|d         }| j        |                              |           d|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   proxyr	   )_lock
_instancessuper__call__lenget_set_session
_set_proxy)clsr'   r(   instancer3   r4   	__class__s         r   r8   zSingletonMeta.__call__/   so   Y 	' 	'#.((+577+T<V<<&.s## &&4&CIIMM7@F7J7Jfjj333PTUVPWGN3'44W===f$$$#d))a--3:f3D3DFJJw///$q'EN3'225999>#&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   C.DDD)
__name__
__module____qualname____doc__r6   	threadingLockr5   r8   __classcell__)r?   s   @r   r1   r1   (   sX          JINE' ' ' ' ' ' ' ' 'r   r1   c                      e Zd ZdZddZd Zd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NNchrome)impersonate)_crumb_cookie_cookie_strategyrD   rE   _cookie_lock_session_proxyr;   r   Sessionr<   )selfr3   r4   s      r   __init__zYfData.__init__E   sy     !( &N,,%/"t{'KX%5(%K%K%KLLLr   c                 t   |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  || _
        | 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   r3   rT   typerQ   rR   rS   proxies)rU   r3   s     r   r;   zYfData._set_sessionT   sB   ?F	lMM (,D$!  #k  l  l  l  	- 	- 	-',D$$$	- '8#3#;<< 	O!  #NdSZmm  #N  #N  #N  O  O  O 	4 	4#DM{&(,%	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4s   # 77  B--B14B1c                     | j         5  |t          |t                    r||dn|}ni }|| _        || j        _        d d d            d S # 1 swxY w Y   d S )N)httphttps)rQ   r   strrS   rR   r[   )rU   r4   s     r   r<   zYfData._set_proxym   s     	* 	* ;EeS;Q;Q\777W\DK$)DM!	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*s   5A

AA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	 -> basicrJ   z -> csrf)rP   rQ   acquirer
   get_yf_loggerdebugrR   cookiesclearrO   rN   	Exceptionrelease)rU   strategy	have_locks      r   _set_cookie_strategyzYfData._set_cookie_strategyv   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   r   s     r   r   z0YfData._save_cookie_curlCffi.<locals>.<listcomp>   s    @@@A7a<<a<<<r   r	   c                     g | ]}d |v|	S )consentr   ro   s     r   r   z0YfData._save_cookie_curlCffi.<locals>.<listcomp>   s"    FFF9A3E3E!3E3E3Er   z1Multiple Yahoo cookies, not sure which to cache: curlCffiT)rR   re   jar_cookiesr9   keysr
   rc   rd   r   get_cookie_cachestore)rU   re   
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 )NFrr   r   cookie/A3g    eAg     @@)tzzcached cookie expiredT)rR   r   rv   lookupr9   r#   ru   expiresdatetimefromtimestamptimezoneutcnowr
   rc   rd   re   rs   rt   updaterO   )rU   cookie_dictre   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                 x   | j         (t          j                                        d           dS |                                 r(t          j                                        d           dS 	 | j                            d|d           n# t          j        j	        $ r Y dS w xY w| 
                                 dS )Nreusing cookieTreusing persistent cookiezhttps://fc.yahoo.comurltimeoutallow_redirectsF)rO   r
   rc   rd   r   rR   r:   r   
exceptionsDNSErrorr{   rU   r   s     r   _get_cookie_basiczYfData._get_cookie_basic   s    <#!!''(89994'')) 	!!''(CDDD4	M* $  & & & & "+ 	 	 	55	 	""$$$ts   -B B#"B#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   )rN   r
   rc   rd   r   rX   _expire_afterrR   r:   textstatus_coder   )rU   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   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/rn   agreedefault)r   consentUUIDr   r   originalDoneUrl	namespacez6https://consent.yahoo.com/v2/collectConsent?sessionId=)r   dataz-https://guce.yahoo.com/copyConsent?sessionId=r   )rO   r
   rc   rd   r   rX   r   rR   r:   r   r   ChunkedEncodingErrorr   contentfindpostr{   )rU   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   )rN   r
   rc   rd   r   rX   r   rR   r:   r   r   r   )rU   r   r   rs       r   _get_crumb_csrfzYfData._get_crumb_csrf9  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 )NrK   zcookie_mode = 'r   ra   rJ   T)rj   )r
   rc   rd   rP   rQ   r   rk   r   )rU   r   crumbri   s       r   _get_cookie_and_crumbzYfData._get_cookie_and_crumbZ  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_requestrR   r:   _is_this_consent_urlr   _accept_consent_formrU   r   r   r   r   s        r   r:   z
YfData.getq  s_    %%cDM<MV\fm%nn ((66 	D 007CCHr   c                 J    |                      || j        j        |||          S )N)r   bodyr   r   )r   rR   r   )rU   r   r   r   r   s        r   r   zYfData.post  s)    !!#8JQU^dnu!vvvr   c                    t          |          dk    r3t          j                                        d|d d          d           n)t          j                                        d|            t          j                                        d|            |i }d|v rt	          d          |                                 \  }}|d|i}ni }|i |||d}	|r||	d<    |di |	}
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   jsonzresponse code=i  rJ   ra   r   r   r   )	r9   r
   rc   rd   rg   r   r   rk   r   )rU   r   r   r   r   r   r   ri   crumbsrequest_argsr   s              r   r   zYfData._make_request  s    s88c>>!!''(=s4C4y(=(=(=>>>>!!''s555##$6f$6$6777>Ff^___4466xu%FFF **6*
 
  	(#'L !>11L11##$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**&(((r   )maxsizec                 0    |                      |||          S r   )r:   )rU   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
   rc   rd   r:   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endswithrg   )rU   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   rZ   r   r   r   )checkboxradior   acceptchecked1c                 6    h | ]}|                                 S r   )lowerro   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   ro   s     r   	<genexpr>z.YfData._accept_consent_form.<locals>.<genexpr>  s/      DDqGqL1HMDDDDDDr   RefererT)r   headersr   r   )r   r   r   r:   r   r   find_allr   has_attrru   anyrR   r   )rU   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   rK   r   )F)r   )Nr   )NNr   )!r@   rA   rB   rC   rV   r;   r<   rk   r
   log_indent_decoratorr{   r   r   r   r   r   r   r   r:   r   r   r/   r   cache_maxsizer   r   r_   boolr   r   Responseintr   r   r   r   rH   rH   ?   s        
   4 4 42* * * *( ( ( (.    (    ,     *     < . .  .
 B B  BH     @     ,      w w w  w . . .  .` Y}%%%. . . &% .        $<$-<8;<		< < < < < <r   rH   )	metaclass)r+   r   	curl_cffir   urllib.parser   r   bs4r   r   r   r   r
   r   rD   r   r   r   r   r/   rZ   r1   rH   r   r   r   <module>r     s8                   * * * * * * * *        ! ! ! ! ! !             9 9 9 9 9 9 9 9  *' ' ' ' 'D ' ' '.N N N N N} N N N N N Nr   