
    g2                        U 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m	Z	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ erd d	lmZ d d
lmZmZmZmZ  ee      Zded<    G d d      Z G d d      Z G d d      Zy)    )annotationsN)Path)TYPE_CHECKINGAnyCallableFinal)source_util)
get_logger)calc_md5)	watch_dir)ScriptCache)PageHashPageInfoPageName
ScriptPathr   _LOGGERc                      e Zd ZU dZdZded<    ej                         Ze	dd       Z
dddZedd       Z	 	 	 	 	 	 ddZdd	Z	 	 	 	 dd
ZddZddZy)PagesStrategyV1a  
    Strategy for MPA v1. This strategy handles pages being set directly
    by a call to `st.navigation`. The key differences here are:
    - The pages are defined by the existence of a `pages` directory
    - We will ensure one watcher is watching the scripts in the directory.
    - Only one script runs for a full rerun.
    - We know at the beginning the intended page script to run.

    NOTE: Thread safety of the pages is handled by the source_util module
    Fboolis_watching_pages_dirc                    t         j                  5  t         j                  r
	 d d d        y dd}| j                  dz  }t	        t        |      |dd       dt         _        d d d        y # 1 sw Y   y xY w)Nc                ,    t        j                          y N)r	   invalidate_pages_cache)_paths    T/var/www/openai/venv/lib/python3.12/site-packages/streamlit/runtime/pages_manager.py_handle_page_changedz=PagesStrategyV1.watch_pages_dir.<locals>._handle_page_changed9   s    224    pagesz*.pyT)glob_patternallow_nonexistent)r   strreturnNone)r   pages_watcher_lockr   main_script_parentr   r"   )pages_managerr   	pages_dirs      r   watch_pages_dirzPagesStrategyV1.watch_pages_dir3   sd    //44 0/5 &887BII$#"&	 59O1 0//s   A+6A++A4c                B    || _         |rt        j                  |       y y r   )r'   r   r)   )selfr'   setup_watchers      r   __init__zPagesStrategyV1.__init__E   s     *++M: r   c                .    | j                   j                  S r   )r'   current_page_script_hashr+   s    r   initial_active_script_hashz*PagesStrategyV1.initial_active_script_hashK   s    !!:::r   c                    | j                         }|r|j                  |d       S |s)r't        t        fd|j	                               d       S t        |j	                               d   }|S )Nc                    | xr | d   k(  S )N	page_name )pr4   s    r   <lambda>z;PagesStrategyV1.get_initial_active_script.<locals>.<lambda>a   s    aAQ{^y%@Ar   r   )	get_pagesgetnextfiltervalueslist)r+   page_script_hashr4   r   main_page_infos     `  r   get_initial_active_scriptz)PagesStrategyV1.get_initial_active_scriptO   ss      99-t44!i
 
 BLLN 
 
 elln-a0r   c                T    t        j                  | j                  j                        S r   )r	   r8   r'   main_script_pathr0   s    r   r8   zPagesStrategyV1.get_pagesm   s    $$T%7%7%H%HIIr   c                ,    t        j                  |      S r   )r	   register_pages_changed_callbackr+   callbacks     r   rD   z/PagesStrategyV1.register_pages_changed_callbackp   s     ::8DDr   c                    t        d      )Nz'Unable to set pages in this V1 strategyNotImplementedError)r+   _pagess     r   	set_pageszPagesStrategyV1.set_pagesv   s    !"KLLr   c                    t        d      )Nz-Unable to get page script in this V1 strategyrH   )r+   _fallback_page_hashs     r   get_page_scriptzPagesStrategyV1.get_page_scripty   s    !"QRRr   Nr'   PagesManager)T)r'   rP   r,   r   r#   r   r>   r   r4   r   r#   PageInfo | Noner#   dict[PageHash, PageInfo]rF   zCallable[[str], None]r#   zCallable[[], None])rJ   rU   r#   r$   )rM   r   r#   rS   )__name__
