
    &eem                    ~   U d dl mZ d dlZd dlZd dlZd dlmZ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 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 d dlmZ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/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6m7Z7m8Z8m9Z9m:Z: d dl;m<Z<m=Z= d dl>m?Z? d dl@mAZA d dlBmCZC d dlDmEZE erd dlFmGZG dZHdeId<    eeJ          ZKdeId <    G d! d"eL          ZM ed#$           G d% d&                      ZN G d' d(e	          ZO G d) d*e          ZP G d+ d,          ZQdS )-    )annotationsN)	dataclassfield)Enum)TYPE_CHECKING	AwaitableDict
NamedTupleOptionalTupleType)Final)config)
get_logger)BackMsg)
ForwardMsg)
AppSession)get_data_cache_stats_provider!get_resource_cache_stats_provider)LocalDiskCacheStorageManager)ForwardMsgCachecreate_reference_msgpopulate_hash_if_needed)_mem_caches)MediaFileManager)MediaFileStorage)MemorySessionStorage)is_cacheable_msg)
ScriptData)ScriptCache)ActiveSessionInfoSessionClientSessionClientDisconnectedErrorSessionManagerSessionStorage)SCRIPT_RUN_WITHOUT_ERRORS_KEYSessionStateStatProvider)StatsManager)UploadedFileManager)WebsocketSessionManager)LocalSourcesWatcher)CacheStorageManager<   r   SCRIPT_RUN_CHECK_TIMEOUTLOGGERc                      e Zd ZdZdS )RuntimeStoppedErrorz;Raised by operations on a Runtime instance that is stopped.N)__name__
__module____qualname____doc__     9lib/python3.11/site-packages/streamlit/runtime/runtime.pyr1   r1   K   s        EEEEr7   r1   T)frozenc                      e Zd ZU dZded<   ded<   ded<   ded	<    ee
          Zded<   eZ	ded<    ee

          Zded<   dZded<   dS )RuntimeConfigz$Config options for StreamlitRuntime.strscript_pathOptional[str]command_liner   media_file_storager)   uploaded_file_manager)default_factoryr,   cache_storage_managerzType[SessionManager]session_manager_classr%   session_storageFboolis_helloN)r2   r3   r4   r5   __annotations__r   r   rC   r*   rD   r   rE   rG   r6   r7   r8   r;   r;   O   s         ..    )((( /... 2742 2 2    
 3JIIII ',e<P&Q&Q&QOQQQQ Hr7   r;   c                  "    e Zd ZdZdZdZdZdZdS )RuntimeStateINITIALNO_SESSIONS_CONNECTEDONE_OR_MORE_SESSIONS_CONNECTEDSTOPPINGSTOPPEDN)r2   r3   r4   rK   rL   rM   rN   rO   r6   r7   r8   rJ   rJ   o   s)        G3%E"HGGGr7   rJ   c                  P    e Zd ZU dZded<   ded<   ded<   ded<   ded	<   ded
<   dS )AsyncObjectszContainer for all asyncio objects that Runtime manages.
    These cannot be initialized until the Runtime's eventloop is assigned.
    zasyncio.AbstractEventLoop	eventloopzasyncio.Event	must_stophas_connectionneed_send_datazasyncio.Future[None]startedstoppedN)r2   r3   r4   r5   rH   r6   r7   r8   rQ   rQ   w   sp          
 )(((  "!!! "!!! "!!! "!!!!!r7   rQ   c                     e Zd ZU dZded<   ed@d            ZedAd            ZdBd
Ze	dCd            Z
e	dDd            Ze	dEd            Ze	dFd            Ze	dGd            Ze	dHd            Ze	dId            ZdJdZdKdZdKdZdLd Z	 	 dMdNd(Z	 	 dMdNd)ZdOd*ZdOd+ZdPd.ZdQd1Ze	dRd3            ZdRd4ZdSd6ZdKd7ZdTd;ZdKd<Z dUd>Z!dKd?Z"dS )VRuntimeNzOptional[Runtime]	_instancereturnc                <    | j         t          d          | j         S )znReturn the singleton Runtime instance. Raise an Error if the
        Runtime hasn't been created yet.
        NzRuntime hasn't been created!)rZ   RuntimeErrorclss    r8   instancezRuntime.instance   s#    
 = =>>>}r7   rF   c                    | j         duS )a2  True if the singleton Runtime instance has been created.

        When a Streamlit app is running in "raw mode" - that is, when the
        app is run via `python app.py` instead of `streamlit run app.py` -
        the Runtime will not exist, and various Streamlit functions need
        to adapt.
        N)rZ   r^   s    r8   existszRuntime.exists   s     }D((r7   r   r;   c                   t           j        t          d          | t           _        d| _        d| _        |j        | _        |j        | _        t          j
        | _        t                      | _        |j        | _        t!          |j                  | _        |j        | _        t+                      | _         |j        |j        | j        | j        | j                  | _        t7                      | _        | j                            t=                                 | j                            t?                                 | j                            t@                     | j                            | j                   | j                            | j                   | j                            tC          | j                             dS )a   Create a Runtime instance. It won't be started yet.

        Runtime is *not* thread-safe. Its public methods are generally
        safe to call only on the same thread that its event loop runs on.

        Parameters
        ----------
        config
            Config options.
        Nz Runtime instance already exists!)storage)rE   rA   script_cachemessage_enqueued_callback)"rY   rZ   r]   _async_objs_loop_coroutine_taskr=   _main_script_pathrG   	_is_hellorJ   rK   _stater   _message_cacherA   _uploaded_file_mgrr   r@   _media_file_mgrrC   _cache_storage_managerr    _script_cacherD   rE   _enqueued_some_message_session_mgrr(   
