U
    nËj7  ã                   @   s|  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m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 d d	lmZm Z m!Z!m"Z" e#e$ƒ ƒZ%ed
ge	e#ef f Z&eee
e eedf f Z'G dd„ de(ƒZ)G dd
„ d
eƒZ*G dd„ dƒZ+G dd„ dƒZ,G dd„ dƒZ-dddœee#e.e	e#ee# f dœdd„Z/ee#e.ee dœdd„Z0dS )é    N)ÚPath)ÚAbstractSetÚAnyÚCallableÚClassVarÚDictÚListÚMappingÚOptionalÚTupleÚTypeÚUnion)Ú
BaseConfigÚExtra)Ú
ModelField)Ú	BaseModel)ÚJsonWrapper)ÚStrPathÚdisplay_as_typeÚ
get_originÚis_union)Údeep_updateÚlenient_issubclassÚ	path_typeÚsequence_likeÚBaseSettings.c                   @   s   e Zd ZdS )ÚSettingsErrorN)Ú__name__Ú
__module__Ú__qualname__© r    r    ú</tmp/pip-unpacked-wheel-zvl9l234/pydantic/v1/env_settings.pyr      s   r   c                	       s¦   e Zd ZU dZedddfee ee ee ee e	ddœ‡ fdd„Z
deee	f ee ee ee ee eee	f dœdd„ZG d	d
„ d
eƒZeee  ed< ‡  ZS )r   zü
    Base class for settings, allowing values to be overridden by environment variables.

    This is useful in production for secrets you do not wish to save in code, it plays nicely with docker(-compose),
    Heroku and any 12 factor app design.
    N)Ú	_env_fileÚ_env_file_encodingÚ_env_nested_delimiterÚ_secrets_dirÚvaluesÚreturnc              	      s"   t ƒ jf | j|||||d�Ž d S )N)r"   r#   r$   r%   )ÚsuperÚ__init__Ú_build_values)Z__pydantic_self__r"   r#   r$   r%   r&   ©Ú	__class__r    r!   r)      s    	ûÿzBaseSettings.__init__)Úinit_kwargsr"   r#   r$   r%   r'   c           
         sœ   t |d�}t|tkr|nˆ jj|d k	r*|nˆ jj|d k	r<|nˆ jjtˆ jjƒd�}t	|p^ˆ jj
d�}ˆ jj|||d�}	|	r”tt‡ fdd„|	D ƒƒŽ S i S d S )N©r-   ©Úenv_fileÚenv_file_encodingÚenv_nested_delimiterÚenv_prefix_len©Úsecrets_dir)Úinit_settingsÚenv_settingsÚfile_secret_settingsc                    s   g | ]}|ˆ ƒ‘qS r    r    )Ú.0Úsource©Úselfr    r!   Ú
<listcomp>L   s     z.BaseSettings._build_values.<locals>.<listcomp>)ÚInitSettingsSourceÚEnvSettingsSourceÚenv_file_sentinelÚ
__config__r0   r1   r2   ÚlenÚ
env_prefixÚSecretsSettingsSourcer5   Úcustomise_sourcesr   Úreversed)
r<   r-   r"   r#   r$   r%   r6   r7   r8   Úsourcesr    r;   r!   r*   2   s     	

ø
  ÿzBaseSettings._build_valuesc                   @   sÖ   e Zd ZU dZeed< dZee ed< dZ	ee ed< dZ