__module____qualname____doc__r   __annotations__	threadingLockr%   staticmethodr)   r-   propertyr1   r@   r8   rD   rK   rN   r5   r   r   r   r   "   s    	 #(4'') 9 9"; ; ; (5=	<JE'E 
EMSr   r   c                  f    e Zd ZdZd
dZ	 	 	 	 	 	 ddZedd       ZddZddZ	ddZ
	 	 	 	 ddZy	)PagesStrategyV2a  
    Strategy for MPA v2. This strategy handles pages being set directly
    by a call to `st.navigation`. The key differences here are:
    - The pages are set directly by the user
    - The initial active script will always be the main script
    - More than one script can run in a single app run (sequentially),
      so we must keep track of the active script hash
    - We rely on pages manager to retrieve the intended page script per run

    NOTE: We don't provide any locks on the pages since the pages are not
    shared across sessions. Only the user script thread can write to
    pages and the event loop thread only reads
    c                     || _         d | _        y r   )r'   rJ   )r+   r'   kwargss      r   r-   zPagesStrategyV2.__init__   s    *7;r   c                d    | j                   j                  |xs | j                   j                  dS N)script_pathr>   )r'   rB   main_script_hashr+   r>   r4   s      r   r@   z)PagesStrategyV2.get_initial_active_script   s4    
  -->> 0 !3!!22	
 	
r   c                .    | j                   j                  S r   )r'   rg   r0   s    r   r1   z*PagesStrategyV2.initial_active_script_hash   s    !!222r   c                     j                   y  j                  j                  rJ j                   j                   j                  j                   j                   j                  |d             S  j                  j                  r1t        t         fd j                   j                               d       S  j                   j                  |d       S )Nc                D    | xr | d   j                   j                  k(  S )Nurl_pathname)r'   intended_page_name)r6   r+   s    r   r7   z1PagesStrategyV2.get_page_script.<locals>.<lambda>   s*    a U>*d.@.@.S.SSUr   )rJ   r'   intended_page_script_hashr9   rm   r:   r;   r<   r+   fallback_page_hashs   ` r   rN   zPagesStrategyV2.get_page_script   s    ;;77 ;;??""<< 2D9  22 
UKK&&(   {{1488r   c                    | j                   xsa | j                  j                  | j                  j                  xs d| j                  j                  xs dd| j                  j
                  diS )N )r>   r4   iconrf   )rJ   r'   rg   rn   rm   rB   r0   s    r   r8   zPagesStrategyV2.get_pages   si     {{ 
//$($6$6$P$P$VTV!//BBHb#11BB	2
 	
r   c                    || _         y r   )rJ   r+   r   s     r   rK   zPagesStrategyV2.set_pages   s	    r   c                    d S )Nc                      y r   r5   r5   r   r   r7   zAPagesStrategyV2.register_pages_changed_callback.<locals>.<lambda>   s    tr   r5   rE   s     r   rD   z/PagesStrategyV2.register_pages_changed_callback   s
    
 r   NrO   )r>   r   r4   r   r#   r   rQ   rp   r   r#   rS   rT   r   rU   r#   r$   rV   )rW   rX   rY   rZ   r-   r@   r_   r1   rN   r8   rK   rD   r5   r   r   ra   ra   }   sc    <
 (
5=
	
 3 39<
' 
r   ra   c                  ,   e Zd ZU dZeZded<   	 d	 	 	 ddZedd       Z	edd       Z
edd       Zedd	       Zedd
       Zedd       Zedd       Zedd       ZddZd dZ	 	 	 	 	 	 d!dZ	 	 	 	 	 	 d"dZd#dZd$dZd%d&dZ	 	 	 	 d'dZd(dZy))rP   a  
    PagesManager is responsible for managing the set of pages based on the
    strategy. By default, PagesManager uses V1 which relies on the original
    assumption that there exists a `pages` directory with all the scripts.

    If the `pages` are being set directly, the strategy is switched to V2.
    This indicates someone has written an `st.navigation` call in their app
    which informs us of the pages.

    NOTE: Each strategy handles its own thread safety when accessing the pages
    z'type[PagesStrategyV1 | PagesStrategyV2]DefaultStrategyNc                    || _         t        |      | _        t        j                  | fi || _        || _        d | _        d | _        d| _	        y Nrr   )
_main_script_pathr   _main_script_hashrP   r{   pages_strategy_script_cache_intended_page_script_hash_intended_page_name_current_page_script_hash)r+   rB   script_cacherc   s       r   r-   zPagesManager.__init__   sR     "2+34D+E*::4J6J);?'48 35&r   c                    | j                   S r   )r~   r0   s    r   rB   zPagesManager.main_script_path       %%%r   c                @    t        | j                        j                  S r   )r   r~   parentr0   s    r   r&   zPagesManager.main_script_parent   s    D**+222r   c                    | j                   S r   )r   r0   s    r   rg   zPagesManager.main_script_hash   r   r   c                    | j                   S r   r   r0   s    r   r/   z%PagesManager.current_page_script_hash   s    ---r   c                    | j                   S r   )r   r0   s    r   rm   zPagesManager.intended_page_name  s    '''r   c                    | j                   S r   )r   r0   s    r   rn   z&PagesManager.intended_page_script_hash  s    ...r   c                .    | j                   j                  S r   )r   r1   r0   s    r   r1   z'PagesManager.initial_active_script_hash	  s    ""===r   c                >    t        | j                  t              rdS dS )N      )
isinstancer   ra   r0   s    r   mpa_versionzPagesManager.mpa_version  s    t22ODqK!Kr   c                    || _         y r   r   )r+   r>   s     r   set_current_page_script_hashz)PagesManager.set_current_page_script_hash  s
    )9&r   c                4    | j                   | j                  dS re   )r~   r   r0   s    r   get_main_pagezPagesManager.get_main_page  s    11 $ 6 6
 	
