
    gN                       U d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ ddlmZmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZmZmZm Z m!Z! ddl"m#Z#m$Z$m%Z%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ ddl,m-Z- erddl.m/Z/ ddl0m1Z1  ee2      Z3de4d<   ejj                  Z6 G d d      Z7 G d d      Z8d dZ9 G d d      Z: G d d      Z;	 	 	 	 	 	 	 	 	 	 	 	 d!dZ<d"dZ=d#dZ>y)$zACommon cache logic shared by st.cache_data and st.cache_resource.    )annotationsN)abstractmethod)defaultdict)TYPE_CHECKINGAnyCallableFinal)	type_util)is_unevaluated_data_object)spinner)
get_logger)
CacheErrorCacheKeyNotFoundErrorUnevaluatedDataFrameErrorUnhashableParamErrorUnhashableTypeErrorUnserializableReturnValueErrorget_cached_func_name_md)CachedMessageReplayContextCachedResultMsgDatareplay_cached_messages)HashFuncsDictupdate_hash)in_cached_function)HASHLIB_KWARGS)FunctionType)	CacheTyper	   _LOGGERc                  `    e Zd ZdZd Zed	d       Zed
d       ZddZdddZ	eddd       Z
y)Cachez<Function cache interface. Caches persist across script runs.c                r    t        t        j                        | _        t        j                         | _        y N)r   	threadingLock_value_locks_value_locks_lockselfs    Z/var/www/openai/venv/lib/python3.12/site-packages/streamlit/runtime/caching/cache_utils.py__init__zCache.__init__E   s"    7B9>>7R!*!1    c                    t         )zRead a value and associated messages from the cache.

        Raises
        ------
        CacheKeyNotFoundError
            Raised if value_key is not in the cache.

        NotImplementedErrorr)   	value_keys     r*   read_resultzCache.read_resultI   s
     "!r,   c                    t         )z}Write a value and associated messages to the cache, overwriting any existing
        result that uses the value_key.
        r.   )r)   r1   valuemessagess       r*   write_resultzCache.write_resultU   s
     "!r,   c                d    | j                   5  | j                  |   cddd       S # 1 sw Y   yxY w)ap  Return the lock that should be held while computing a new cached value.
        In a popular app with a cache that hasn't been pre-warmed, many sessions may try
        to access a not-yet-cached value simultaneously. We use a lock to ensure that
        only one of those sessions computes the value, and the others block until
        the value is computed.
        N)r'   r&   r0   s     r*   compute_value_lockzCache.compute_value_lock^   s'     ##$$Y/ $##s   &/Nc                    | j                   5  |s| j                  j                          n|| j                  v r| j                  |= ddd       | j                  |       y# 1 sw Y   xY w)zClear values from this cache.
        If no argument is passed, all items are cleared from the cache.
        A key can be passed to clear that key from the cache only.Nkey)r'   r&   clear_clearr)   r;   s     r*   r<   zCache.clearh   s\     ##!!''))))%%c*	 $
 	 $#s   9A!!A*c                    t         )z?Subclasses must implement this to perform cache-clearing logic.r.   r>   s     r*   r=   zCache._clears   s
     "!r,   )r1   strreturnr   )r1   r@   r4   r   r5   zlist[MsgData]rA   None)r1   r@   rA   zthreading.Lockr#   )r;   
str | None)r;   rC   rA   rB   )__name__
__module____qualname____doc__r+   r   r2   r6   r8   r<   r=    r,   r*   r!   r!   B   sP    F2 	" 	" " "0	 " "r,   r!   c                  P    e Zd ZdZ	 	 	 	 	 	 ddZedd       Zed	d       Zd
dZy)CachedFuncInfozEncapsulates data for a cached function instance.

    CachedFuncInfo instances are scoped to a single script run - they're not
    persistent.
    c                .    || _         || _        || _        y r#   )funcshow_spinner
hash_funcs)r)   rL   rM   rN   s       r*   r+   zCachedFuncInfo.__init__   s     	($r,   c                    t         r#   r.   r(   s    r*   
cache_typezCachedFuncInfo.cache_type       !!r,   c                    t         r#   r.   r(   s    r*   cached_message_replay_ctxz(CachedFuncInfo.cached_message_replay_ctx   rQ   r,   c                    t         )z3Get or create the function cache for the given key.r.   )r)   function_keys     r*   get_function_cachez!CachedFuncInfo.get_function_cache   rQ   r,   N)rL   r   rM   z
bool | strrN   HashFuncsDict | None)rA   r   )rA   r   )rU   r@   rA   r!   )	rD   rE   rF   rG   r+   propertyrP   rS   rV   rH   r,   r*   rJ   rJ   y   sU    %% !% )	% " " " ""r,   rJ   c                X    t        |       }t        j                  || j                        S )aa  Create a callable wrapper around a CachedFunctionInfo.

    Calling the wrapper will return the cached value if it's already been
    computed, and will call the underlying function to compute and cache the
    value otherwise.

    The wrapper also has a `clear` function that can be called to clear
    some or all of the wrapper's cached values.
    )
CachedFunc	functoolsupdate_wrapperrL   )infocached_funcs     r*   make_cached_func_wrapperr_      s%     T"K##K;;r,   c                  ,    e Zd ZdZddZddZd Zd Zy)	BoundCachedFunczwA wrapper around a CachedFunc that binds it to a specific instance in case of
    decorated function is a class method.c                     || _         || _        y r#   _cached_func	_instance)r)   r^   instances      r*   r+   zBoundCachedFunc.__init__   s    '!r,   c                B     | j                   | j                  g|i |S r#   rc   r)   argskwargss      r*   __call__zBoundCachedFunc.__call__   s#     t  A$A&AAr,   c                d    d| j                   j                  j                   d| j                   dS )Nz<BoundCachedFunc: z of >)rd   _inforL   re   r(   s    r*   __repr__zBoundCachedFunc.__repr__   s0    #D$5$5$;$;$@$@#AdnnEUUVWWr,   c                    |s|r+ | j                   j                  | j                  g|i | y | j                   j                          y r#   )rd   r<   re   rh   s      r*   r<   zBoundCachedFunc.clear   sA    6 $D##DNNDTDVD ##%r,   N)r^   rZ   rf   r   rA   r   )rD   rE   rF   rG   r+   rk   ro   r<   rH   r,   r*   ra   ra      s    -"BX&r,   ra   c                  n    e Zd Zd
dZd ZddZddZ	 d	 	 	 	 	 	 	 ddZddZ	 	 	 	 	 	 	 	 	 	 ddZ	d	 Z
y)rZ   c                \    || _         t        |j                  |j                        | _        y r#   )rn   _make_function_keyrP   rL   _function_key)r)   r]   s     r*   r+   zCachedFunc.__init__   s     
/Kr,   c                6    d| j                   j                   dS )Nz<CachedFunc: rm   )rn   rL   r(   s    r*   ro   zCachedFunc.__repr__   s    tzz/q11r,   Nc                J    || S t        j                  t        | |      |       S )zCCachedFunc implements descriptor protocol to support cache methods.)r[   r\   ra   )r)   rf   owners      r*   __get__zCachedFunc.__get__   s'    K''h(GNNr,   c                d   d}t        | j                  j                  t              r| j                  j                  }na| j                  j                  du rI| j                  j                  j
                  }t        |      dk(  rt        |      dk(  rd| d}nd| d}| j                  |||      S )zEThe wrapper. We'll only call our underlying function on a cache miss.NTr   z	Running `z()`.z(...)`.)
