U
    s\j`                     @  s  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 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  d dl!m"Z"m#Z# d dl$m%Z% d dl&m'Z'm(Z( d dl)m*Z* erd dl+m,Z, eee-eeee-f  eeee-f df f Z.edZ/de0d< G dd de1Z2G dd deZ3G dd de3Z4G dd de3Z5G dd de5Z6G dd de5Z7G d d! d!e7Z8dd"d#d$d%d&d'd(d)d*Z9d+d,d&d-d.d/Z:d+d&d0d1d2Z;dS )3    )annotationsN)ABCabstractmethod)deque)is_dataclass)Path)TYPE_CHECKINGAnyListMappingSequenceTupleUnioncast)dotenv_values)AliasChoices	AliasPath	BaseModelJson)origin_is_union)deep_updatelenient_issubclass)	FieldInfo)get_args
get_origin)path_type_label)BaseSettings. 
DotenvTypeENV_FILE_SENTINELc                   @  s   e Zd ZdS )SettingsErrorN)__name__
__module____qualname__ r$   r$   P/root/pica-gateway/venv/lib/python3.8/site-packages/pydantic_settings/sources.pyr    !   s   r    c                   @  s   e Zd ZdZddddZedddd	d
dZdddddZddddddddZdddddddZ	eddddZ
dS )PydanticBaseSettingsSourcezi
    Abstract base class for settings sources, every settings source classes should inherit from it.
    type[BaseSettings])settings_clsc                 C  s   || _ |j| _d S N)r(   model_configconfig)selfr(   r$   r$   r%   __init__*   s    z#PydanticBaseSettingsSource.__init__r   strtuple[Any, str, bool]field
field_namereturnc                 C  s   dS )a  
        Gets the value, the key for model creation, and a flag to determine whether value is complex.

        This is an abstract method that should be overridden in every settings source classes.

        Args:
            field: The field.
            field_name: The field name.

        Returns:
            A tuple contains the key, value and a flag to determine whether value is complex.
        Nr$   r,   r1   r2   r$   r$   r%   get_field_value.   s    z*PydanticBaseSettingsSource.get_field_valueboolr1   r3   c                 C  s   t |j|jS )z
        Checks whether a field is complex, in which case it will attempt to be parsed as JSON.

        Args:
            field: The field.

        Returns:
            Whether the field is complex.
        )_annotation_is_complex
annotationmetadata)r,   r1   r$   r$   r%   field_is_complex>   s    
z+PydanticBaseSettingsSource.field_is_complexr	   r2   r1   valuevalue_is_complexr3   c                 C  s(   |dk	r$|  |s|r$| |||S |S )aF  
        Prepares the value of a field.

        Args:
            field_name: The field name.
            field: The field.
            value: The value of the field that has to be prepared.
            value_is_complex: A flag to determine whether value is complex.

        Returns:
            The prepared value.
        N)r;   decode_complex_value)r,   r2   r1   r=   r>   r$   r$   r%   prepare_field_valueJ   s    z.PydanticBaseSettingsSource.prepare_field_value)r2   r1   r=   r3   c                 C  s
   t |S )a  
        Decode the value for a complex field

        Args:
            field_name: The field name.
            field: The field.
            value: The value of the field that has to be prepared.

        Returns:
            The decoded value for further preparation
        )jsonloads)r,   r2   r1   r=   r$   r$   r%   r?   [   s    z/PydanticBaseSettingsSource.decode_complex_valuedict[str, Any]r3   c                 C  s   d S r)   r$   r,   r$   r$   r%   __call__i   s    z#PydanticBaseSettingsSource.__call__N)r!   r"   r#   __doc__r-   r   r5   r;   r@   r?   rF   r$   r$   r$   r%   r&   %   s   r&   c                      sV   e Zd ZdZddd fddZddd	d
ddZddddZddddZ  ZS )InitSettingsSourcezX
    Source class for loading values provided during settings class initialization.
    r'   rC   )r(   init_kwargsc                   s   || _ t | d S r)   )rI   superr-   )r,   r(   rI   	__class__r$   r%   r-   s   s    zInitSettingsSource.__init__r   r.   r/   r0   c                 C  s   dS )N)Nr   Fr$   r4   r$   r$   r%   r5   w   s    z"InitSettingsSource.get_field_valuerD   c                 C  s   | j S r)   rI   rE   r$   r$   r%   rF   {   s    zInitSettingsSource.__call__c                 C  s   d| j dS )NzInitSettingsSource(init_kwargs=)rM   rE   r$   r$   r%   __repr__~   s    zInitSettingsSource.__repr__)	r!   r"   r#   rG   r-   r5   rF   rO   __classcell__r$   r$   rK   r%   rH   n   s
   rH   c                      sl   e Zd Zdddddd fddZd	d	d
ddZdd	ddddZddddddZddddZ  ZS )PydanticBaseEnvSettingsSourceNr'   bool | None
str | NoneNone)r(   case_sensitive
env_prefixr3   c                   sH   t  | |d k	r|n| jdd| _|d k	r4|n| jdd| _d S )NrU   FrV   r   )rJ   r-   r+   getrU   rV   )r,   r(   rU   rV   rK   r$   r%   r-      s    z&PydanticBaseEnvSettingsSource.__init__r.   )r=   r3   c                 C  s   | j s| S |S r)   )rU   lower)r,   r=   r$   r$   r%   _apply_case_sensitive   s    z3PydanticBaseEnvSettingsSource._apply_case_sensitiver   zlist[tuple[str, str, bool]]r0   c                 C  s   g }t |jttfr |j }n|j}|rt |tr|D ]t}t |trn||| |t	|dkrddndf q8t |tr8t
t|d }||| |t	|dkrdndf q8q||| |df n||| | j| df |S )a  
        Extracts field info. This info is used to get the value of field from environment variables.

        It returns a list of tuples, each tuple contains:
            * field_key: The key of field that has to be used in model creation.
            * env_name: The environment variable name of the field.
            * value_is_complex: A flag to determine whether the value from environment variable
              is complex and has to be parsed.

        Args:
            field (FieldInfo): The field.
            field_name (str): The field name.

        Returns:
            list[tuple[str, str, bool]]: List of tuples, each tuple contains field_key, env_name, and value_is_complex.
           TFr   )
isinstancevalidation_aliasr   r   Zconvert_to_aliaseslistr.   appendrY   lenr   rV   )r,   r1   r2   Z
field_infoZv_aliasaliasZ	first_argr$   r$   r%   _extract_field_info   s"    

(
z1PydanticBaseEnvSettingsSource._extract_field_inforC   )r1   field_valuesr3   c           	      C  s   i }|  D ]\}}d}|jr*t|jds4|||< q|jj  D ]&\}}|js@| | kr@|} qhq@|sv|||< qt|jtrt|t	r| 
||||< q|||< q|S )ae  
        Replace field names in values dict by looking in models fields insensitively.

        By having the following models:

            ```py
            class SubSubSub(BaseModel):
                VaL3: str

            class SubSub(BaseModel):
                Val2: str
                SUB_sub_SuB: SubSubSub

            class Sub(BaseModel):
                VAL1: str
                SUB_sub: SubSub

            class Settings(BaseSettings):
                nested: Sub

                model_config = SettingsConfigDict(env_nested_delimiter='__')
            ```

        Then:
            _replace_field_names_case_insensitively(
                field,
                {"val1": "v1", "sub_SUB": {"VAL2": "v2", "sub_SUB_sUb": {"vAl3": "v3"}}}
            )
            Returns {'VAL1': 'v1', 'SUB_sub': {'Val2': 'v2', 'SUB_sub_SuB': {'VaL3': 'v3'}}}
        Nmodel_fields)itemsr9   hasattrrc   r\   rX   r   r   r[   dict'_replace_field_names_case_insensitively)	r,   r1   rb   valuesnamer=   Zsub_model_fieldZsub_model_field_namefr$   r$   r%   rg      s"    
zEPydanticBaseEnvSettingsSource._replace_field_names_case_insensitivelyrD   c                 C  s  i }| j j D ]\}}z| ||\}}}W n> tk
rl } z td| d| jj d|W 5 d }~X Y nX z| ||||}W n> t	k
r } z td| d| jj d|W 5 d }~X Y nX |d k	r| j
st|jtrt|tr| ||||< q|||< q|S )Nzerror getting value for field "z" from source ""zerror parsing value for field ")r(   rc   rd   r5   	Exceptionr    rL   r!   r@   
ValueErrorrU   r   r9   r   r[   rf   rg   )r,   datar2   r1   Zfield_value	field_keyr>   er$   r$   r%   rF      s8    

z&PydanticBaseEnvSettingsSource.__call__)NN)	r!   r"   r#   r-   rY   ra   rg   rF   rP   r$   r$   rK   r%   rQ      s      (;rQ   c                      sz   e Zd ZdZddddddd fd	d
Zdd fddZedddddddZddddddZddddZ	  Z
S )SecretsSettingsSourcezE
    Source class for loading settings values from secret files.
    Nr'   zstr | Path | NonerR   rS   rT   )r(   secrets_dirrU   rV   r3   c                   s.   t  ||| |d k	r|n
| jd| _d S )Nrr   )rJ   r-   r+   rW   rr   )r,   r(   rr   rU   rV   rK   r$   r%   r-     s    zSecretsSettingsSource.__init__rC   rD   c                   sl   i }| j dkr|S t| j  | _| j sDtd| j d |S | j sbtdt	| j t
  S )z4
        Build fields from "secrets" files.
        Nzdirectory "z" does not existz.secrets_dir must reference a directory, not a )rr   r   
expandusersecrets_pathexistswarningswarnis_dirr    r   rJ   rF   )r,   ZsecretsrK   r$   r%   rF     s    


zSecretsSettingsSource.__call__r   r.   r6   zPath | None)dir_path	file_namerU   r3   c                 C  sB   |  D ]4}|j|kr|  S |s|j | kr|  S qdS )af  
        Find a file within path's directory matching filename, optionally ignoring case.

        Args:
            dir_path: Directory path.
            file_name: File name.
            case_sensitive: Whether to search for file name case sensitively.

        Returns:
            Whether file path or `None` if file does not exist in directory.
        N)iterdirri   rX   )clsry   rz   rU   rj   r$   r$   r%   find_case_path2  s    

z$SecretsSettingsSource.find_case_pathr   r/   r0   c                 C  sx   |  ||D ]`\}}}| | j|| j}|s.q| rL|  ||f  S tjd| dt	| ddd qd||fS )ag  
        Gets the value for field from secret file and a flag to determine whether value is complex.

        Args:
            field: The field.
            field_name: The field name.

        Returns:
            A tuple contains the key, value if the file exists otherwise `None`, and
                a flag to determine whether value is complex.
        zattempted to load secret file "z" but found a z	 instead.   )
