
    gO                    L   U d dl mZ d dlZd dlZd dl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 d dlZd dlZd dlmZ d dlmZ  ee      Zd	ed
<    G d d      Z e       Zd	ed<   ddZddZddZ  G d dee!ef         Z" G d dee!ef         Z# e#       Z$d	ed<   y)    )annotationsN)	ItemsViewIteratorKeysViewMapping
ValuesView)deepcopy)AnyCallableFinalNoReturn)Signal)runtime)
get_loggerr   _LOGGERc                      e Zd ZdZd ZddZddZddZ	 	 	 	 ddZ	 	 	 	 ddZ	ddZ
dd	Zdd
ZddZddZddZddZy)SecretErrorMessagesa  SecretErrorMessages stores all error messages we use for secrets to allow customization for different environments.
    For example Streamlit Cloud can customize the message to be different than the open source.

    For internal use, may change in future releases without notice.
    c                d    d | _         d | _        d | _        d | _        d | _        d | _        y )Nc                    d|  dS )Nzst.secrets has no attribute "". Did you forget to add it to secrets.toml, mount it to secret directory, or the app settings on Streamlit Cloud? More info: https://docs.streamlit.io/deploy/streamlit-community-cloud/deploy-your-app/secrets-management 	attr_names    N/var/www/openai/venv/lib/python3.12/site-packages/streamlit/runtime/secrets.py<lambda>z.SecretErrorMessages.__init__.<locals>.<lambda>.   s    +I; 7w x    c                    d|  dS )Nzst.secrets has no key "r   r   keys    r   r   z.SecretErrorMessages.__init__.<locals>.<lambda>3   s    %cU +w xr   c                *    ddj                  |        S )NzQNo secrets found. Valid paths for a secrets.toml file or secret directories are: z, )join)
file_pathss    r   r   z.SecretErrorMessages.__init__.<locals>.<lambda>8   s    _`d`i`ijt`u_vwr   c                    d|  d| S )NzError parsing secrets file at z: r   )pathexs     r   r   z.SecretErrorMessages.__init__.<locals>.<lambda><   s    =dV2bTJr   c                    |  dS )Nzn is not a folder. To use directory based secrets, mount every secret in a subfolder under the secret directoryr   )sub_folder_paths    r   r   z.SecretErrorMessages.__init__.<locals>.<lambda>>   s      k kr   c                    d|  dS )NzInvalid secrets path: z): path is not a .toml file or a directoryr   )r$   s    r   r   z.SecretErrorMessages.__init__.<locals>.<lambda>B   s    $TF*STr   )missing_attr_messagemissing_key_messageno_secrets_founderror_parsing_file_at_pathsubfolder_path_is_not_a_folderinvalid_secret_pathselfs    r   __init__zSecretErrorMessages.__init__-   sB    %
!
$
 
!
 K 	'/