isinstancern   rM   r@   rL   rF   len_get_or_create_cached_value)r)   ri   rj   spinner_messagenames        r*   rk   zCachedFunc.__call__   s     '+djj--s3"jj55OZZ$$,::??//D4yA~#f+"2$-dV4"8$-dV7";//foNNr,   c                P   | j                   j                  | j                        }t        | j                   j                  | j                   j
                  ||| j                   j                        }t        j                  t              5  |j                  |      }| j                  |      cd d d        S # 1 sw Y   nxY wt        j                         }||st        |d      nt        j                         }|5  | j!                  ||||      cd d d        S # 1 sw Y   y xY w)NrP   rL   	func_argsfunc_kwargsrN   T)_cache)rn   rV   ru   _make_value_keyrP   rL   rN   
contextlibsuppressr   r2   _handle_cache_hitr   getr   nullcontext_handle_cache_miss)	r)   r   r   r~   cacher1   cached_resultis_nested_cache_functionspinner_or_no_contexts	            r*   r}   z&CachedFunc._get_or_create_cached_value   s     

--d.@.@A $zz,,#zz,,
	   !67!--i8M))-8 877 $6#9#9#;  *3K OD1'') 	
 #**5)YT #""s   "B77C >DD%c                    t        || j                  j                  | j                  j                         |j                  S )zVHandle a cache hit: replay the result's cached messages, and return its
        value.)r   rn   rP   rL   r4   )r)   results     r*   r   zCachedFunc._handle_cache_hit  s3     	JJ!!JJOO	

 ||r,   c           
        |j                  |      5  	 |j                  |      }| j                  |      cddd       S # t        $ r Y nw xY w| j                  j
                  j                  | j                  j                        5   | j                  j                  |i |}ddd       n# 1 sw Y   nxY w| j                  j
                  j                  }	 |j                  ||       |cddd       S # t        t        f$ rt}t              rCt        dt        | j                  j                         dt        j                   |       d      |t#        || j                  j                        d}~ww xY w# 1 sw Y   yxY w)zHandle a cache miss: compute a new cached value, write it back to the cache,
        and return that newly-computed value.
        NzThe function zV is decorated with `st.cache_data` but it returns an unevaluated data object of type `z`. Please convert the object to a serializable format (e.g. Pandas DataFrame) before returning it, so `st.cache_data` can serialize and cache it.)return_valuerL   )r8   r2   r   r   rn   rS   calling_cached_functionrL   _most_recent_messagesr6   r   RuntimeErrorr   r   r   r
   get_fqn_typer   )	r)   r   r1   r   r   r   computed_valuer5   exs	            r*   r   zCachedFunc._handle_cache_miss  sp   : %%i0 % 1 1) <--m< 10 )   55MM

 "1)!K{!K   zz;;QQH""9nhG%1 102 - 
 .n= 4'(?