stacklevelN)
ra   r}   rt   rU   is_file	read_textstriprv   rw   r   )r,   r1   r2   ro   env_namer>   pathr$   r$   r%   r5   F  s    z%SecretsSettingsSource.get_field_valuec                 C  s   d| j dS )Nz"SecretsSettingsSource(secrets_dir=rN   )rr   rE   r$   r$   r%   rO   c  s    zSecretsSettingsSource.__repr__)NNN)r!   r"   r#   rG   r-   rF   classmethodr}   r5   rO   rP   r$   r$   rK   r%   rq     s      
rq   c                      s   e Zd ZdZd,dddddd fdd	Zd
dddZddddddZddddddddZddddddZdddd d!Z	e
d"dd"d#d$d%Zddd
d&d'd(d)Zddd*d+Z  ZS )-EnvSettingsSourcezN
    Source class for loading settings values from environment variables.
    Nr'   rR   rS   rT   )r(   rU   rV   env_nested_delimiterr3   c                   sD   t  ||| |d k	r|n
| jd| _t| j| _|  | _	d S )Nr   )
rJ   r-   r+   rW   r   r_   rV   env_prefix_len_load_env_varsenv_vars)r,   r(   rU   rV   r   rK   r$   r%   r-   l  s
    zEnvSettingsSource.__init__Mapping[str, str | None]rD   c                 C  s    | j rtjS dd tj D S )Nc                 S  s   i | ]\}}|  |qS r$   rX   .0kvr$   r$   r%   