+$
 r   c                    || _         y)z(Set the missing attribute error message.Nr)   r0   messages     r   set_missing_attr_messagez,SecretErrorMessages.set_missing_attr_messageF   s
    $+!r   c                    || _         y)z"Set the missing key error message.Nr*   r4   s     r   set_missing_key_messagez+SecretErrorMessages.set_missing_key_messageJ   
    #* r   c                    || _         y)z'Set the no secrets found error message.Nr+   r4   s     r   set_no_secrets_found_messagez0SecretErrorMessages.set_no_secrets_found_messageN   s
     'r   c                    || _         y)z1Set the error parsing file at path error message.Nr,   r4   s     r   &set_error_parsing_file_at_path_messagez:SecretErrorMessages.set_error_parsing_file_at_path_messageR   s     +2'r   c                    || _         y)z5Set the subfolder path is not a folder error message.Nr-   r4   s     r   *set_subfolder_path_is_not_a_folder_messagez>SecretErrorMessages.set_subfolder_path_is_not_a_folder_messageX   s     /6+r   c                    || _         y)z*Set the invalid secret path error message.Nr.   r4   s     r   set_invalid_secret_path_messagez3SecretErrorMessages.set_invalid_secret_path_message^   r:   r   c                $    | j                  |      S )z(Get the missing attribute error message.r3   )r0   r   s     r   get_missing_attr_messagez,SecretErrorMessages.get_missing_attr_messageb   s    ((33r   c                $    | j                  |      S )z"Get the missing key error message.r8   r0   r   s     r   get_missing_key_messagez+SecretErrorMessages.get_missing_key_messagef   s    '',,r   c                $    | j                  |      S )z'Get the no secrets found error message.r<   )r0   r"   s     r   get_no_secrets_found_messagez0SecretErrorMessages.get_no_secrets_found_messagej   s    $$Z00r   c                &    | j                  ||      S )z1Get the error parsing file at path error message.r?   )r0   r$   r%   s      r   &get_error_parsing_file_at_path_messagez:SecretErrorMessages.get_error_parsing_file_at_path_messagen   s    ..tR88r   c                $    | j                  |      S )z5Get the subfolder path is not a folder error message.rB   )r0   r'   s     r   *get_subfolder_path_is_not_a_folder_messagez>SecretErrorMessages.get_subfolder_path_is_not_a_folder_messager   s    22?CCr   c                $    | j                  |      S )z*Get the invalid secret path error message.rE   )r0   r$   s     r   get_invalid_secret_path_messagez3SecretErrorMessages.get_invalid_secret_path_messagev   s    ''--r   N)r5   zCallable[[str], str]returnNone)r5   zCallable[[list[str]], str]rT   rU   )r5   zCallable[[str, Exception], str]rT   rU   r   strrT   rW   r   rW   rT   rW   )r"   z	list[str]rT   rW   )r$   rW   r%   	ExceptionrT   rW   )r'   rW   rT   rW   )r$   rW   rT   rW   )__name__