(P'Q R0090F0F~0V/W XFF  5!/djjoo #3 10s]   E>!?	AE>
A<E>B-$	E>-B6	2'E>C88E;A/E66E;;E>>Fc                   | j                   j                  | j                        }|s|rMt        | j                   j                  | j                   j
                  ||| j                   j                        }nd}|j                  |       y)a  Clear the cached function's associated cache.

        If no arguments are passed, Streamlit will clear all values cached for
        the function. If arguments are passed, Streamlit will clear the cached
        value for these arguments only.

        Parameters
        ----------

        *args: Any
            Arguments of the cached functions.

        **kwargs: Any
            Keyword arguments of the cached function.

        Example
        -------
        >>> import streamlit as st
        >>> import time
        >>>
        >>> @st.cache_data
        >>> def foo(bar):
        >>>     time.sleep(2)
        >>>     st.write(f"Executed foo({bar}).")
        >>>     return bar
        >>>
        >>> if st.button("Clear all cached values for `foo`", on_click=foo.clear):
        >>>     foo.clear()
        >>>
        >>> if st.button("Clear the cached value of `foo(1)`"):
        >>>     foo.clear(1)
        >>>
        >>> foo(1)
        >>> foo(2)

        r   Nr:   )rn   rV   ru   r   rP   rL   rN   r<   )r)   ri   rj   r   r;   s        r*   r<   zCachedFunc.clear[  sn    J 

--d.@.@A6!::00ZZ__"::00C Cr,   )r]   rJ   r#   rq   )r   tuple[Any, ...]r   dict[str, Any]r~   rC   rA   r   )r   r   rA   r   )
r   r!   r1   r@   r   r   r   r   rA   r   )rD   rE   rF   r+   ro   ry   rk   r}   r   r   r<   rH   r,   r*   rZ   rZ      s    L2OO& '+	(U"(U $(U $	(U
 