<dictcomp>~  s      z4EnvSettingsSource._load_env_vars.<locals>.<dictcomp>)rU   osenvironrd   rE   r$   r$   r%   r   {  s    z EnvSettingsSource._load_env_varsr   r.   r/   r0   c                 C  s>   d}|  ||D ]"\}}}| j|}|dk	r q4q|||fS )aq  
        Gets the value for field from environment variables and a flag to determine whether value is complex.

        Args:
            field: The field.
            field_name: The field name.

        Returns:
            A tuple contains the key, value if the file exists otherwise `None`, and
                a flag to determine whether value is complex.
        N)ra   r   rW   )r,   r1   r2   env_valro   r   r>   r$   r$   r%   r5     s    z!EnvSettingsSource.get_field_valuer	   r6   r<   c           	   
   C  s   |  |\}}|s|r|dkr8| ||| j}|r|S qz| |||}W n* tk
rt } z|sd|W 5 d}~X Y nX t|trt|| ||| jS |S n|dk	r|S dS )a  
        Prepare value for the field.

        * Extract value for nested field.
        * Deserialize value to python object for complex field.

        Args:
            field: The field.
            field_name: The field name.

        Returns:
            A tuple contains prepared value for the field.

        Raises:
            ValuesError: When There is an error in deserializing value for complex field.
        N)_field_is_complexexplode_env_varsr   r?   rm   r[   rf   r   )	r,   r2   r1   r=   r>   
