
    &eE                       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	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 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#m$Z$ ddl%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0  ee1          Z2ej3        Z4ed9d            Z5ed:d            Z5ddd;dZ5dZ6 G d d           Z7 G d! d"          Z8d<d%Z9 G d& d'          Z:d=d3Z;d>d4Z<d?d8Z=dS )@zACommon cache logic shared by st.cache_data and st.cache_resource.    )annotationsN)abstractmethod)defaultdict)	timedelta)AnyCallableoverload)Literal)	type_util)spinner)
get_logger)BadTTLStringError
CacheErrorCacheKeyNotFoundErrorUnevaluatedDataFrameErrorUnhashableParamErrorUnhashableTypeErrorUnserializableReturnValueErrorget_cached_func_name_md)	CacheType)CachedMessageReplayContextCachedResultMsgDatareplay_cached_messages)HashFuncsDictupdate_hash)HASHLIB_KWARGSttlfloat | timedelta | str | Nonecoerce_none_to_infLiteral[False]returnfloat | Nonec                   d S N )r   r    s     Elib/python3.11/site-packages/streamlit/runtime/caching/cache_utils.pyttl_to_secondsr(   ?   s	     C    floatc                    d S r%   r&   )r   s    r'   r(   r(   F   s    Cr)   T)r    boolc                  |r| t           j        S t          | t                    r|                                 S t          | t
                    ryddl}ddl}	 |                    |                                           }n"# t          $ r}t          |           |d}~ww xY w|                    |          rt          |           |S | S )zJ
    Convert a ttl value to a float representing "number of seconds".
    Nr   )mathinf
isinstancer   total_secondsstrnumpypandas	Timedelta
ValueErrorr   isnan)r   r    nppdoutexs         r'   r(   r(   K   s      ckx#y!! #  """#s 	1c**88::CC 	1 	1 	1#C((b0	1 88C== 	)#C(((
Js   'B   
B
BB)zsnowflake.snowpark.table.Tablez&snowflake.snowpark.dataframe.DataFramezpyspark.sql.dataframe.DataFramec                  n    e Zd ZdZd Zedd            Zedd            ZddZd Z	edd            Z
dS )Cachez<Function cache interface. Caches persist across script runs.c                r    t          t          j                  | _        t          j                    | _        d S r%   )r   	threadingLock_value_locks_value_locks_lockselfs    r'   __init__zCache.__init__r   s*    7B9>7R7R!*!1!1r)   	value_keyr2   r"   r   c                    t           )zRead a value and associated messages from the cache.

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

        NotImplementedErrorrD   rF   s     r'   read_resultzCache.read_resultv   s
     "!r)   valuer   messageslist[MsgData]Nonec                    t           )z}Write a value and associated messages to the cache, overwriting any existing
        result that uses the value_key.
        rH   )rD   rF   rL   rM   s       r'   write_resultzCache.write_result   s
     "!r)   threading.Lockc                ^    | j         5  | j        |         cddd           S # 1 swxY w Y   dS )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)rB   rA   rJ   s     r'   compute_value_lockzCache.compute_value_lock   s|     # 	0 	0$Y/	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0s   "&&c                    | j         5  | j                                         ddd           n# 1 swxY w Y   |                                  dS )z!Clear all values from this cache.N)rB   rA   clear_clearrC   s    r'   rV   zCache.clear   s    # 	& 	&##%%%	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&s   .22c                    t           )z?Subclasses must implement this to perform cache-clearing logic.rH   rC   s    r'   rW   zCache._clear   s
     "!r)   N)rF   r2   r"   r   )rF   r2   rL   r   rM   rN   r"   rO   )rF   r2   r"   rR   )r"   rO   )__name__
__module____qualname____doc__rE   r   rK   rQ   rT   rV   rW   r&   r)   r'   r=   r=   o   s        FF2 2 2 	" 	" 	" ^	" " " " ^"0 0 0 0   " " " ^" " "r)   r=   c                  R    e Zd ZdZdd
Zedd            Zedd            ZddZdS )CachedFuncInfozEncapsulates data for a cached function instance.

    CachedFuncInfo instances are scoped to a single script run - they're not
    persistent.
    functypes.FunctionTypeshow_spinner