(UTII I #	I
 $I 
IV0r,   rZ   c           	     <   g }t        t        |            D ]$  }t        ||      }|j                  |||   f       & |j	                         D ]  \  }}	|j                  ||	f        t        j                  di t        }
|D ]O  \  }}|(|j                  d      rt        j                  d|       0	 t        ||
| |       t        ||
| ||       Q |
j                         }t        j                  d|       |S # t        $ r}t        | ||||      d}~ww xY w)aP  Create the key for a value within a cache.

    This key is generated from the function's arguments. All arguments
    will be hashed, except for those named with a leading "_".

    Raises
    ------
    StreamlitAPIException
        Raised (with a nicely-formatted explanation message) if we encounter
        an un-hashable arg.
    N_z'Not hashing %s because it starts with _hasherrP   hash_source)r   rP   rN   r   zCache key: %smd5)ranger|   _get_positional_arg_nameappenditemshashlibnewr   
startswithr   debugr   r   r   	hexdigest)rP   rL   r   r   rN   	arg_pairsarg_idxarg_namekw_namekw_valargs_hasher	arg_valueexcr1   s                 r*   r   r     s3   * /1IY(+D':(Ig$678 ) ',,. 	'6*+	 / ++6~6K()H$7$7$<MMCXN	S"% 	 "%%   )2 %%'IMM/9- # 	S&z49cRR	Ss   5C>>	DDDc                n   t        j                  di t        }t        |j                  |j
                  f|| |       	 t        j                  |      }t        ||| |       |j                         S # t        $ r7}t        j                  d|       |j                  j                  }Y d}~Zd}~ww xY w)zCreate the unique key for a function's cache.

    A function's key is stable across reruns of the app, and changes when
    the function's source code changes.
    r   zZFailed to retrieve function's source code when building its key; falling back to bytecode.)exc_infoNr   )r   r   r   r   rE   rF   inspect	getsourceOSErrorr   r   __code__co_coder   )rP   rL   func_hashersource_coder   s        r*   rt   rt     s     ++6~6K 	$++,	,''- KJD   ""  ,( 	 	

 mm++,s    A4 4	B4=-B//B4c                >   |dk  ryt        t        j                  |       j                  j	                               }|t        |      k\  ry||   j                  t        j                  j                  t        j                  j                  fv r||   j                  S y)zReturn the name of a function's positional argument.

    If arg_index is out of range, or refers to a parameter that is not a
    named positional argument (e.g. an *args, **kwargs, or keyword-only param),
    return None instead.
    r   N)listr   	signature
parametersvaluesr|   kind	ParameterPOSITIONAL_OR_KEYWORDPOSITIONAL_ONLYr   )rL   	arg_indexparamss      r*   r   r     s     1}&*7+<+<T+B+M+M+T+T+V&WFCKi//))"  i %%%r,   )r]   rJ   rA   zCallable[..., Any])rP   r   rL   r   r   r   r   r   rN   rW   rA   r@   )rP   r   rL   r   rA   r@   )rL   r   r   intrA   rC   )?rG   
__future__r   r   r[   r   r   r$   timeabcr   collectionsr   typingr   r   r   r	   	streamlitr
   streamlit.dataframe_utilr   streamlit.elements.spinnerr   streamlit.loggerr   &streamlit.runtime.caching.cache_errorsr   r   r   r   r   r   r   /streamlit.runtime.caching.cached_message_replayr   r   r   r   !streamlit.runtime.caching.hashingr   r   7streamlit.runtime.scriptrunner_utils.script_run_contextr   streamlit.utilr   typesr   $streamlit.runtime.caching.cache_typer   rD   r   __annotations__	monotonicTTLCACHE_TIMERr!   rJ   r_   ra   rZ   r   rt   r   rH   r,   r*   <module>r      s   H "        # 6 6  ? . '    I *">H% % 4" 4"n" "<<& &2M M`@@
@ @  	@
 %@ 	@F$#Nr,   