32
32
def config (
33
33
* configs : Iterable ,
34
34
prefix : str = "" ,
35
+ strip_prefix : bool = True ,
35
36
separator : Optional [str ] = None ,
36
37
remove_level : int = 1 ,
37
38
lowercase_keys : bool = False ,
@@ -44,6 +45,7 @@ def config(
44
45
Params:
45
46
configs: iterable of configurations
46
47
prefix: prefix to filter environment variables with
48
+ strip_prefix: whether to strip the prefix
47
49
remove_level: how many levels to remove from the resulting config
48
50
lowercase_keys: whether to convert every key to lower case.
49
51
ignore_missing_paths: whether to ignore failures from missing files/folders.
@@ -71,6 +73,9 @@ def config(
71
73
if isinstance (config_ , Mapping ):
72
74
instances .append (config_from_dict (config_ , ** default_kwargs ))
73
75
continue
76
+ elif isinstance (config_ , Configuration ):
77
+ instances .append (config_ )
78
+ continue
74
79
elif isinstance (config_ , str ):
75
80
if config_ .endswith (".py" ):
76
81
config_ = ("python" , config_ , * default_args )
@@ -82,8 +87,8 @@ def config(
82
87
config_ = ("toml" , config_ , True )
83
88
elif config_ .endswith (".ini" ):
84
89
config_ = ("ini" , config_ , True )
85
- elif config_ .endswith (".env" ):
86
- config_ = ("dotenv" , config_ , True )
90
+ elif config_ .endswith (".env" ) or config_ . startswith ( ".env" ) :
91
+ config_ = ("dotenv" , config_ , True , * default_args )
87
92
elif os .path .isdir (config_ ):
88
93
config_ = ("path" , config_ , remove_level )
89
94
elif config_ in ("env" , "environment" ):
@@ -103,7 +108,13 @@ def config(
103
108
instances .append (config_from_dict (* config_ [1 :], ** default_kwargs ))
104
109
elif type_ in ("env" , "environment" ):
105
110
params = list (config_ [1 :]) + default_args [(len (config_ ) - 1 ) :]
106
- instances .append (config_from_env (* params , ** default_kwargs ))
111
+ instances .append (
112
+ config_from_env (
113
+ * params ,
114
+ ** default_kwargs ,
115
+ strip_prefix = strip_prefix ,
116
+ ),
117
+ )
107
118
elif type_ == "python" :
108
119
if len (config_ ) < 2 :
109
120
raise ValueError ("No path specified for python module" )
@@ -113,6 +124,7 @@ def config(
113
124
* params ,
114
125
** default_kwargs ,
115
126
ignore_missing_paths = ignore_missing_paths ,
127
+ strip_prefix = strip_prefix ,
116
128
),
117
129
)
118
130
elif type_ == "json" :
@@ -137,6 +149,7 @@ def config(
137
149
* config_ [1 :],
138
150
** default_kwargs ,
139
151
ignore_missing_paths = ignore_missing_paths ,
152
+ strip_prefix = strip_prefix ,
140
153
),
141
154
)
142
155
elif type_ == "ini" :
@@ -145,6 +158,7 @@ def config(
145
158
* config_ [1 :],
146
159
** default_kwargs ,
147
160
ignore_missing_paths = ignore_missing_paths ,
161
+ strip_prefix = strip_prefix ,
148
162
),
149
163
)
150
164
elif type_ == "dotenv" :
@@ -153,6 +167,7 @@ def config(
153
167
* config_ [1 :],
154
168
** default_kwargs ,
155
169
ignore_missing_paths = ignore_missing_paths ,
170
+ strip_prefix = strip_prefix ,
156
171
),
157
172
)
158
173
elif type_ == "path" :
@@ -178,9 +193,10 @@ class EnvConfiguration(Configuration):
178
193
179
194
def __init__ (
180
195
self ,
181
- prefix : str ,
196
+ prefix : str = "" ,
182
197
separator : str = "__" ,
183
198
* ,
199
+ strip_prefix : bool = True ,
184
200
lowercase_keys : bool = False ,
185
201
interpolate : InterpolateType = False ,
186
202
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -189,9 +205,11 @@ def __init__(
189
205
190
206
prefix: prefix to filter environment variables with
191
207
separator: separator to replace by dots
208
+ strip_prefix: whether to include the prefix
192
209
lowercase_keys: whether to convert every key to lower case.
193
210
"""
194
211
self ._prefix = prefix
212
+ self ._strip_prefix = strip_prefix
195
213
self ._separator = separator
196
214
super ().__init__ (
197
215
{},
@@ -207,9 +225,12 @@ def reload(self) -> None:
207
225
for key , value in os .environ .items ():
208
226
if not key .startswith (self ._prefix + self ._separator ):
209
227
continue
210
- result [
211
- key [len (self ._prefix ) :].replace (self ._separator , "." ).strip ("." )
212
- ] = value
228
+ if self ._strip_prefix :
229
+ result [
230
+ key [len (self ._prefix ) :].replace (self ._separator , "." ).strip ("." )
231
+ ] = value
232
+ else :
233
+ result [key .replace (self ._separator , "." ).strip ("." )] = value
213
234
super ().__init__ (
214
235
result ,
215
236
lowercase_keys = self ._lowercase ,
@@ -222,6 +243,7 @@ def config_from_env(
222
243
prefix : str ,
223
244
separator : str = "__" ,
224
245
* ,
246
+ strip_prefix : bool = True ,
225
247
lowercase_keys : bool = False ,
226
248
interpolate : InterpolateType = False ,
227
249
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -231,6 +253,7 @@ def config_from_env(
231
253
Params:
232
254
prefix: prefix to filter environment variables with.
233
255
separator: separator to replace by dots.
256
+ strip_prefix: whether to include the prefix
234
257
lowercase_keys: whether to convert every key to lower case.
235
258
interpolate: whether to apply string interpolation when looking for items.
236
259
@@ -240,6 +263,7 @@ def config_from_env(
240
263
return EnvConfiguration (
241
264
prefix ,
242
265
separator ,
266
+ strip_prefix = strip_prefix ,
243
267
lowercase_keys = lowercase_keys ,
244
268
interpolate = interpolate ,
245
269
interpolate_type = interpolate_type ,
@@ -463,13 +487,15 @@ def __init__(
463
487
read_from_file : bool = False ,
464
488
* ,
465
489
section_prefix : str = "" ,
490
+ strip_prefix : bool = True ,
466
491
lowercase_keys : bool = False ,
467
492
interpolate : InterpolateType = False ,
468
493
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
469
494
ignore_missing_paths : bool = False ,
470
495
):
471
496
"""Class Constructor."""
472
497
self ._section_prefix = section_prefix
498
+ self ._strip_prefix = strip_prefix
473
499
super ().__init__ (
474
500
data = data ,
475
501
read_from_file = read_from_file ,
@@ -502,8 +528,9 @@ def optionxform(self, optionstr: str) -> str:
502
528
data = cast (str , data )
503
529
cfg = ConfigParser ()
504
530
cfg .read_string (data )
531
+ n = len (self ._section_prefix ) if self ._strip_prefix else 0
505
532
result = {
506
- section [len ( self . _section_prefix ) :] + "." + k : v
533
+ section [n :] + "." + k : v
507
534
for section , values in cfg .items ()
508
535
for k , v in values .items ()
509
536
if section .startswith (self ._section_prefix )
@@ -516,6 +543,7 @@ def config_from_ini(
516
543
read_from_file : bool = False ,
517
544
* ,
518
545
section_prefix : str = "" ,
546
+ strip_prefix : bool = True ,
519
547
lowercase_keys : bool = False ,
520
548
interpolate : InterpolateType = False ,
521
549
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -538,6 +566,7 @@ def config_from_ini(
538
566
data ,
539
567
read_from_file ,
540
568
section_prefix = section_prefix ,
569
+ strip_prefix = strip_prefix ,
541
570
lowercase_keys = lowercase_keys ,
542
571
interpolate = interpolate ,
543
572
interpolate_type = interpolate_type ,
@@ -555,14 +584,17 @@ def __init__(
555
584
prefix : str = "" ,
556
585
separator : str = "__" ,
557
586
* ,
587
+ strip_prefix : bool = True ,
558
588
lowercase_keys : bool = False ,
559
589
interpolate : InterpolateType = False ,
560
590
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
561
591
ignore_missing_paths : bool = False ,
562
592
):
563
593
"""Class Constructor."""
564
594
self ._prefix = prefix
595
+ self ._strip_prefix = strip_prefix
565
596
self ._separator = separator
597
+
566
598
super ().__init__ (
567
599
data = data ,
568
600
read_from_file = read_from_file ,
@@ -589,8 +621,9 @@ def _reload(
589
621
parse_env_line (x ) for x in data .splitlines () if x and not x .startswith ("#" )
590
622
)
591
623
624
+ n = len (self ._prefix ) if self ._strip_prefix else 0
592
625
result = {
593
- k [len ( self . _prefix ) :].replace (self ._separator , "." ).strip ("." ): v
626
+ k [n :].replace (self ._separator , "." ).strip ("." ): v
594
627
for k , v in result .items ()
595
628
if k .startswith (self ._prefix )
596
629
}
@@ -604,6 +637,7 @@ def config_from_dotenv(
604
637
prefix : str = "" ,
605
638
separator : str = "__" ,
606
639
* ,
640
+ strip_prefix : bool = True ,
607
641
lowercase_keys : bool = False ,
608
642
interpolate : InterpolateType = False ,
609
643
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -629,6 +663,7 @@ def config_from_dotenv(
629
663
read_from_file ,
630
664
prefix = prefix ,
631
665
separator = separator ,
666
+ strip_prefix = strip_prefix ,
632
667
lowercase_keys = lowercase_keys ,
633
668
interpolate = interpolate ,
634
669
interpolate_type = interpolate_type ,
@@ -645,6 +680,7 @@ def __init__(
645
680
prefix : str = "" ,
646
681
separator : str = "_" ,
647
682
* ,
683
+ strip_prefix : bool = True ,
648
684
lowercase_keys : bool = False ,
649
685
interpolate : InterpolateType = False ,
650
686
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -677,6 +713,7 @@ def __init__(
677
713
module = importlib .import_module (module )
678
714
self ._module : Optional [ModuleType ] = module
679
715
self ._prefix = prefix
716
+ self ._strip_prefix = strip_prefix
680
717
self ._separator = separator
681
718
except (FileNotFoundError , ModuleNotFoundError ):
682
719
if not ignore_missing_paths :
@@ -699,10 +736,9 @@ def reload(self) -> None:
699
736
for x in dir (self ._module )
700
737
if not x .startswith ("__" ) and x .startswith (self ._prefix )
701
738
]
739
+ n = len (self ._prefix ) if self ._strip_prefix else 0
702
740
result = {
703
- k [len (self ._prefix ) :]
704
- .replace (self ._separator , "." )
705
- .strip ("." ): getattr (self ._module , k )
741
+ k [n :].replace (self ._separator , "." ).strip ("." ): getattr (self ._module , k )
706
742
for k in variables
707
743
}
708
744
else :
@@ -720,6 +756,7 @@ def config_from_python(
720
756
prefix : str = "" ,
721
757
separator : str = "_" ,
722
758
* ,
759
+ strip_prefix : bool = True ,
723
760
lowercase_keys : bool = False ,
724
761
interpolate : InterpolateType = False ,
725
762
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -741,6 +778,7 @@ def config_from_python(
741
778
module ,
742
779
prefix ,
743
780
separator ,
781
+ strip_prefix = strip_prefix ,
744
782
lowercase_keys = lowercase_keys ,
745
783
interpolate = interpolate ,
746
784
interpolate_type = interpolate_type ,
@@ -882,6 +920,7 @@ def __init__(
882
920
read_from_file : bool = False ,
883
921
* ,
884
922
section_prefix : str = "" ,
923
+ strip_prefix : bool = True ,
885
924
lowercase_keys : bool = False ,
886
925
interpolate : InterpolateType = False ,
887
926
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -894,6 +933,7 @@ def __init__(
894
933
)
895
934
896
935
self ._section_prefix = section_prefix
936
+ self ._strip_prefix = strip_prefix
897
937
super ().__init__ (
898
938
data = data ,
899
939
read_from_file = read_from_file ,
@@ -920,8 +960,9 @@ def _reload(
920
960
loaded = toml .loads (data )
921
961
loaded = cast (dict , loaded )
922
962
963
+ n = len (self ._section_prefix ) if self ._section_prefix else 0
923
964
result = {
924
- k [len ( self . _section_prefix ) :]: v
965
+ k [n :]: v
925
966
for k , v in self ._flatten_dict (loaded ).items ()
926
967
if k .startswith (self ._section_prefix )
927
968
}
@@ -934,6 +975,7 @@ def config_from_toml(
934
975
read_from_file : bool = False ,
935
976
* ,
936
977
section_prefix : str = "" ,
978
+ strip_prefix : bool = True ,
937
979
lowercase_keys : bool = False ,
938
980
interpolate : InterpolateType = False ,
939
981
interpolate_type : InterpolateEnumType = InterpolateEnumType .STANDARD ,
@@ -955,6 +997,7 @@ def config_from_toml(
955
997
data ,
956
998
read_from_file ,
957
999
section_prefix = section_prefix ,
1000
+ strip_prefix = strip_prefix ,
958
1001
lowercase_keys = lowercase_keys ,
959
1002
interpolate = interpolate ,
960
1003
interpolate_type = interpolate_type ,
0 commit comments