bool | strallow_widgetsr,   
hash_funcsHashFuncsDict | Nonec                >    || _         || _        || _        || _        d S r%   )r_   ra   rc   rd   )rD   r_   ra   rc   rd   s        r'   rE   zCachedFuncInfo.__init__   s&     	(*$r)   r"   r   c                    t           r%   rH   rC   s    r'   
cache_typezCachedFuncInfo.cache_type       !!r)   r   c                    t           r%   rH   rC   s    r'   cached_message_replay_ctxz(CachedFuncInfo.cached_message_replay_ctx   ri   r)   function_keyr2   r=   c                    t           )z3Get or create the function cache for the given key.rH   )rD   rl   s     r'   get_function_cachez!CachedFuncInfo.get_function_cache   ri   r)   N)r_   r`   ra   rb   rc   r,   rd   re   )r"   r   )r"   r   )rl   r2   r"   r=   )	rY   rZ   r[   r\   rE   propertyrh   rk   rn   r&   r)   r'   r^   r^      s         
% 
% 
% 
% " " " X" " " " X"" " " " " "r)   r^   infoCallable[..., Any]c                    t          |           t          j        | j                  fd            }j        |_        |S )aY  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
    all of the wrapper's cached values.
    c                      | i |S r%   r&   )argskwargscached_funcs     r'   wrapperz)make_cached_func_wrapper.<locals>.wrapper   s    {D+F+++r)   )
CachedFunc	functoolswrapsr_   rV   )rp   rw   rv   s     @r'   make_cached_func_wrapperr{      sU     T""K _TY, , , ,  ,
  %GMNr)   c                  <    e Zd ZddZddZddZddZddZd ZdS )rx   rp   r^   c                R    || _         t          |j        |j                  | _        d S r%   )_info_make_function_keyrh   r_   _function_key)rD   rp   s     r'   rE   zCachedFunc.__init__   s%    
/KKr)   r"   r   c                   | j         j        j        }t          | j         j        t
                    r4t          |          dk    rt          |          dk    rd| d}nd| d}n| j         j        }| j         j        st          | j         j        t                    rAt          |d          5  | 	                    ||          cddd           S # 1 swxY w Y   dS | 	                    ||          S )zEThe wrapper. We'll only call our underlying function on a cache miss.r   z	Running `z()`.z(...)`.T)cacheN)
r~   r_   r[   r0   ra   r,   lenr2   r   _get_or_create_cached_value)rD   rt   ru   namemessages        r'   __call__zCachedFunc.__call__   sO    z+dj-t44 	.4yyA~~#f++"2"20d0003d333j-G:" 	Bj1H#&N&N 	B--- F F77fEEF F F F F F F F F F F F F F F F F F 33D&AAAs   -CCC	func_argstuple[Any, ...]func_kwargsdict[str, Any]c                J   | j                             | j                  }t          | j         j        | j         j        ||| j         j                  }	 |                    |          }|                     |          S # t          $ r | 
                    ||||          cY S w xY w)N)rh   r_   r   r   rd   )r~   rn   r   _make_value_keyrh   r_   rd   rK   _handle_cache_hitr   _handle_cache_miss)rD   r   r   r   rF   cached_results         r'   r   z&CachedFunc._get_or_create_cached_value   s     
--d.@AA $z,#z,
 
 
		U!--i88M))-888$ 	U 	U 	U**5)YTTTTT	Us   )A= ="B"!B"resultr   c                Z    t          || j        j        | j        j                   |j        S )zNHandle a cache hit: replay the result's cached messages, and return its value.)r   r~   rh   r_   rL   )rD   r   s     r'   r   zCachedFunc._handle_cache_hit  s0    J!JO	
 	
 	

 |r)   r   r=   rF   r2   c                   |                     |          5  	 |                    |          }|                     |          cddd           S # t          $ r | j        j                            | j        j        | j        j                  5   | j        j        |i |ddd           n# 1 swxY w Y   | j        j        j	        }	 |
                    ||           cY cddd           S # t          t          f$ rp dfdt          D             v r?t          dt          | j        j                   dt!          j                   d          t%          | j        j                  w xY ww xY w# 1 swxY w Y   dS )zHandle a cache miss: compute a new cached value, write it back to the cache,
        and return that newly-computed value.
        NTc                :    g | ]}t          j        |          S r&   )r   is_type).0	type_namecomputed_values     r'   
<listcomp>z1CachedFunc._handle_cache_miss.<locals>.<listcomp>M  s6          % ").)DD     r)   z*
                            The function zp is decorated with `st.cache_data` but it returns an unevaluated dataframe
                            of type `z`. Please call `collect()` or `to_pandas()` on the dataframe before returning it,
                            so `st.cache_data` can serialize and cache it.)return_valuer_   )rT   rK   r   r   r~   rk   calling_cached_functionr_   rc   _most_recent_messagesrQ   r   RuntimeErrorUNEVALUATED_DATAFRAME_TYPESr   r   r   get_fqn_typer   )rD   r   rF   r   r   r   rM   r   s          @r'   r   zCachedFunc._handle_cache_miss  s   : %%i00 &	 &	" % 1 1) < <--m<<&	 &	 &	 &	 &	 &	 &	 &	 )   Z9QQJOTZ%=  P P &5TZ_i%O;%O%ONP P P P P P P P P P P P P P P  :?U&&y.(KKK)))+&	 &	 &	 &	 &	 &	 &	 &	, #L1            )D        8N*A$*/*R*RN N&/&<^&L&LN N N   9%3$*/   &	 &	 &	 &	 &	 &	 &	 &	 &	 &	se   E9)A?E6B-!E6-B11E64B15E6
