@@ -135,35 +135,49 @@ def rewrite(path: Union[str, _PathLike]) -> Iterator[Tuple[IO[str], IO[str]]]:
135
135
shutil .move (dest .name , path )
136
136
137
137
138
- def set_key (
139
- dotenv_path : Union [str , _PathLike ],
140
- key_to_set : str ,
141
- value_to_set : str ,
138
+ def make_env_line (
139
+ key : str ,
140
+ value : str ,
142
141
quote_mode : str = "always" ,
143
142
export : bool = False ,
144
- ) -> Tuple [ Optional [ bool ], str , str ] :
143
+ ) -> str :
145
144
"""
146
- Adds or Updates a key/value to the given .env
147
-
148
- If the .env path given doesn't exist, fails instead of risking creating
149
- an orphan .env somewhere in the filesystem
145
+ Make a line which format fits to .env
150
146
"""
151
147
if quote_mode not in ("always" , "auto" , "never" ):
152
148
raise ValueError ("Unknown quote_mode: {}" .format (quote_mode ))
153
149
154
150
quote = (
155
151
quote_mode == "always"
156
- or (quote_mode == "auto" and not value_to_set .isalnum ())
152
+ or (quote_mode == "auto" and not value .isalnum ())
157
153
)
158
154
159
155
if quote :
160
- value_out = "'{}'" .format (value_to_set .replace ("'" , "\\ '" ))
156
+ value_out = "'{}'" .format (value .replace ("'" , "\\ '" ))
161
157
else :
162
- value_out = value_to_set
158
+ value_out = value
163
159
if export :
164
- line_out = 'export {}={}\n ' .format (key_to_set , value_out )
160
+ line_out = 'export {}={}\n ' .format (key , value_out )
165
161
else :
166
- line_out = "{}={}\n " .format (key_to_set , value_out )
162
+ line_out = "{}={}\n " .format (key , value_out )
163
+
164
+ return line_out
165
+
166
+
167
+ def set_key (
168
+ dotenv_path : Union [str , _PathLike ],
169
+ key_to_set : str ,
170
+ value_to_set : str ,
171
+ quote_mode : str = "always" ,
172
+ export : bool = False ,
173
+ ) -> Tuple [Optional [bool ], str , str ]:
174
+ """
175
+ Adds or Updates a key/value to the given .env
176
+
177
+ If the .env path given doesn't exist, fails instead of risking creating
178
+ an orphan .env somewhere in the filesystem
179
+ """
180
+ line_out = make_env_line (key_to_set , value_to_set , quote_mode , export )
167
181
168
182
with rewrite (dotenv_path ) as (source , dest ):
169
183
replaced = False
@@ -358,3 +372,33 @@ def dotenv_values(
358
372
override = True ,
359
373
encoding = encoding ,
360
374
).dict ()
375
+
376
+
377
+ def update_dict_to_dotenv (
378
+ dotenv_path : Union [str , _PathLike ],
379
+ env_dict : dict ,
380
+ quote_mode : str = "always" ,
381
+ export : bool = False
382
+ ):
383
+ """
384
+ Adds or Updates key/value pairs in the given dictionary to the given .env
385
+
386
+ If the .env path given doesn't exist, fails instead of risking creating
387
+ an orphan .env somewhere in the filesystem
388
+ """
389
+ key_to_line = {}
390
+
391
+ for key_to_set , value_to_set in env_dict .items ():
392
+ env_line = make_env_line (key_to_set , value_to_set , quote_mode , export )
393
+ key_to_line [key_to_set ] = env_line
394
+
395
+ with rewrite (dotenv_path ) as (source , dest ):
396
+ for mapping in with_warn_for_invalid_lines (parse_stream (source )):
397
+ if mapping .key in key_to_line :
398
+ line_out = key_to_line .pop (mapping .key )
399
+ dest .write (line_out )
400
+ else :
401
+ dest .write (mapping .original .string )
402
+
403
+ for _ , line_out in key_to_line .items ():
404
+ dest .write (line_out )
0 commit comments