is_complexallow_parse_failureZenv_val_builtrp   r$   r$   r%   r@     s     
z%EnvSettingsSource.prepare_field_valuetype[Any] | None	list[Any]r9   r:   r3   c                   s   t  fddt|D S )Nc                 3  s   | ]}t | V  qd S r)   )r8   )r   argr:   r$   r%   	<genexpr>  s     z6EnvSettingsSource._union_is_complex.<locals>.<genexpr>)anyr   )r,   r9   r:   r$   r   r%   _union_is_complex  s    z#EnvSettingsSource._union_is_complexztuple[bool, bool]r7   c                 C  s@   |  |rd}n(tt|jr4| |j|jr4d}ndS d|fS )za
        Find out if a field is complex, and if so whether JSON errors should be ignored
        FT)FF)r;   r   r   r9   r   r:   )r,   r1   r   r$   r$   r%   r     s    
z#EnvSettingsSource._field_is_complexzFieldInfo | None)r1   keyr3   c                 C  sF   | rt t| jrdS | jrBt| jdrB| jj|rB| jj| S dS )a  
        Find the field in a sub model by key(env name)

        By having the following models:

            ```py
            class SubSubModel(BaseSettings):
                dvals: Dict

            class SubModel(BaseSettings):
                vals: list[str]
                sub_sub_model: SubSubModel

            class Cfg(BaseSettings):
                sub_model: SubModel
            ```

        Then:
            next_field(sub_model, 'vals') Returns the `vals` field of `SubModel` class
            next_field(sub_model, 'sub_sub_model') Returns `sub_sub_model` field of `SubModel` class

        Args:
            field: The field.
            key: The key (env name).

        Returns:
            Field if it finds the next field otherwise `None`.
        Nrc   )r   r   r9   re   rc   rW   )r1   r   r$   r$   r%   
next_field  s
     zEnvSettingsSource.next_fieldrC   )r2   r1   r   r3   c                   s  fdd ||D }i }| D ]\ }t fdd|D sFq& jd }|j^}}	}
|}|}|	D ]}||}||i }qt||
}|r|r|\}}|rz	|
||}W n* t
k
r } z|s|W 5 d}~X Y nX |||
< q&|S )a  
        Process env_vars and extract the values of keys containing env_nested_delimiter into nested dictionaries.

        This is applied to a single field, hence filtering by env_var prefix.

        Args:
            field_name: The field name.
            field: The field.
            env_vars: Environment variables.

        Returns:
            A dictionaty contains extracted values from nested env values.
        c                   s    g | ]\}}}|  j  qS r$   )r   )r   _r   rE   r$   r%   
<listcomp>  s    z6EnvSettingsSource.explode_env_vars.<locals>.<listcomp>c                 3  s   | ]}  |V  qd S r)   )
startswith)r   prefix)r   r$   r%   r     s     z5EnvSettingsSource.explode_env_vars.<locals>.<genexpr>N)ra   rd   r   r   splitr   r   
setdefaultr   r?   rm   )r,   r2   r1   r   prefixesresultr   env_name_without_prefixr   keyslast_keyenv_varZtarget_fieldr   r   Zallow_json_failurerp   r$   )r   r,   r%   r     s2    