__module____qualname____doc__r1   r6   r9   r=   r@   rC   rF   rH   rK   rM   rO   rQ   rS   r   r   r   r   r   &   si    
2,+(262	26+6	6+4-19D.r   r   secret_error_messages_singletonc           	         t        | t              r| j                         S | j                         D ci c](  \  }}|t        |t              r|j                         n|* c}}S c c}}w )z4Convert Mapping or AttrDict objects to dictionaries.)
isinstanceAttrDictto_dictitems)objkvs      r   _convert_to_dictrg   ~   sP    #x {{}ILUAAjH5qyy{1<UUUs   -A%c                ,    t         j                  |       S N)r^   rH   r   s    r   _missing_attr_error_messagerj      s    *CCINNr   c                ,    t         j                  |       S ri   )r^   rK   r   s    r   _missing_key_error_messagerl      s    *BB3GGr   c                  f    e Zd ZdZd Zedd       ZddZddZddZ	ddZ
d Zdd	Zdd
ZddZy)ra   zjWe use AttrDict to wrap up dictionary values from secrets
    to provide dot access to nested secrets
    c                4    t        |      | j                  d<   y )N__nested_secrets__)dict__dict__)r0   values     r   r1   zAttrDict.__init__   s    .25k*+r   c                <    t        | t              s| S t        |       S ri   )r`   r   ra   )rr   s    r   _maybe_wrap_in_attr_dictz!AttrDict._maybe_wrap_in_attr_dict   s    %)LE?"r   c                ,    t        | j                        S ri   )lenro   r/   s    r   __len__zAttrDict.__len__   s    4**++r   c                ,    t        | j                        S ri   )iterro   r/   s    r   __iter__zAttrDict.__iter__       D++,,r   c                    	 | j                   |   }| j                  |      S # t        $ r t        t        |            w xY wri   )ro   rt   KeyErrorrl   r0   r   rr   s      r   __getitem__zAttrDict.__getitem__   sH    	<++C0E0077 	<5c:;;	<	   " A c                    	 | j                   |   }| j                  |      S # t        $ r t        t	        |            w xY wri   )ro   rt   r}   AttributeErrorrj   )r0   r   rr   s      r   __getattr__zAttrDict.__getattr__   sK    	I++I6E0077 	I !<Y!GHH	Ir   c                ,    t        | j                        S ri   )reprro   r/   s    r   __repr__zAttrDict.__repr__   r{   r   c                    t        d      )Nz)Secrets does not support item assignment.	TypeErrorr~   s      r   __setitem__zAttrDict.__setitem__   s    CDDr   c                    t        d      )Nz.Secrets does not support attribute assignment.r   r~   s      r   __setattr__zAttrDict.__setattr__   s    HIIr   c                ,    t        | j                        S ri   )r	   ro   r/   s    r   rb   zAttrDict.to_dict   s    //00r   N)rT   r
   rT   intrT   zIterator[str]r   rW   rT   r
   )r   rW   rT   r
   )rT   r   rT   dict[str, Any])rZ   r[   r\   r]   r1   staticmethodrt   rw   rz   r   r   r   r   r   rb   r   r   r   ra   ra      sK    : # #,-<I-EJ1r   ra   c                      e Zd ZdZd ZddZ	 	 	 	 ddZddZddZddZ	ddZ
dd	Zd d
Z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Zd'dZd(dZd)dZd*dZd+dZy),SecretszA dict-like class that stores secrets.
    Parses secrets.toml on-demand. Cannot be externally mutated.

    Safe to use from multiple threads.
    c                    d | _         t        j                         | _        d| _        d| _        t        d      | _        y )NFz4Emitted when a `secrets.toml` file has been changed.)doc)_secrets	threadingRLock_lock_file_watchers_installed"_suppress_print_error_on_exceptionr   file_change_listenerr/   s    r   r1   zSecrets.__init__   s7    26__&
(-%27/$*F%
!r   c                    | j                   }	 d| _         | j                          	 || _         y# t        $ r
 Y || _         yw xY w# || _         w xY w)a'  Load secrets.toml files from disk if they exists. If none exist,
        no exception will be raised. (If a file exists but is malformed,
        an exception *will* be raised.)

        Returns True if a secrets.toml file was successfully parsed, False otherwise.

        Thread-safe.
        TF)r   _parseFileNotFoundError)r0   &prev_suppress_print_error_on_exceptions     r   load_if_toml_existszSecrets.load_if_toml_exists   sg     261X1X.	 7;D3KKM 7 3	 ! 	 7 3		
 7 3s    . 	AA  AA 	Ac                    || _         y)zSet whether exceptions should be printed when accessing secrets.
        For internal use, may change in future releases without notice.N)r   )r0   !suppress_print_error_on_exceptions     r   %set_suppress_print_error_on_exceptionz-Secrets.set_suppress_print_error_on_exception   s    
 3T/r   c                Z    | j                   st        j                  t        |             yy)z?Print the given error message if exceptions are not suppressed.N)r   sterrorrW   )r0   	error_msgs     r   "_print_exception_if_not_suppressedz*Secrets._print_exception_if_not_suppressed   s     66HHS^$ 7r   c                    | j                   5  | j                  
	 ddd       y| j                  j                         D ]  \  }}| j                  ||        d| _        ddd       y# 1 sw Y   yxY w)zyClear the secrets dictionary and remove any secrets that were
        added to os.environ.

        Thread-safe.
        N)r   r   rc   "_maybe_delete_environment_variable)r0   re   rf   s      r   _resetzSecrets._reset   s]     ZZ}}$ Z ++-1771= . DM ZZs   A(;A((A1c                v   i }d}	 t        |d      5 }|j                         }ddd       d}	 ddl}|j	                  |j                               ||fS # 1 sw Y   4xY w# t        $ r i dfcY S w xY w# t        j                  f$ r-}t        j                  ||      }| j                  |        d}~ww xY w)z9Parse a TOML file and return the secrets as a dictionary.Fzutf-8)encodingNTr   )openreadr   tomlupdateloadsr   TomlDecodeErrorr^   rO   r   )	r0   r$   secretsfound_secrets_filefsecrets_file_strr   r%   r   s	            r   _parse_toml_filezSecrets._parse_toml_file  s    "	dW-#$668  . "&
	NN4::&678 ***+ .- ! 	u9	 4//0 	/VV" 
 33I>	s>   A# A
A# $A6 A A# #A32A36B8(B33B8c                   i }d}t        j                  |      D ]=  }t         j                  j                  ||      }t         j                  j	                  |      s1t
        j                  |      }| j                  |       t        |      i }t        j                  |      D ]y  }t         j                  j                  ||      }	t         j                  j	                  |	      rCt        |	      5 }
|
j                         j                         ||<   d}ddd       { t        |      dk(  r$|t        |j                               d      ||<   9|||<   @ ||fS # 1 sw Y   xY w)a  Parse a directory for secrets. Directory style can be used to support Kubernetes secrets that are mounted to folders.

        Example structure:
        - top_level_secret_folder
            - user_pass_secret (folder)
                - username (file), content: myuser
                - password (file), content: mypassword
            - my_plain_secret (folder)
                - regular_secret (file), content: mysecret

        See: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#create-a-pod-that-has-access-to-the-secret-data-through-a-volume
        And: https://docs.snowflake.com/en/developer-guide/snowpark-container-services/additional-considerations-services-jobs#passing-secrets-in-local-container-files
        FTN   r   )oslistdirr$   r!   isdirr^   rQ   r   
ValueErrorr   r   striprv   listkeys)r0   r$   r   r   dirnamer'   r   sub_secretsfilename	file_pathr   s              r   _parse_directoryzSecrets._parse_directory   s3    #%"zz$'G ggll49O77==1;ff#	 77	B ++KJJ7GGLL(C	 77==+)_,-FFHNN,<K))-& %_ 8 ;1$#.tK4D4D4F/G/J#K #. 3 (6 *** %_s   3$EE(c                   |j                  d      r| j                  |      S t        j                  j	                  |      r| j                  |      S t        j                  |      }| j                  |       t        |      )N.toml)
endswithr   r   r$   r   r   r^   rS   r   r   )r0   r$   r   s      r   _parse_file_pathzSecrets._parse_file_pathN  sn    ==!((..77==((..3SS
	 	//	:##r   c                R   | j                   }||S | j                  5  | j                   | j                   cddd       S i }t        j                  j	                  d      }d}|D ]-  }| j                  |      \  }}|xs |}|j                  |       / |s1t        j                  |      }| j                  |       t        |      |j                         D ]  \  }}	| j                  ||	        || _         | j                          | j                   cddd       S # 1 sw Y   yxY w)a  Parse our secrets.toml files if they're not already parsed.
        This function is safe to call from multiple threads.

        Parameters
        ----------
        print_exceptions : bool
            If True, then exceptions will be printed with `st.error` before
            being re-raised.

        Raises
        ------
        FileNotFoundError
            Raised if secrets.toml doesn't exist.

        Nsecrets.filesF)r   r   r   config
get_optionr   r   r^   rM   r   r   rc   _maybe_set_environment_variable_maybe_install_file_watchers)
r0   r   r"   r   r$   path_secretsfound_secrets_file_in_pathr   re   rf   s
             r   r   zSecrets._parse[  s   $ --NZZ}}(}} Z G--o>J!&";?;P;PQU;V88%7%U;U"|, #
 &3PP" 
 77	B'	22144Q: ( $DM--/==9 ZZs   DCDD&c                8    | j                         }t        |      S )zxConverts the secrets store into a nested dictionary, where nested AttrDict objects are also converted into dictionaries.)r   rg   )r0   r   s     r   rb   zSecrets.to_dict  s    ++-((r   c                z    t        |      }|t        t        t        fv rt        |      t        j
                  | <   yy)zdAdd the given key/value pair to os.environ if the value
        is a string, int, or float.
        N)typerW   r   floatr   environre   rf   
value_types      r   r   z'Secrets._maybe_set_environment_variable  s2    
 !W
#sE**FBJJqM +r   c                    t        |      }|t        t        t        fv r5t        j
                  j                  |       |k(  rt        j
                  | = yyy)ziRemove the given key/value pair from os.environ if the value
        is a string, int, or float.
        N)r   rW   r   r   r   r   getr   s      r   r   z*Secrets._maybe_delete_environment_variable  sD    
 !W
#sE**rzz~~a/@A/E

1 0F*r   c                   | j                   5  | j                  r
	 d d d        y t        j                  j	                  d      }|D ]  }	 |j                  d      r7t        j                  j                  j                  || j                  d       n6t        j                  j                  j                  || j                  d        d| _        d d d        y # t        $ r Y w xY w# 1 sw Y   y xY w)Nr   r   poll)watcher_typeT)r   r   r   r   r   r   	streamlitwatcherpath_watcher
watch_file_on_secrets_changed	watch_dirr   )r0   r"   r$   s      r   r   z$Secrets._maybe_install_file_watchers  s    ZZ,, Z --o>J"}}W-!))66AA  44)/ B  "))66@@  44)/ A  #, -1D)7 Z& )  	' Zs5   C($C(	A>C	C(	C%"C($C%%C((C1c                    | j                   5  t        j                  d|       | j                          | j	                          d d d        | j
                  j                          y # 1 sw Y   $xY w)Nz!Secret path %s changed, reloading)r   r   debugr   r   r   send)r0   changed_file_paths     r   r   zSecrets._on_secrets_changed  sL    ZZMM=?PQKKMKKM  	!!&&( Zs   7A''A0c                    	 | j                         |   }t        |t              s|S t        |      S # t        t
        f$ r t        t        |            w xY w)z{Return the value with the given key. If no such key
        exists, raise an AttributeError.

        Thread-safe.
        )r   r`   r   ra   r}   r   r   rj   r~   s      r   r   zSecrets.__getattr__  s[    
	CKKM#&EeW-& +, 	C !<S!ABB	Cs   $2 
2 $Ac                    	 | j                         |   }t        |t              s|S t        |      S # t        $ r t	        t        |            w xY w)ztReturn the value with the given key. If no such key
        exists, raise a KeyError.

        Thread-safe.
        )r   r`   r   ra   r}   rl   r~   s      r   r   zSecrets.__getitem__  sP    	<KKM#&EeW-& 	<5c:;;	<s   $2 
2 Ac                    t        j                         s| j                  j                   S t	        | j                               S )zAA string representation of the contents of the dict. Thread-safe.)r   exists	__class__rZ   r   r   r/   s    r   r   zSecrets.__repr__  s2     ~~nn--./DKKM""r   c                4    t        | j                               S )z/The number of entries in the dict. Thread-safe.)rv   r   r/   s    r   rw   zSecrets.__len__  s    4;;=!!r   c                &    || j                         v S z2True if the given key is in the dict. Thread-safe.r   )r0   re   s     r   has_keyzSecrets.has_key  s    DKKM!!r   c                >    | j                         j                         S )z,A view of the keys in the dict. Thread-safe.)r   r   r/   s    r   r   zSecrets.keys  s    {{}!!##r   c                >    | j                         j                         S )z.A view of the values in the dict. Thread-safe.)r   valuesr/   s    r   r   zSecrets.values  s    {{}##%%r   c                >    | j                         j                         S )z7A view of the key-value items in the dict. Thread-safe.)r   rc   r/   s    r   rc   zSecrets.items	  s    {{}""$$r   c                &    || j                         v S r   r   rJ   s     r   __contains__zSecrets.__contains__  s    dkkm##r   c                4    t        | j                               S )z3An iterator over the keys in the dict. Thread-safe.)ry   r   r/   s    r   rz   zSecrets.__iter__  s    DKKM""r   N)rT   bool)r   r   rT   rU   )r   rW   rT   rU   )rT   rU   )r$   rW   rT   ztuple[Mapping[str, Any], bool])rT   zMapping[str, Any]r   )re   r
   rf   r
   rT   rU   r   )rT   rW   r   )re   rW   rT   r   )rT   zKeysView[str])rT   zValuesView[Any])rT   zItemsView[str, Any])r   r
   rT   r   r   )rZ   r[   r\   r]   r1   r   r   r   r   r   r   r   r   rb   r   r   r   r   r   r   r   r   rw   r   r   r   rc   r   rz   r   r   r   r   r      s    	
4T15T	T%
!+:,+\$2!h)
 # #  1<)C$<#""$&%$#r   r   secrets_singleton)rd   zMapping[str, Any] | AttrDictrT   r   rV   rX   )%
__future__r   r   r   collections.abcr   r   r   r   r   copyr	   typingr
   r   r   r   blinkerr   r   r   streamlit.watcher.path_watcherr   streamlit.loggerr   rZ   r   __annotations__r   r^   rg   rj   rl   rW   ra   r   r   r   r   r   <module>r     s    # 	  N N     %  'H% %R. R.j *=)>  >VOH-1wsCx  -1`V#gc3h V#r
 #9 5 $r   