@@ -45,11 +45,11 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str,
45
45
This is an abstract method that should be overrided in every settings source classes.
46
46
47
47
Args:
48
- field (FieldInfo) : The field.
49
- field_name (str) : The field name.
48
+ field: The field.
49
+ field_name: The field name.
50
50
51
51
Returns:
52
- tuple[str, Any, bool]: The key, value and a flag to determine whether value is complex.
52
+ A tuple contains the key, value and a flag to determine whether value is complex.
53
53
"""
54
54
pass
55
55
@@ -58,10 +58,10 @@ def field_is_complex(self, field: FieldInfo) -> bool:
58
58
Checks whether a field is complex, in which case it will attempt to be parsed as JSON.
59
59
60
60
Args:
61
- field (FieldInfo) : The field.
61
+ field: The field.
62
62
63
63
Returns:
64
- bool: Whether the field is complex.
64
+ Whether the field is complex.
65
65
"""
66
66
return _annotation_is_complex (field .annotation )
67
67
@@ -70,13 +70,13 @@ def prepare_field_value(self, field_name: str, field: FieldInfo, value: Any, val
70
70
Prepares the value of a field.
71
71
72
72
Args:
73
- field_name (str) : The field name.
74
- field (FieldInfo) : The field.
75
- value (Any) : The value of the field that has to be prepared.
73
+ field_name: The field name.
74
+ field: The field.
75
+ value: The value of the field that has to be prepared.
76
76
value_is_complex: A flag to determine whether value is complex.
77
77
78
78
Returns:
79
- Any: The prepared value.
79
+ The prepared value.
80
80
"""
81
81
if self .field_is_complex (field ) or value_is_complex :
82
82
return json .loads (value )
@@ -88,6 +88,10 @@ def __call__(self) -> dict[str, Any]:
88
88
89
89
90
90
class InitSettingsSource (PydanticBaseSettingsSource ):
91
+ """
92
+ Source class for loading values provided during settings class initialization.
93
+ """
94
+
91
95
def __init__ (self , settings_cls : type [BaseSettings ], init_kwargs : dict [str , Any ]):
92
96
self .init_kwargs = init_kwargs
93
97
super ().__init__ (settings_cls )
@@ -236,6 +240,10 @@ def __call__(self) -> dict[str, Any]:
236
240
237
241
238
242
class SecretsSettingsSource (PydanticBaseEnvSettingsSource ):
243
+ """
244
+ Source class for loading settings values from secret files.
245
+ """
246
+
239
247
def __init__ (self , settings_cls : type [BaseSettings ], secrets_dir : str | Path | None ):
240
248
self .secrets_dir = secrets_dir
241
249
super ().__init__ (settings_cls )
@@ -264,6 +272,14 @@ def __call__(self) -> dict[str, Any]:
264
272
def find_case_path (cls , dir_path : Path , file_name : str , case_sensitive : bool ) -> Path | None :
265
273
"""
266
274
Find a file within path's directory matching filename, optionally ignoring case.
275
+
276
+ Args:
277
+ dir_path: Directory path.
278
+ file_name: File name.
279
+ case_sensitive: Whether to search for file name case sensitively.
280
+
281
+ Returns:
282
+ Whether file path or `None` if file does not exist in directory.
267
283
"""
268
284
for f in dir_path .iterdir ():
269
285
if f .name == file_name :
@@ -273,6 +289,18 @@ def find_case_path(cls, dir_path: Path, file_name: str, case_sensitive: bool) ->
273
289
return None
274
290
275
291
def get_field_value (self , field : FieldInfo , field_name : str ) -> tuple [Any , str , bool ]:
292
+ """
293
+ Gets the value for field from secret file and a flag to determine whether value is complex.
294
+
295
+ Args:
296
+ field: The field.
297
+ field_name: The field name.
298
+
299
+ Returns:
300
+ A tuple contains the key, value if the file exists otherwise `None`, and
301
+ a flag to determine whether value is complex.
302
+ """
303
+
276
304
for field_key , env_name , value_is_complex in self ._extract_field_info (field , field_name ):
277
305
path = self .find_case_path (
278
306
self .secrets_path , env_name , self .settings_cls .model_config .get ('case_sensitive' , False )
@@ -296,6 +324,10 @@ def __repr__(self) -> str:
296
324
297
325
298
326
class EnvSettingsSource (PydanticBaseEnvSettingsSource ):
327
+ """
328
+ Source class for loading settings values from environment variables.
329
+ """
330
+
299
331
def __init__ (
300
332
self ,
301
333
settings_cls : type [BaseSettings ],
@@ -315,6 +347,18 @@ def _load_env_vars(self) -> Mapping[str, str | None]:
315
347
return {k .lower (): v for k , v in os .environ .items ()}
316
348
317
349
def get_field_value (self , field : FieldInfo , field_name : str ) -> tuple [Any , str , bool ]:
350
+ """
351
+ Gets the value for field from environment variables and a flag to determine whether value is complex.
352
+
353
+ Args:
354
+ field: The field.
355
+ field_name: The field name.
356
+
357
+ Returns:
358
+ A tuple contains the key, value if the file exists otherwise `None`, and
359
+ a flag to determine whether value is complex.
360
+ """
361
+
318
362
env_val : str | None = None
319
363
for field_key , env_name , value_is_complex in self ._extract_field_info (field , field_name ):
320
364
env_val = self .env_vars .get (env_name )
@@ -324,6 +368,22 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str,
324
368
return env_val , field_key , value_is_complex
325
369
326
370
def prepare_field_value (self , field_name : str , field : FieldInfo , value : Any , value_is_complex : bool ) -> Any :
371
+ """
372
+ Prepare value for the field.
373
+
374
+ * Extract value for nested field.
375
+ * Deserialize value to python object for complex field.
376
+
377
+ Args:
378
+ field: The field.
379
+ field_name: The field name.
380
+
381
+ Returns:
382
+ A tuple contains prepared value for the field.
383
+
384
+ Raises:
385
+ ValuesError: When There is an error in deserializing value for complex field.
386
+ """
327
387
is_complex , allow_parse_failure = self ._field_is_complex (field )
328
388
if is_complex or value_is_complex :
329
389
if value is None :
@@ -382,6 +442,13 @@ class Cfg(BaseSettings):
382
442
Then:
383
443
next_field(sub_model, 'vals') Returns the `vals` field of `SubModel` class
384
444
next_field(sub_model, 'sub_sub_model') Returns `sub_sub_model` field of `SubModel` class
445
+
446
+ Args:
447
+ field: The field.
448
+ key: The key (env name).
449
+
450
+ Returns:
451
+ Field if it finds the next field otherwise `None`.
385
452
"""
386
453
if not field or origin_is_union (get_origin (field .annotation )):
387
454
# no support for Unions of complex BaseSettings fields
@@ -396,6 +463,14 @@ def explode_env_vars(self, field_name: str, field: FieldInfo, env_vars: Mapping[
396
463
Process env_vars and extract the values of keys containing env_nested_delimiter into nested dictionaries.
397
464
398
465
This is applied to a single field, hence filtering by env_var prefix.
466
+
467
+ Args:
468
+ field_name: The field name.
469
+ field: The field.
470
+ env_vars: Environment variables.
471
+
472
+ Returns:
473
+ A dictionaty contains extracted values from nested env values.
399
474
"""
400
475
prefixes = [
401
476
f'{ env_name } { self .env_nested_delimiter } ' for _ , env_name , _ in self ._extract_field_info (field , field_name )
@@ -437,6 +512,10 @@ def __repr__(self) -> str:
437
512
438
513
439
514
class DotEnvSettingsSource (EnvSettingsSource ):
515
+ """
516
+ Source class for loading settings values from env files.
517
+ """
518
+
440
519
def __init__ (
441
520
self ,
442
521
settings_cls : type [BaseSettings ],
@@ -514,18 +593,6 @@ def read_env_file(
514
593
return file_vars
515
594
516
595
517
- def find_case_path (dir_path : Path , file_name : str , case_sensitive : bool ) -> Path | None :
518
- """
519
- Find a file within path's directory matching filename, optionally ignoring case.
520
- """
521
- for f in dir_path .iterdir ():
522
- if f .name == file_name :
523
- return f
524
- elif not case_sensitive and f .name .lower () == file_name .lower ():
525
- return f
526
- return None
527
-
528
-
529
596
def _annotation_is_complex (annotation : type [Any ] | None ) -> bool :
530
597
origin = get_origin (annotation )
531
598
return (
0 commit comments