_stats_mgrregister_providerr   r   r   r'   )selfr   s     r8   __init__zRuntime.__init__   s    (ABBB  48 CG!!'!3"* .//"(">/8QRRR&,&B#(]]8F8"2"&"9+&*&A	
 
 
 '..))*G*I*IJJJ))*K*M*MNNN))+666))$*=>>>))$*ABBB))*B4CT*U*UVVVVVr7   rJ   c                    | j         S N)rk   ru   s    r8   statezRuntime.state   s
    {r7   r   c                    | j         S rx   )rl   ry   s    r8   message_cachezRuntime.message_cache   s    ""r7   r)   c                    | j         S rx   )rm   ry   s    r8   uploaded_file_mgrzRuntime.uploaded_file_mgr   s    &&r7   r,   c                    | j         S rx   )ro   ry   s    r8   rC   zRuntime.cache_storage_manager   s    **r7   r   c                    | j         S rx   )rn   ry   s    r8   media_file_mgrzRuntime.media_file_mgr   s    ##r7   r(   c                    | j         S rx   )rs   ry   s    r8   	stats_mgrzRuntime.stats_mgr   s
    r7   Awaitable[None]c                4    |                                  j        S )z?A Future that completes when the Runtime's run loop has exited.)_get_async_objsrW   ry   s    r8   rW   zRuntime.stopped   s     ##%%--r7   
session_idr<   Optional[SessionClient]c                L    | j                             |          }|dS |j        S )zGet the SessionClient for the given session_id, or None
        if no such session exists.

        Notes
        -----
        Threading: SAFE. May be called on any thread.
        N)rr   get_active_session_infoclientru   r   session_infos      r8   
get_clientzRuntime.get_client   s.     (@@LL4""r7   Nonec           	       K   t          t          j                    t          j                    t          j                    t          j                    t          j                    t          j                              }|| _        t          j        |                                 d          | _        |j	         d{V  dS )a  Start the runtime. This must be called only once, before
        any other functions are called.

        When this coroutine returns, Streamlit is ready to accept new sessions.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        )rR   rS   rT   rU   rV   rW   zRuntime.loop_coroutine)nameN)
rQ   asyncioget_running_loopEventFuturerg   create_task_loop_coroutinerh   rV   ru   
async_objss     r8   startzRuntime.start  s       ".00moo"=??"=??N$$N$$
 
 

 &$+$7  "")A%
 %
 %
