U
    ARd0                     @   s*  U d dl Z d dl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mZmZ d dlZd dlmZ d dlmZ d dlZd dlZd dlmZmZ d dlmZ eeZededgZee
e   e!d	< e e d
ddZ"e e dddZ#G dd dee ef Z$G dd dee ef Z%e%eZ&ee!d< dS )    N)deepcopy)
AnyDict	ItemsViewIteratorKeysViewListMappingNoReturnOptional
ValuesView)Signal)Final)	file_utilruntime)
get_loggerzsecrets.tomlSECRETS_FILE_LOCS	attr_namereturnc                 C   s   d|  dS )Nzst.secrets has no attribute "". Did you forget to add it to secrets.toml or the app settings on Streamlit Cloud? More info: https://docs.streamlit.io/streamlit-cloud/get-started/deploy-an-app/connect-to-data-sources/secrets-management )r   r   r   =/tmp/pip-unpacked-wheel-b9et7o5g/streamlit/runtime/secrets.py_missing_attr_error_message1   s    
r   keyr   c                 C   s   d|  dS )Nzst.secrets has no key "r   r   )r   r   r   r   _missing_key_error_message9   s    
r   c                   @   s   e Zd ZdZdd ZeedddZedddZ	e
e dd	d
ZeedddZeedddZdd ZedddZedddZeeef dddZdS )AttrDictzo
    We use AttrDict to wrap up dictionary values from secrets
    to provide dot access to nested secrets
    c                 C   s   t || jd< d S )N__nested_secrets__)dict__dict__)selfvaluer   r   r   __init__G   s    zAttrDict.__init__r   c                 C   s   t | ts| S t| S d S N)
isinstancer	   r   )r"   r   r   r   _maybe_wrap_in_attr_dictJ   s    
z!AttrDict._maybe_wrap_in_attr_dictc                 C   s
   t | jS r%   )lenr   r!   r   r   r   __len__Q   s    zAttrDict.__len__c                 C   s
   t | jS r%   )iterr   r)   r   r   r   __iter__T   s    zAttrDict.__iter__r   c                 C   s<   z| j | }| |W S  tk
r6   tt|Y nX d S r%   )r   r'   KeyErrorr   r!   r   r"   r   r   r   __getitem__W   s
    
zAttrDict.__getitem__r   c                 C   s<   z| j | }| |W S  tk
r6   tt|Y nX d S r%   )r   r'   r-   AttributeErrorr   )r!   r   r"   r   r   r   __getattr__^   s
    
zAttrDict.__getattr__c                 C   s
   t | jS r%   )reprr   r)   r   r   r   __repr__e   s    zAttrDict.__repr__c                 C   s   t dd S )Nz)Secrets does not support item assignment.	TypeErrorr.   r   r   r   __setitem__h   s    zAttrDict.__setitem__c                 C   s   t dd S )Nz.Secrets does not support attribute assignment.r4   r.   r   r   r   __setattr__k   s    zAttrDict.__setattr__c                 C   s
   t | jS r%   )r   r   r)   r   r   r   to_dictn   s    zAttrDict.to_dictN)__name__
__module____qualname____doc__r#   staticmethodr   r'   intr*   r   strr,   r/   r1   r3   r
   r6   r7   r   r8   r   r   r   r   r   A   s   r   c                   @   sF  e Zd ZdZee dddZedddZddd	d
Z	ee
eef dddZeeeddddZeeeddddZddddZddddZeedddZeedddZedddZedddZeed d!d"Zee dd#d$Zee dd%d&Zeeef dd'd(Zeedd)d*Zee dd+d,Z dS )-SecretszA dict-like class that stores secrets.
    Parses secrets.toml on-demand. Cannot be externally mutated.

    Safe to use from multiple threads.
    )
file_pathsc                 C   s,   d | _ t | _d| _|| _tdd| _d S )NFz4Emitted when a `secrets.toml` file has been changed.)doc)_secrets	threadingRLock_lock_file_watchers_installed_file_pathsr   file_change_listener)r!   rA   r   r   r   r#   y   s    
zSecrets.__init__r$   c                 C   s.   z| j dd W dS  tk
r(   Y dS X dS )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.
        Fprint_exceptionsTN)_parseFileNotFoundErrorr)   r   r   r   load_if_toml_exists   s
    	zSecrets.load_if_toml_existsNc              	   C   sT   | j D | jdkr W 5 Q R  dS | j D ]\}}| || q*d| _W 5 Q R X dS )zyClear the secrets dictionary and remove any secrets that were
        added to os.environ.

        Thread-safe.
        N)rF   rC   items"_maybe_delete_environment_variable)r!   kvr   r   r   _reset   s    
zSecrets._reset)rK   r   c           
      C   sp  | j }|dk	r|S | jL | j dk	r8| j W  5 Q R  S d}i }| jD ]~}z(t|dd}| }W 5 Q R X d}W n tk