ee ed< dZee ed< dZeed	< ejZeed
< dZeed< dZeed< eeddœdd„ƒZeeeeeedf dœdd„ƒZeeeedœdd„ƒZdS )zBaseSettings.ConfigÚ rC   Nr0   r1   r2   r5   TÚvalidate_allÚextraÚarbitrary_types_allowedFÚcase_sensitive©Úfieldr'   c                 C   sÊ   |   |j¡}| d¡p"|jj d¡}|d krN|jr>t dt¡ | j	|j h}nRt
|tƒr`|h}n@t
|ttfƒrt|}n,t|ƒr†t|ƒ}ntd|›dt|ƒ› d�ƒ‚| jsº| dd„ |D ƒ¡}||jjd< d S )	NÚenvzÑaliases are no longer used by BaseSettings to define which environment variables to read. Instead use the "env" field setting. See https://pydantic-docs.helpmanual.io/usage/settings/#environment-variable-nameszinvalid field env: z (z ); should be string, list or setc                 s   s   | ]}|  ¡ V  qd S ©N©Úlower)r9   Únr    r    r!   Ú	<genexpr>v   s     z4BaseSettings.Config.prepare_field.<locals>.<genexpr>Ú	env_names)Zget_field_infoÚnameÚgetÚ
field_inforJ   Z	has_aliasÚwarningsÚwarnÚFutureWarningrC   Ú
isinstanceÚstrÚsetÚ	frozensetr   ÚlistÚ	TypeErrorr   rL   r,   )ÚclsrN   Zfield_info_from_configrO   rU   r    r    r!   Úprepare_field]   s&    ü

z!BaseSettings.Config.prepare_field.)r6   r7   r8   r'   c                 C   s
   |||fS rP   r    )rb   r6   r7   r8   r    r    r!   rE   y   s    z%BaseSettings.Config.customise_sources)Ú
field_nameÚraw_valr'   c                 C   s
   |   |¡S rP   )Z
json_loads)rb   rd   re   r    r    r!   Úparse_env_var‚   s    z!BaseSettings.Config.parse_env_var)r   r   r   rC   r]   Ú__annotations__r0   r
   Ú
DotenvTyper1   r2   r5   r   rI   Úboolr   ZforbidrJ   rK   rL   Úclassmethodr   rc   ÚSettingsSourceCallabler   rE   r   rf   r    r    r    r!   ÚConfigR   s&   

ûrl   rA   )NNNN)r   r   r   Ú__doc__r@   r
   rh   r]   r   r   r)   r   r*   r   rl   r   r   rg   Ú__classcell__r    r    r+   r!   r      s6   
	ûù    ú

ù 5c                   @   sL   e Zd ZdZeeef dœdd„Zeeeef dœdd„Z	edœdd	„Z
d
S )r>   r.   c                 C   s
   || _ d S rP   r.   )r<   r-   r    r    r!   r)   �   s    zInitSettingsSource.__init__©Úsettingsr'   c                 C   s   | j S rP   r.   )r<   rp   r    r    r!   Ú__call__�   s    zInitSettingsSource.__call__©r'   c                 C   s   d| j ›d�S )NzInitSettingsSource(init_kwargs=ú)r.   r;   r    r    r!   Ú__repr__“   s    zInitSettingsSource.__repr__N)r   r   r   Ú	__slots__r   r]   r   r)   r   rq   rt   r    r    r    r!   r>   Š   s   r>   c                   @   s²   e Zd ZdZdee ee ee edœdd„Ze	e
eef dœdd„Zee
eee f d	œd
d„Zeeeef dœdd„Zeeeee f e
eef dœdd„Zedœdd„ZdS )r?   r/   Nr   c                 C   s   || _ || _|| _|| _d S rP   r/   )r<   r0   r1   r2   r3   r    r    r!   r)   š   s    zEnvSettingsSource.__init__ro   c                 C   sN  i }|j jrtj}ndd„ tj ¡ D ƒ}|  |j j¡}|rB||–}|j ¡ D ]ü}d}|jj	d D ]}| 
|¡}|dk	r` q|q`|  |¡\}}	|�r6|dkr´|  ||¡}
|
r²|
||j< n€z|j  |j|¡}W n: tk
�r } z|	sòtd|› d�ƒ|‚W 5 d}~X Y nX t|tƒ�r*t||  ||¡ƒ||j< n
|||j< qL|dk	rL|||j< qL|S )zP
        Build environment variables suitable for passing to the Model.
        c                 S   s   i | ]\}}|  ¡ |“qS r    rQ   ©r9   ÚkÚvr    r    r!   Ú
<dictcomp>¯   s      z.EnvSettingsSource.__call__.<locals>.<dictcomp>NrU   úerror parsing env var "ú")rA   rL   ÚosÚenvironÚitemsÚ_read_env_filesÚ
__fields__r&   rX   rJ   rW   Úfield_is_complexÚexplode_env_varsÚaliasrf   rV   Ú
ValueErrorr   r\   Údictr   )r<   rp   ÚdÚenv_varsÚdotenv_varsrN   Úenv_valÚenv_nameÚ
is_complexÚallow_parse_failureZenv_val_builtÚer    r    r!   rq   ¦   s<    
$zEnvSettingsSource.__call__)rL   r'   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©ÚencodingrL   )r0   r\   r]   r|   ÚPathLiker   Ú
expanduserÚis_fileÚupdateÚread_env_filer1   )r<   rL   Z	env_filesrˆ   r0   Zenv_pathr    r    r!   r   Õ   s    ÿz!EnvSettingsSource._read_env_filesrM   c                 C   sX   t |jtƒrdS | ¡ rd}n2tt|jƒƒrL|jrLtdd„ |jD ƒƒrLd}ndS d|fS )za
        Find out if a field is complex, and if so whether JSON errors should be ignored
        )FFFc                 s   s   | ]}|  ¡ V  qd S rP   )r‹   )r9   Úfr    r    r!   rT   ð   s     z5EnvSettingsSource.field_is_complex.<locals>.<genexpr>T)	r   Ú
annotationr   r‹   r   r   Útype_Z
sub_fieldsÚany)r<   rN   rŒ   r    r    r!   r�   ç   s    (z"EnvSettingsSource.field_is_complex)rN   r‡   r'   c                    s�   ‡fdd„|j jd D ƒ}i }| ¡ D ]d\‰ }t‡ fdd„|D ƒƒsFq&ˆ ˆjd… }| ˆj¡�^}}}	|}
|D ]}|
 |i ¡}
qp||
|	< q&|S )zÊ
        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.
        c                    s   g | ]}|› ˆ j › �‘qS r    )r2   )r9   rŠ   r;   r    r!   r=   ý   s     z6EnvSettingsSource.explode_env_vars.<locals>.<listcomp>rU   c                 3   s   | ]}ˆ   |¡V  qd S rP   )Ú
startswith)r9   Úprefix)rŠ   r    r!   rT      s     z5EnvSettingsSource.explode_env_vars.<locals>.<genexpr>N)rX   rJ   r~   r˜   r3   Úsplitr2   Ú
setdefault)r<   rN   r‡   ÚprefixesÚresultr‰   Zenv_name_without_prefixÚ_ÚkeysZlast_keyÚenv_varÚkeyr    )rŠ   r<   r!   r‚   ÷   s    
z"EnvSettingsSource.explode_env_varsrr   c                 C   s   d| j ›d| j›d| j›d�S )NzEnvSettingsSource(env_file=z, env_file_encoding=z, env_nested_delimiter=rs   )r0   r1   r2   r;   r    r    r!   rt     s    ÿzEnvSettingsSource.__repr__)Nr   )r   r   r   ru   r
   rh   r]   Úintr)   r   r   r   rq   ri   r   r   r   r�   r	   r‚   rt   r    r    r    r!   r?   —   s     ûû/&r?   c                   @   sH   e Zd ZdZee dœdd„Zeee	e
f dœdd„Ze	dœdd	„Zd
S )rD   r4   c                 C   s
   || _ d S rP   r4   )r<   r5   r    r    r!   r)     s    zSecretsSettingsSource.__init__ro   c           	      C   s&  i }| j dkr|S t| j ƒ ¡ }| ¡ s>t d|› d�¡ |S | ¡ sXtdt|ƒ› �ƒ‚|j	 
¡ D ]¾}|jjd D ]¬}t|||jjƒ}|sŒqr| ¡ rþ| ¡  ¡ }| ¡ ròz|j |j|¡}W n4 tk
rð } ztd|› d�ƒ|‚W 5 d}~X Y nX |||j< qrtjd|› d	t|ƒ› d
�dd� qrqb|S )z4
        Build fields from "secrets" files.
        Nzdirectory "z" does not existz.secrets_dir must reference a directory, not a rU   rz   r{   zattempted to load secret file "z" but found a z	 instead.é   )Ú
stacklevel)r5   r   r‘   ÚexistsrY   rZ   Úis_dirr   r   r€   r&   rX   rJ   Úfind_case_pathrA   rL   r’   Ú	read_textÚstripr‹   rf   rV   r„   rƒ   )	r<   rp   ZsecretsZsecrets_pathrN   rŠ   ÚpathZsecret_valuer�   r    r    r!   rq     s6    
$þ
zSecretsSettingsSource.__call__rr   c                 C   s   d| j ›d�S )Nz"SecretsSettingsSource(secrets_dir=rs   r4   r;   r    r    r!   rt   B  s    zSecretsSettingsSource.__repr__N)r   r   r   ru   r
   r   r)   r   r   r]   r   rq   rt   r    r    r    r!   rD     s   )rD   FrŽ   )Ú	file_pathr�   rL   r'   c             
   C   sl   zddl m} W n, tk
r< } ztdƒ|‚W 5 d }~X Y nX || |pHdd�}|sddd„ | ¡ D ƒS |S d S )Nr   )Údotenv_valueszBpython-dotenv is not installed, run `pip install pydantic[dotenv]`Úutf8)r�   c                 S   s   i | ]\}}|  ¡ |“qS r    rQ   rv   r    r    r!   ry   P  s      z!read_env_file.<locals>.<dictcomp>)Zdotenvr­   ÚImportErrorr~   )r¬   r�   rL   r­   r�   Z	file_varsr    r    r!   r”   F  s    r”   )Údir_pathÚ	file_namerL   r'   c                 C   sB   |   ¡ D ]4}|j|kr|  S |s|j ¡ | ¡ kr|  S qdS )zZ
    Find a file within path's directory matching filename, optionally ignoring case.
    N)ÚiterdirrV   rR   )r°   r±   rL   r•   r    r    r!   r¨   U  s    

r¨   )1r|   rY   Úpathlibr   Útypingr   r   r   r   r   r   r	   r
   r   r   r   Zpydantic.v1.configr   r   Zpydantic.v1.fieldsr   Zpydantic.v1.mainr   Zpydantic.v1.typesr   Zpydantic.v1.typingr   r   r   r   Zpydantic.v1.utilsr   r   r   r   r]   Úobjectr@   rk   rh   r„   r   r   r>   r?   rD   ri   r”   r¨   r    r    r    r!   Ú<module>   s4   4
s|4 ÿ  þ