C1"E6#E91BE22E66E99E= E=c                l    | j                             | j                  }|                                 dS )z.Clear the wrapped function's associated cache.N)r~   rn   r   rV   )rD   r   s     r'   rV   zCachedFunc.clear[  s+    
--d.@AAr)   N)rp   r^   )r"   r   )r   r   r   r   r"   r   )r   r   r"   r   )
r   r=   rF   r2   r   r   r   r   r"   r   )	rY   rZ   r[   rE   r   r   r   r   rV   r&   r)   r'   rx   rx      s        L L L LB B B B&U U U U0   C C C CJ    r)   rx   rh   r   r_   r`   r   r   r   r   rd   re   r2   c           	        g }t          t          |                    D ]/}t          ||          }|                    |||         f           0|                                D ]\  }}	|                    ||	f           t          j        di t          }
|D ]\  }}|1|                    d          rt          
                    d|           8	 t          ||
| |           t          ||
| ||           a# t          $ r}t          | ||||          d}~ww xY w|
                                }t          
                    d|           |S )	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.
    md5N_z'Not hashing %s because it starts with _hasherrh   hash_source)r   rh   rd   r   zCache key: %sr   )ranger   _get_positional_arg_nameappenditemshashlibnewr   
startswith_LOGGERdebugr   r   r   	hexdigest)rh   r_   r   r   rd   	arg_pairsarg_idxarg_namekw_namekw_valargs_hasher	arg_valueexcrF   s                 r'   r   r   a  s   * /1IY(( 9 9+D'::(Ig$678888&,,.. , , 	'6*++++
 +66~66K( S S)H$7$7$<$<MMCXNNN	S"% 	    "%%      # 	S 	S 	S&z49cRRR	S %%''IMM/9---s   'C99
DDDc                f   t          j        di t          }t          |j        |j        f|| |           	 t          j        |          }n># t          $ r1}t          
                    d|           |j        j        }Y d}~nd}~ww xY wt          ||| |           |                                }|S )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   r   zbFailed to retrieve function's source code when building its key; falling back to bytecode. err={0}Nr   )r   r   r   r   rZ   r[   inspect	getsourceOSErrorr   r   __code__co_coder   )rh   r_   func_hashersource_codee	cache_keys         r'   r   r     s     +66~66K 	$+,	   ,'-- , , ,p	
 	
 	
 m+, KJD    %%''Is   A 
B'BB	arg_indexint
str | Nonec                (   |dk     rdS t          t          j        |           j                                                  }|t          |          k    rdS ||         j        t          j        j        t          j        j	        fv r||         j
        S dS )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   )r_   r   paramss      r'   r   r     s     1}}t&*7+<T+B+B+M+T+T+V+V&W&WFCKKti/)"   i %%4r)   )r   r   r    r!   r"   r#   )r   r   r"   r*   )r   r   r    r,   r"   r#   )rp   r^   r"   rq   )rh   r   r_   r`   r   r   r   r   rd   re   r"   r2   )rh   r   r_   r`   r"   r2   )r_   r`   r   r   r"   r   )>r\   
__future__r   ry   r   r   r.   r?   timetypesabcr   collectionsr   datetimer   typingr   r   r	   typing_extensionsr
   	streamlitr   streamlit.elements.spinnerr   streamlit.loggerr   &streamlit.runtime.caching.cache_errorsr   r   r   r   r   r   r   r   $streamlit.runtime.caching.cache_typer   /streamlit.runtime.caching.cached_message_replayr   r   r   r   !streamlit.runtime.caching.hashingr   r   streamlit.utilr   rY   r   	monotonicTTLCACHE_TIMERr(   r   r=   r^   r{   rx   r   r   r   r&   r)   r'   <module>r      sJ   H G " " " " " "                    # # # # # #       * * * * * * * * * * % % % % % %       . . . . . . ' ' ' ' ' '	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ; : : : : :            I H H H H H H H ) ) ) ) ) )
*X

  
   
 
   

 HL     : /" /" /" /" /" /" /" /"d" " " " " " " "@   8A A A A A A A AH@ @ @ @F$ $ $ $N     r)   