!           r7   c                r                                        fd}j                            |           dS )zRequest that Streamlit close all sessions and stop running.
        Note that Streamlit won't stop running immediately.

        Notes
        -----
        Threading: SAFE. May be called from any thread.
        c                     j         t          j        t          j        fv rd S t                              d                               t          j                    j                                         d S )NzRuntime stopping...)	rk   rJ   rN   rO   r/   debug
_set_staterS   set)r   ru   s   r8   stop_on_eventloopz'Runtime.stop.<locals>.stop_on_eventloop/  sc    {|4l6JKKKLL.///OOL1222 $$&&&&&r7   N)r   rR   call_soon_threadsafe)ru   r   r   s   ` @r8   stopzRuntime.stop$  sU     ))++
	' 	' 	' 	' 	' 	' 	112CDDDDDr7   c                6    | j                             |          S )zTrue if the session_id belongs to an active session.

        Notes
        -----
        Threading: SAFE. May be called on any thread.
        )rr   is_active_session)ru   r   s     r8   r   zRuntime.is_active_session9  s      22:>>>r7   r   r"   	user_infoDict[str, Optional[str]]existing_session_idr>   session_id_overridec                   |r|r
J d            | j         t          j        t          j        fv rt	          d| j          d          | j                            |t          | j        | j	                  |||          }| 
                    t          j                   |                                 j                                         |S )a  Create a new session (or connect to an existing one) and return its unique ID.

        Parameters
        ----------
        client
            A concrete SessionClient implementation for communicating with
            the session's client.
        user_info
            A dict that contains information about the session's user. For now,
            it only (optionally) contains the user's email address.

            {
                "email": "example@example.com"
            }
        existing_session_id
            The ID of an existing session to reconnect to. If one is not provided, a new
            session is created. Note that whether the Runtime's SessionManager supports
            reconnecting to an existing session depends on the SessionManager that this
            runtime is configured with.
        session_id_override
            The ID to assign to a new session being created with this method. Setting
            this can be useful when the service that a Streamlit Runtime is running in
            wants to tie the lifecycle of a Streamlit session to some other session-like
            object that it manages. Only one of existing_session_id and
            session_id_override should be set.

        Returns
        -------
        str
            The session's unique string ID.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        zFOnly one of existing_session_id and session_id_override should be set!zCan't connect_session (state=))r   script_datar   r   r   )rk   rJ   rN   rO   r1   rr   connect_sessionr   ri   rj   r   rM   r   rT   r   )ru   r   r   r   r   r   s         r8   r   zRuntime.connect_sessionB  s    V  	T$7	T 	TS	T 	T 	T ;<0,2FGGG%&Tdk&T&T&TUUU&66"4#94>JJ 3 3 7 
 

 	CDDD-11333r7   c                h    t                               d           |                     ||||          S )zCreate a new session (or connect to an existing one) and return its unique ID.

        Notes
        -----
        This method is simply an alias for connect_session added for backwards
        compatibility.
        z:create_session is deprecated! Use connect_session instead.)r   r   r   r   )r/   warningr   )ru   r   r   r   r   s        r8   create_sessionzRuntime.create_session  s@     	STTT## 3 3	 $ 
 
 	
