@@ -23,14 +23,28 @@ class BaseSettings(BaseModel):
23
23
Heroku and any 12 factor app design.
24
24
"""
25
25
26
- def __init__ (__pydantic_self__ , _env_file : Union [Path , str , None ] = env_file_sentinel , ** values : Any ) -> None :
26
+ def __init__ (
27
+ __pydantic_self__ ,
28
+ _env_file : Union [Path , str , None ] = env_file_sentinel ,
29
+ _env_file_encoding : Optional [str ] = None ,
30
+ ** values : Any ,
31
+ ) -> None :
27
32
# Uses something other than `self` the first arg to allow "self" as a settable attribute
28
- super ().__init__ (** __pydantic_self__ ._build_values (values , _env_file = _env_file ))
29
-
30
- def _build_values (self , init_kwargs : Dict [str , Any ], _env_file : Union [Path , str , None ] = None ) -> Dict [str , Any ]:
31
- return deep_update (self ._build_environ (_env_file ), init_kwargs )
32
-
33
- def _build_environ (self , _env_file : Union [Path , str , None ] = None ) -> Dict [str , Optional [str ]]:
33
+ super ().__init__ (
34
+ ** __pydantic_self__ ._build_values (values , _env_file = _env_file , _env_file_encoding = _env_file_encoding )
35
+ )
36
+
37
+ def _build_values (
38
+ self ,
39
+ init_kwargs : Dict [str , Any ],
40
+ _env_file : Union [Path , str , None ] = None ,
41
+ _env_file_encoding : Optional [str ] = None ,
42
+ ) -> Dict [str , Any ]:
43
+ return deep_update (self ._build_environ (_env_file , _env_file_encoding ), init_kwargs )
44
+
45
+ def _build_environ (
46
+ self , _env_file : Union [Path , str , None ] = None , _env_file_encoding : Optional [str ] = None
47
+ ) -> Dict [str , Optional [str ]]:
34
48
"""
35
49
Build environment variables suitable for passing to the Model.
36
50
"""
@@ -42,10 +56,16 @@ def _build_environ(self, _env_file: Union[Path, str, None] = None) -> Dict[str,
42
56
env_vars = {k .lower (): v for k , v in os .environ .items ()}
43
57
44
58
env_file = _env_file if _env_file != env_file_sentinel else self .__config__ .env_file
59
+ env_file_encoding = _env_file_encoding if _env_file_encoding is not None else self .__config__ .env_file_encoding
45
60
if env_file is not None :
46
61
env_path = Path (env_file )
47
62
if env_path .is_file ():
48
- env_vars = {** read_env_file (env_path , case_sensitive = self .__config__ .case_sensitive ), ** env_vars }
63
+ env_vars = {
64
+ ** read_env_file (
65
+ env_path , encoding = env_file_encoding , case_sensitive = self .__config__ .case_sensitive
66
+ ),
67
+ ** env_vars ,
68
+ }
49
69
50
70
for field in self .__fields__ .values ():
51
71
env_val : Optional [str ] = None
@@ -68,6 +88,7 @@ def _build_environ(self, _env_file: Union[Path, str, None] = None) -> Dict[str,
68
88
class Config :
69
89
env_prefix = ''
70
90
env_file = None
91
+ env_file_encoding = None
71
92
validate_all = True
72
93
extra = Extra .forbid
73
94
arbitrary_types_allowed = True
@@ -102,13 +123,13 @@ def prepare_field(cls, field: ModelField) -> None:
102
123
__config__ : Config # type: ignore
103
124
104
125
105
- def read_env_file (file_path : Path , * , case_sensitive : bool = False ) -> Dict [str , Optional [str ]]:
126
+ def read_env_file (file_path : Path , * , encoding : str = None , case_sensitive : bool = False ) -> Dict [str , Optional [str ]]:
106
127
try :
107
128
from dotenv import dotenv_values
108
129
except ImportError as e :
109
130
raise ImportError ('python-dotenv is not installed, run `pip install pydantic[dotenv]`' ) from e
110
131
111
- file_vars : Dict [str , Optional [str ]] = dotenv_values (file_path )
132
+ file_vars : Dict [str , Optional [str ]] = dotenv_values (file_path , encoding = encoding )
112
133
if not case_sensitive :
113
134
return {k .lower (): v for k , v in file_vars .items ()}
114
135
else :
0 commit comments