r   Y qFY nX z|t| W qF   |rt	
d|   Y qFX qF|sdd| j }|rt	
| t|td	d
 | jD dkr&tdd| j d | D ]\}}	| ||	 q.|| _ |   | j W  5 Q R  S Q R X dS )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.

        NFzutf-8)encodingTzError parsing secrets file at zANo secrets files found. Valid paths for a secrets.toml file are: z, c                 S   s   g | ]}t j|r|qS r   )ospathexists).0pr   r   r   
<listcomp>   s      z"Secrets._parse.<locals>.<listcomp>   z%Secrets found in multiple locations: z`. When multiple secret.toml files exist, local secrets will take precedence over global secrets.)rC   rF   rH   openreadrM   updatetomlloadssterrorjoinr(   _LOGGERinforO   _maybe_set_environment_variable_maybe_install_file_watchers)
r!   rK   ZsecretsZfound_secrets_filerV   fZsecrets_file_strerr_msgrQ   rR   r   r   r   rL      sF    





zSecrets._parse)rQ   rR   r   c                 C   s(   t |}|tttfkr$t|tj| < dS )zdAdd the given key/value pair to os.environ if the value
        is a string, int, or float.
        N)typer?   r>   floatrU   environrQ   rR   Z
value_typer   r   r   rf      s    z'Secrets._maybe_set_environment_variablec                 C   s2   t |}|tttfkr.tj| |kr.tj| = dS )ziRemove the given key/value pair from os.environ if the value
        is a string, int, or float.
        N)rj   r?   r>   rk   rU   rl   getrm   r   r   r   rP      s    z*Secrets._maybe_delete_environment_variablec              
   C   sl   | j \ | jrW 5 Q R  d S | jD ]4}ztjjj|| jdd W q" tk
rT   Y q"X q"d| _W 5 Q R X d S )Npoll)Zwatcher_typeT)	rF   rG   rH   	streamlitZwatcherZpath_watcherZ
watch_file_on_secrets_file_changedrM   )r!   rV   r   r   r   rg      s    

z$Secrets._maybe_install_file_watchersc              	   C   s@   | j & td| |   | jdd W 5 Q R X | j  d S )Nz"Secrets file %s changed, reloadingTrJ   )rF   rd   debugrS   rL   rI   send)r!   Zchanged_file_pathr   r   r   rq     s
    z Secrets._on_secrets_file_changedr   c              	   C   sV   z,|  d| }t|ts |W S t|W S W n$ ttfk
rP   tt|Y nX dS )z{Return the value with the given key. If no such key
        exists, raise an AttributeError.

        Thread-safe.
        TN)rL   r&   r	   r   r-   rM   r0   r   r.   r   r   r   r1     s    
zSecrets.__getattr__c                 C   sR   z,|  d| }t|ts |W S t|W S W n  tk
rL   tt|Y nX dS )ztReturn the value with the given key. If no such key
        exists, raise a KeyError.

        Thread-safe.
        TN)rL   r&   r	   r   r-   r   r.   r   r   r   r/   *  s    
zSecrets.__getitem__c                 C   s,   t  s| jj d| jdS t| dS )zAA string representation of the contents of the dict. Thread-safe.z(file_paths=)T)r   rW   	__class__r9   rH   r2   rL   r)   r   r   r   r3   9  s    zSecrets.__repr__c                 C   s   t | dS )z/The number of entries in the dict. Thread-safe.T)r(   rL   r)   r   r   r   r*   C  s    zSecrets.__len__)rQ   r   c                 C   s   ||  dkS z2True if the given key is in the dict. Thread-safe.TrL   )r!   rQ   r   r   r   has_keyG  s    zSecrets.has_keyc                 C   s   |  d S )z,A view of the keys in the dict. Thread-safe.T)rL   keysr)   r   r   r   ry   K  s    zSecrets.keysc                 C   s   |  d S )z.A view of the values in the dict. Thread-safe.T)rL   valuesr)   r   r   r   rz   O  s    zSecrets.valuesc                 C   s   |  d S )z7A view of the key-value items in the dict. Thread-safe.T)rL   rO   r)   r   r   r   rO   S  s    zSecrets.itemsc                 C   s   ||  dkS rv   rw   )r!   r   r   r   r   __contains__W  s    zSecrets.__contains__c                 C   s   t | dS )z3An iterator over the keys in the dict. Thread-safe.T)r+   rL   r)   r   r   r   r,   [  s    zSecrets.__iter__)!r9   r:   r;   r<   r   r?   r#   boolrN   rS   r	   r   rL   r=   rf   rP   rg   rq   r1   r/   r3   r>   r*   rx   r   ry   r   rz   r   rO   r{   r   r,   r   r   r   r   r@   r   s*   D

r@   secrets_singleton)'rU   rD   copyr   typingr   r   r   r   r   r   r	   r
   r   r   r_   Zblinkerr   Ztyping_extensionsr   rp   ra   Zstreamlit.watcher.path_watcherr   r   Zstreamlit.loggerr   r9   rd   Zget_streamlit_file_pathZget_project_streamlit_file_pathr   r?   __annotations__r   r   r   r@   r}   r   r   r   r   <module>   s*    01 o