r7   c                    | j                             |          }|r9| j                            |j                   | j                             |           |                                  dS )a9  Close and completely shut down a session.

        This differs from disconnect_session in that it always completely shuts down a
        session, permanently losing any associated state (session state, uploaded files,
        etc.).

        This function may be called multiple times for the same session,
        which is not an error. (Subsequent calls just no-op.)

        Parameters
        ----------
        session_id
            The session's unique ID.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        N)rr   get_session_inforl   remove_refs_for_sessionsessionclose_session_on_session_disconnectedr   s      r8   r   zRuntime.close_session  sk    & (99*EE 	8778LMMM++J777%%'''''r7   c                    | j                             |          }|r9| j                            |j                   | j                             |           |                                  dS )aZ  Disconnect a session. It will stop producing ForwardMsgs.

        Differs from close_session because disconnected sessions can be reconnected to
        for a brief window (depending on the SessionManager/SessionStorage
        implementations used by the runtime).

        This function may be called multiple times for the same session,
        which is not an error. (Subsequent calls just no-op.)

        Parameters
        ----------
        session_id
            The session's unique ID.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        N)rr   r   rl   r   r   disconnect_sessionr   r   s      r8   r   zRuntime.disconnect_session  sm    & (@@LL 		= 778LMMM00<<<%%'''''r7   msgr   c                   | j         t          j        t          j        fv rt	          d| j          d          | j                            |          }|t                              d|           dS |j	        
                    |           dS )a+  Send a BackMsg to an active session.

        Parameters
        ----------
        session_id
            The session's unique ID.
        msg
            The BackMsg to deliver to the session.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        zCan't handle_backmsg (state=r   Nz3Discarding BackMsg for disconnected session (id=%s))rk   rJ   rN   rO   r1   rr   r   r/   r   r   handle_backmsg)ru   r   r   r   s       r8   r   zRuntime.handle_backmsg  s     ;<0,2FGGG%&ST[&S&S&STTT(@@LLLLEz   F++C00000r7   excBaseExceptionc                   | j         t          j        t          j        fv rt	          d| j          d          | j                            |          }|t                              d|           dS |j	        
                    |           dS )a.  Handle an Exception raised during deserialization of a BackMsg.

        Parameters
        ----------
        session_id
            The session's unique ID.
        exc
            The Exception.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        z6Can't handle_backmsg_deserialization_exception (state=r   Nz=Discarding BackMsg Exception for disconnected session (id=%s))rk   rJ   rN   rO   r1   rr   r   r/   r   r   handle_backmsg_exception)ru   r   r   r   s       r8   (handle_backmsg_deserialization_exceptionz0Runtime.handle_backmsg_deserialization_exception  s      ;<0,2FGGG%WWWW   (@@LLLLO   F55c:::::r7   Tuple[bool, str]c                b   K   | j         t          j        t          j        t          j        fvrdS dS )N)Tok)Funavailable)rk   rJ   rK   rN   rO   ry   s    r8   is_ready_for_browser_connectionz'Runtime.is_ready_for_browser_connection  s9      ; ! 
 
 

 :##r7   c           	       K   t          t          | j        | j                  | j        | j        | j        t          | j                  ddi          }	 |                    d           t          j
                    }t          |j        vrft          j
                    |z
  t          k     rGt          j        d           d{V  t          |j        vrt          j
                    |z
  t          k     Gt          |j        vr	 |                                 dS |j        t                   }|rdnd}||f|                                 S # |                                 w xY w)	aJ  Load and execute the app's script to verify it runs without an error.

        Returns
        -------
        (True, "ok") if the script completes without error, or (False, err_msg)
        if the script raises an exception.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        emailztest@test.com)r   rA   re   rf   local_sources_watcherr   Ng?)Ftimeoutr   error)r   r   ri   rj   rm   rp   rq   r+   request_reruntimeperf_counterr&   session_stater.   r   sleepshutdown)ru   r   nowr   r   s        r8   does_script_run_without_errorz%Runtime.does_script_run_without_error  sp      "4#94>JJ"&"9+&*&A"5d6L"M"M0
 
 
	!!$'''#%%C-W5JJJ&((3.2JJJmC((((((((( .W5JJJ&((3.2JJJ -G4III'  &'DEB)$$'Cs7Gs   B*E E E	new_statec                V    t                               d| j        |           || _        d S )NzRuntime state: %s -> %s)r/   r   rk   )ru   r   s     r8   r   zRuntime._set_state>  s&    .YGGGr7   c                ,  K   |                                  }	 | j        t          j        k    r |                     t          j                   n-| j        t          j        k    rnt          d| j                   |j        	                    d           |j
                                        s| j        t          j        k    r{t          j        t          j        |j
                                                  t          j        |j                                                  ft          j                   d{V  n| j        t          j        k    r|j                                         | j                                        D ]}|j                                        }|D ]h}	 |                     ||           n4# t0          $ r' | j                            |j        j                   Y nw xY wt          j        d           d{V  it          j        d           d{V  nnt          j        t          j        |j
                                                  t          j        |j                                                  ft          j                   d{V  |j
                                        | j                                        D ]&}| j                            |j        j                   '|                     t          j                   |j        	                    d           dS # t@          $ rR}|j        !                    |           tE          j#                     tH          %                    d           Y d}~dS d}~ww xY w)zThe main Runtime loop.

        This function won't exit until `stop` is called.

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        zBad Runtime state at start: N)return_whenr   g{Gz?zJ
Please report this bug at https://github.com/streamlit/streamlit/issues.
)&r   rk   rJ   rK   r   rL   rM   r]   rV   
set_resultrS   is_setr   waitr   rT   FIRST_COMPLETEDrU   clearrr   list_active_sessionsr   flush_browser_queue_send_messager#   r   idr   list_sessionsr   rO   rW   	Exceptionset_exception	traceback	print_excr/   info)ru   r   active_session_infomsg_listr   r   es          r8   r   zRuntime._loop_coroutineB  s      ))++
H	{l222 BCCCC KKK"#O$+#O#OPPP ))$/// *1133 *;,"DDD ",#/
0D0I0I0K0KLL#/
0I0N0N0P0PQQ %,$;           [L$OOO-33555/3/@/U/U/W/W 3 3+#6#>#R#R#T#T#+ 	3 	3C" $ 2 23F L L L L#A " " " $ 1 D D$7$?$B!" !" !" !" !"" #*-"2"222222222	3 "----------- l+J,@,E,E,G,GHH+J,E,J,J,L,LMM !( 7         I !*1133 *Z !% 1 ? ? A A I I !//0D0GHHHHOOL0111))$///// 	 	 	,,Q///!!!KK        	s>   FL7 %F<;L7 <.G-*L7 ,G--EL7 7
NANNr   r!   r   c                   t          |          |j        _        |}|j        j        rt          |           | j                            ||j        |j                  r/t          	                    d|j
                   t          |          }t          	                    d|j
                   | j                            ||j        |j                   |                    d          dk    rw|j        t          j        k    rbt          	                    dt#          j        d                     |xj        dz  c_        | j                            |j        |j                   |j                            |           dS )	a  Send a message to a client.

        If the client is likely to have already cached the message, we may
        instead send a "reference" message that contains only the hash of the
        message.

        Parameters
        ----------
        session_info : ActiveSessionInfo
            The ActiveSessionInfo associated with websocket
        msg : ForwardMsg
            The message to send to the client

        Notes
        -----
        Threading: UNSAFE. Must be called on the eventloop thread.
        z$Sending cached message ref (hash=%s)zCaching message (hash=%s)typescript_finishedzYScript run finished successfully; removing expired entries from MessageCache (max_age=%s)zglobal.maxCachedMessageAge   N)r   metadata	cacheabler   rl   has_message_referencer   script_run_countr/   r   hashr   add_message
WhichOneofr   r   FINISHED_SUCCESSFULLYr   
get_option"remove_expired_entries_for_sessionr   write_forward_msg)ru   r   r   msg_to_sends       r8   r   zRuntime._send_message  sw   $ "2#!6!6<! 	#C((("88\)<+H  8
 CSXNNN2377
 LL4ch???++\)<+H   NN6""&777#z'GGGLL !">??	   ))Q.))BB$l&C  
 	--k:::::r7   c                v    |                                  }|j                            |j        j                   dS )a  Callback called by AppSession after the AppSession has enqueued a
        message. Sets the "needs_send_data" event, which causes our core
        loop to wake up and flush client message queues.

        Notes
        -----
        Threading: SAFE. May be called on any thread.
        N)r   rR   r   rU   r   r   s     r8   rq   zRuntime._enqueued_some_message  s8     ))++
11*2K2OPPPPPr7   rQ   c                <    | j         t          d          | j         S )zpReturn our AsyncObjects instance. If the Runtime hasn't been
        started, this will raise an error.
        NzRuntime hasn't started yet!)rg   r]   ry   s    r8   r   zRuntime._get_async_objs  s%     #<===r7   c                   | j         t          j        k    ri| j                                        dk    rN|                                 j                                         |                     t          j	                   dS dS dS )zlSet the runtime state to NO_SESSIONS_CONNECTED if the last active
        session was disconnected.
        r   N)
rk   rJ   rM   rr   num_active_sessionsr   rT   r   r   rL   ry   s    r8   r   z Runtime._on_session_disconnected  sy    
 K<FFF!55771<<  ""177999OOL>?????	 GF<<r7   )r[   rY   )r[   rF   )r   r;   )r[   rJ   )r[   r   )r[   r)   )r[   r,   )r[   r   )r[   r(   )r[   r   )r   r<   r[   r   )r[   r   )r   r<   r[   rF   )NN)
r   r"   r   r   r   r>   r   r>   r[   r<   )r   r<   r[   r   )r   r<   r   r   r[   r   )r   r<   r   r   r[   r   )r[   r   )r   rJ   r[   r   )r   r!   r   r   r[   r   )r[   rQ   )#r2   r3   r4   rZ   rH   classmethodr`   rb   rv   propertyrz   r|   r~   rC   r   r   rW   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rq   r   r   r6   r7   r8   rY   rY      s        #'I''''   [ ) ) ) [)/W /W /W /Wb    X # # # X# ' ' ' X' + + + X+ $ $ $ X$    X . . . X.# # # #! ! ! !:E E E E*? ? ? ? .2-1; ; ; ; ;B .2-1
 
 
 
 
,( ( ( (2( ( ( (@1 1 1 14; ; ; ;> $ $ $ X$* * * *X       T T T Tl9; 9; 9; 9;v
Q 
Q 
Q 
Q       	@ 	@ 	@ 	@ 	@ 	@r7   rY   )R
__future__r   r   r   r   dataclassesr   r   enumr   typingr   r   r	   r
   r   r   r   typing_extensionsr   	streamlitr   streamlit.loggerr   streamlit.proto.BackMsg_pb2r   streamlit.proto.ForwardMsg_pb2r   streamlit.runtime.app_sessionr   streamlit.runtime.cachingr   r   :streamlit.runtime.caching.storage.local_disk_cache_storager   #streamlit.runtime.forward_msg_cacher   r   r   (streamlit.runtime.legacy_caching.cachingr   $streamlit.runtime.media_file_managerr   $streamlit.runtime.media_file_storager   (streamlit.runtime.memory_session_storager   streamlit.runtime.runtime_utilr   streamlit.runtime.script_datar   +streamlit.runtime.scriptrunner.script_cacher    !streamlit.runtime.session_managerr!   r"   r#   r$   r%   streamlit.runtime.stater&   r'   streamlit.runtime.statsr(   'streamlit.runtime.uploaded_file_managerr)   +streamlit.runtime.websocket_session_managerr*   streamlit.watcherr+   !streamlit.runtime.caching.storager,   r.   rH   r2   r/   r   r1   r;   rJ   rQ   rY   r6   r7   r8   <module>r     s   # " " " " " "       ( ( ( ( ( ( ( (       T T T T T T T T T T T T T T T T T T # # # # # #       ' ' ' ' ' ' / / / / / / 5 5 5 5 5 5 4 4 4 4 4 4                     
 A @ @ @ @ @ A A A A A A A A A A A A I I I I I I ; ; ; ; ; ; 4 4 4 4 4 4 C C C C C C                     1 0 0 0 0 0 G G G G G G O O O O O O 1 1 1 1 1 1 FEEEEEE #%  $ $ $ $
8$$ $ $ $ $F F F F F) F F F $       >    4   " " " " ": " " "0a	@ a	@ a	@ a	@ a	@ a	@ a	@ a	@ a	@ a	@r7   