z"EnvSettingsSource.explode_env_varsc                 C  s   d| j d| jdS )Nz'EnvSettingsSource(env_nested_delimiter=, env_prefix_len=rN   )r   r   rE   r$   r$   r%   rO   !  s    zEnvSettingsSource.__repr__)NNN)r!   r"   r#   rG   r-   r   r5   r@   r   r   staticmethodr   r   rO   rP   r$   r$   rK   r%   r   g  s      (%.r   c                	      s|   e Zd ZdZeddddfdddddddd fd	d
ZddddZdddddZdd fddZddddZ	  Z
S )DotEnvSettingsSourcezB
    Source class for loading settings values from env files.
    Nr'   zDotenvType | NonerS   rR   rT   )r(   env_fileenv_file_encodingrU   rV   r   r3   c                   sJ   |t kr|n
|jd| _|d k	r&|n
|jd| _t |||| d S )Nr   r   )r   r*   rW   r   r   rJ   r-   )r,   r(   r   r   rU   rV   r   rK   r$   r%   r-   -  s    	zDotEnvSettingsSource.__init__r   rD   c                 C  s   |  | jS r)   )_read_env_filesrU   rE   r$   r$   r%   r   <  s    z#DotEnvSettingsSource._load_env_varsr6   )rU   r3   c                 C  sd   | j }|d kri S t|ttjfr(|g}i }|D ].}t| }| r0|t	|| j
|d q0|S )NencodingrU   )r   r[   r.   r   PathLiker   rs   r   updateread_env_filer   )r,   rU   Z	env_filesZdotenv_varsr   Zenv_pathr$   r$   r%   r   ?  s    z$DotEnvSettingsSource._read_env_filesrC   c                   s   t   }g }| js&dd | D }| j D ]Z\}}|| jr0|d k	r0|| jd  }|	| j
^}}|rv||ks|s0||kr0|||< q0|S )Nc                 S  s   g | ]}|  qS r$   r   )r   xr$   r$   r%   r   V  s     z1DotEnvSettingsSource.__call__.<locals>.<listcomp>)rJ   rF   rU   r   r   rd   r   rV   r   r   r   )r,   rn   Zdata_lower_keysr   Z	env_valuer   Z	first_keyr   rK   r$   r%   rF   Q  s    

zDotEnvSettingsSource.__call__r.   c              	   C  s&   d| j d| jd| jd| jd	S )NzDotEnvSettingsSource(env_file=z, env_file_encoding=z, env_nested_delimiter=r   rN   )r   r   r   r   rE   r$   r$   r%   rO   f  s    $zDotEnvSettingsSource.__repr__)r!   r"   r#   rG   r   r-   r   r   rF   rO   rP   r$   r$   rK   r%   r   (  s    r   Fr   r   rS   r6   r   )	file_pathr   rU   r3   c                C  s.   t | |p
dd}|s&dd | D S |S d S )Nutf8)r   c                 S  s   i | ]\}}|  |qS r$   r   r   r$   r$   r%   r   r  s      z!read_env_file.<locals>.<dictcomp>)r   rd   )r   r   rU   Z	file_varsr$   r$   r%   r   m  s    r   r   r   r   c                 C  sB   t dd |D rdS t| }t| p@t|p@t|dp@t|dS )Nc                 s  s   | ]}t |tV  qd S r)   )r[   r   )r   mdr$   r$   r%   r   x  s     z)_annotation_is_complex.<locals>.<genexpr>FZ__pydantic_core_schema__Z__get_pydantic_core_schema__)r   r   _annotation_is_complex_innerre   )r9   r:   originr$   r$   r%   r8   w  s    r8   )r9   r3   c              	   C  s2   t | ttfrdS t | ttttttt	fp0t
| S )NF)r   r.   bytesr   r   r   tupleset	frozensetr   r   )r9   r$   r$   r%   r     s
    r   )<
__future__r   Z_annotationsrA   r   rv   abcr   r   collectionsr   dataclassesr   pathlibr   typingr   r	   r
   r   r   r   r   r   Zdotenvr   Zpydanticr   r   r   r   Z pydantic._internal._typing_extrar   Zpydantic._internal._utilsr   r   Zpydantic.fieldsr   typing_extensionsr   r   Zpydantic_settings.utilsr   Zpydantic_settings.mainr   r.   r   r   __annotations__rm   r    r&   rH   rQ   rq   r   r   r   r8   r   r$   r$   r$   r%   <module>   sD    (,I X BF 