r   c                     || _         || _        y r   )r   r   rh   s      r   set_script_intentzPagesManager.set_script_intent  s     +;'#, r   c                :    | j                   j                  ||      S r   )r   r@   rh   s      r   r@   z&PagesManager.get_initial_active_script   s"     ""<<i
 	
r   c                6    | j                   j                         S r   )r   r8   r0   s    r   r8   zPagesManager.get_pages'  s    "",,..r   c                .   t        | j                  t              r`t        j                  j                  | j                  dz        rt        j                  d       t        t        _        t        |       | _        | j                  j                  |       y )Nr   zst.navigation was called in an app with a pages/ directory. This may cause unusual app behavior. You may want to rename the pages/ directory.)r   r   r   ospathexistsr&   r   warningra   rP   r{   rK   ru   s     r   rK   zPagesManager.set_pages*  si    d))?;ww~~d55?@(
 ,;L("1$"7D%%e,r   c                X    	 | j                   j                  |      S # t        $ r Y y w xY wr   )r   rN   rI   ro   s     r   rN   zPagesManager.get_page_script8  s1    	&&667IJJ" 		s    	))c                8    | j                   j                  |      S )zRegister a callback to be called when the set of pages changes.

        The callback will be called with the path changed.
        )r   rD   rE   s     r   rD   z,PagesManager.register_pages_changed_callback@  s     ""BB8LLr   c                R    | j                   y| j                   j                  |      S r}   )r   get_bytecode)r+   rf   s     r   get_page_script_byte_codez&PagesManager.get_page_script_byte_codeK  s(    %!!..{;;r   r   )rB   r   r   zScriptCache | None)r#   r   )r#   r   rQ   )r#   zPageName | None)r#   zPageHash | None)r#   int)r>   r   r#   r$   )r#   r   )r>   r   r4   r   r#   r$   rR   rT   ry   )rr   rx   rV   )rf   r"   r#   r   )rW   rX   rY   rZ   r   r{   r[   r-   r_   rB   r&   rg   r/   rm   rn   r1   r   r   r   r   r@   r8   rK   rN   rD   r   r5   r   r   rP   rP      sF   
 @OO<N
 ,06$6 )6 & & 3 3 & & . . ( ( / / > > L L:
- (-5=-	-
 (
5=
	
/-	M'	M 
	M<r   rP   ) 
__future__r   r   r\   pathlibr   typingr   r   r   r   	streamlitr	   streamlit.loggerr
   streamlit.utilr   streamlit.watcherr   +streamlit.runtime.scriptrunner.script_cacher   streamlit.source_utilr   r   r   r   rW   r   r[   r   ra   rP   r5   r   r   <module>r      sh    # 	   6 6 ! ' # 'GNNH% %XS XSvT Tn|< |<r   